1. 程式人生 > 實用技巧 >記一次使用elasticsearch遇到bug的探索過程

記一次使用elasticsearch遇到bug的探索過程

背景:

練習一個小專案,爬取京東的資料,存到ES庫中,然後讀取ES庫中資料,展示到頁面上。效果圖如下:

涉及兩個介面,一個爬取寫入ES介面,一個查詢展示介面,當我寫完程式碼信心滿滿準備看看效果的時候,呼叫爬取介面突然報了異常,因為我也是剛開始接觸ES,所以對異常也是一臉的蒙,但本著有問題還是要解決的想法,開始分析原因。異常如下:

過程:

一開始我以為是我的程式並沒有連上我的ES庫,但是我試了一下查詢方法,雖然查回來的資料是空的,但證明庫還是連上了的。看著異常,順著棧針找到自己的程式碼開始報錯的地方,發現是呼叫ES的client入庫的時候報的錯,

BulkResponse rsBulk = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);

在這個地方debug,順著棧軌跡一層一層的進入,來到了異常棧的棧底,也就是BulkRequest.class ,是這個類的validate()方法,看名字應該是個校驗方法,對這個方法一點點看,在debug顯示變數值時,發現了異常中的錯誤資訊,那就是這個request的validate()報了現有的錯。

"type is miss",type沒有找到,ES庫中確實有這個要求,但我找了一下程式碼,發現並沒有呼叫方法傳去type的地方,難道是我寫錯了?翻看了一下教程,發現沒寫錯。找到了寫入資料的地方

bulkRequest.add(new IndexRequest("jd_goods")
.source(JSON.toJSONString(jdCommodityInfo.get(i)),XContentType.JSON));

點進IndexRequest(String index),找到了返回的錯誤資訊,

if (this.type == null) {
validationException = ValidateActions.addValidationError("type is missing", validationException);
}

錯誤的來源找到了,那是什麼原因造成了這個錯誤呢?

回頭看了一下我點進來的構造方法,猛的發現,這個構造方法裡並沒有type的定義

public IndexRequest(String index) {
this.opType = OpType.INDEX;
this.version = -3L;
this.versionType = VersionType.INTERNAL;
this.autoGeneratedTimestamp = -1L;
this.isRetry = false;
this.ifSeqNo = -2L;
this.ifPrimaryTerm = 0L;
this.index = index;
}

怪不得,你都沒定義,驗證的時候肯定報錯啊!難道開源專案百年難得一遇的bug被我發現了,那我以後豈不是要升職加薪,當上總經理,出任CEO,贏取白富美,走上人生巔峰。為了驗證我的想法,我找了一個帶有type型別引數構造方法,進行了測試。

bulkRequest.add(new IndexRequest("jd_goods" ,"doc")
.source(JSON.toJSONString(jdCommodityInfo.get(i)),XContentType.JSON));

果然能執行成功。想想心裡有點小激動,我要立刻去提Issues,去提Pr,不對,等等,我能遇見,別人也能遇見,而且我不是用的最近版本的ES,是不是已經被修復了。找了個高版本的ES程式碼,開啟IndexRequ.clss找到validate(),果然被修復了,type判斷已經被刪除了。

總結:

雖然沒能真正的修復一個開源專案的bug,到時候和同事,面試官好好的吹一下。但這個過程中真的學習到了,解決bug的思路。相信以後遇到未知bug的時候,也能輕鬆解決。