1. 程式人生 > >記一次線上問題排查

記一次線上問題排查

  這周在上線一個功能的時候,碰到了“fail to respond”問題(上一篇文章),問題雖然解決了,但是解決的過程很痛苦,走了很多彎路,我覺得有必要記錄下來。

  情景還原:專案A(公司內部專案),專案A裡面有呼叫專案B的介面(專案B是公司接入的第三方專案,類似於rabbitMQ的存在)。線下環境,一切ok;上線了,“一個介面都調不通”。

  問題分析:碰到這個問題,我也很懵逼,咋線下好好的,到了線上就不行了呢?第一反應是去看日誌。一看日誌,竟然是json解析異常,列印異常資訊的時候,順便還把呼叫介面返回的內容給列印了出來,我一看,介面返回的內容:尼瑪,這不是官網的html嘛,這麼跑到官網去了?

第一次交鋒,運維甩鍋

  現在問題很明確了

期待返回:{code:1000,message:abc,result:xxx}

實際返回:<html><head>….</head></html>

  程式碼裡進行解析的時候,肯定json解析異常。出現這問題,肯定是運維的鍋,馬上就跑去找運維。運維聽完問題,馬上氣勢很足的說:沒有問題的啊,都用了這麼長時間了,早有問題早就暴露出來了啊!

我堅持說:程式碼是不會騙人的啊,調專案B的,現在返回了官網的html,肯定不對啊

運維聽了,很不負責任的說:奧,那別人怎麼就沒碰到這問題呢?你提測單裡的地址配錯了吧?

我:心裡一萬個MMP。但是,還是得求運維大爺幫忙排查問題,賠笑了一下,讓運維再幫忙看下線上的配置(我們的配置檔案是放在配置中心的,開發沒檢視的許可權,只有運維才可以看),看了配置檔案,配置的是對的啊,不死心的我,又讓運維登入線上的docker環境,ping一下www.b.read.com,結果,是ping的通的!在運維得意的眼神中,開發落魄的回到工位。

第二次交鋒,運維的錯判

  當時,我早已經不在狀態了,我記得那天,我忙的暈頭轉向,同時有三件事情要處理:一個線上問題排查(急)、一個新功能上線(就是這個功能)、還有自己的開發工作要做,而且今天出問題的功能是之前開發人員遺留下來的,雖然是上線了,但是,沒有測試!沒有測試!真是屋漏偏逢連夜雨,感冒發燒大姨媽!知道自己的狀態已經不對了,就跟旁邊的同事討論,尋求突破。旁邊的同事,還是比較給力的,聽完我的描述,肯定的說:肯定是運維的問題,並且,ping的通,又不能代表就是正確返回!我一聽,是這樣的啊。於是又去找運維,這次去,剛才幫我排查的運維不在(稱呼之前的運維A吧),我就找負責當天上線的運維B,運維B是新來的,他說他剛來,對什麼的不熟。尼瑪,這就尷尬了!

  這時,運維B旁邊的一個運維老人,就叫他運維C吧,運維C搭話了,說:我們這個專案B啊,讀和寫的域名是不一樣的,你配置的是寫的域名,配錯了,讀操作應該是www.b.read.com(現在配的是www.b.write.com,錯誤的)

  “假的吧,讀和寫居然還不是一個域名?”我滿臉不可置信

  “是的啊,讀和寫不是一個的,只是之前都是寫操作,你們開發配的都是www.b.write.com,沒配置過www.b.read.com,所以你不知道有這個域名”運維C很認真的說

  “奧,是的,之前都是寫操作,讀操作現在是第一次”,我覺得有點道理,讀操作,我的確是第一個,“那我發郵件讓重發一次了?”,因為重發得抄送直屬領導、總監、和全部開發人員,有點不情願

  “要重發郵件的,不然我們這邊沒法走流程”,運維C很認真的說

  “好吧”雖然有點不情願,但是,要搞定這問題,必須得發郵件。

  發郵件,走流程,再次上線了,但是,結果還是出異常了,不過,這次異常跟上次異常不一樣。

上次異常是:json解析異常,返回錯誤的html

這次的異常是:

response:503 service unvailable

什麼鬼,怎麼還有問題?這503是什麼情況?百度了這個錯誤出現的情況,又沒發現和我情況很吻合的,看了下時間已經過了五點半了(公司的規定,五點半以後非特殊情況,不上線),我又一時想不出解決方案,就做開發任務去了,這個問題第二天再看吧(當然這個專案是技術專案,不影響業務的,不然,如果是產品專案,搞不定的話,今晚就別回家了,哈哈)

第三次交鋒,問題終解決

  第二天,早上上班,第一件事,就是找運維A處理,因為運維A的資歷最老,對公司最熟悉。我把昨天改成www.b.read.com域名的事情跟他說了,他就很詫異:你改成www.b.read.com幹嘛,這個域名有配置過嘛?

我就很無語:這個是你們運維讓我改的啊,我還特意上一個fixbug啊!

他一愣,找其他運維瞭解情況,然而,最終結論是:根本就沒有配置www.b.read.com域名,也就是說我昨天fixbug是白上了,不僅白上了,今天還得再上一個,再改回來!尼瑪!

我突然想起,昨天沒改之前,不也是錯誤的嘛?我就問運維A,運維A想了想,在伺服器上curl www.b.write.com,發現返回的就是官網的html,又去看了什麼配置,又問了其他運維有沒有配置 www.b.write.com的域名解析,都回答沒有。然後,很直白的告訴我:昨天的問題,是沒有配置域名解析。

我:。。。。

  搞半天,居然是這麼弱智的問題,就是域名解析沒配置,所以,解析不到就跑到官網去了,就返回了官網的html。真狗血。

  我又問A為什麼運維C會說“讀和寫是兩個域名”?A解釋道:開發的機器是不能訪問線上的伺服器的,但是,日常工作中開發又需要訪問線上專案B,所有,就有了矛盾。那運維那邊是怎麼解決的呢?運維那邊是線上下配置了一個域名,即www.b.read.com,通過這個域名中轉,間接的提供給開發訪問。www.b.read.com這個域名只存線上下的,運維C可能沒搞清楚,以為線上環境也配了www.b.read.com域名,所以才有那麼一說。

  好吧,事情總算是搞清楚了。回去發郵件,㕛走一個fixbug!(這裡吐槽一下啊,都是犯錯,運維犯錯了,私下改改配置就可以了,其他的什麼都不用做了;開發犯錯了,就得發郵件,抄直屬領導、抄總監、抄全體測試人員、還要走流程。做開發,真的很虧!)

第四次交鋒,還有坑!

  這一次上線,我覺得事情已經十拿九穩了,滿懷信心的測試,哪知,“一個介面都不能用”!翻異常資訊,一看,這次異常資訊變了,是HttpClient呼叫超時,程式裡我可是設定20秒的啊,如果連20秒都超時,那這個是根本沒法使用啊。為了排除是網路的問題,我在瀏覽器上,呼叫專案B的介面(專案B提供了站內的API呼叫),等待了一分鐘,直接504 gateway time-out

  無奈之下,跟直屬領導反映了,直屬領導有點不高興了,畢竟花時間、花精力做的東西,要上線了,居然說不能用,這是打臉啊。雖然有點不高興,但是沒怎麼責怪我,還跟我一起分析,確定是不是還有的救。在無意中,呼叫了專案B的其他介面,居然是可以調的通的!我差點不敢相信我的眼睛,再呼叫第二次,還是可以的!再呼叫最初的介面,失敗,再呼叫,失敗。呼叫其他的介面,成功!尼瑪,我都差點懷疑人生了,都是一個專案的介面,怎麼有的是ok的,有的就是不ok的呢?

  領導看我一臉疑問,跟我解釋,專案B呼叫超時的介面,是獲取source的,而專案B是無法直接返回source,它應該是對所有的訊息進行group by,進而得到所有的source。這個方案線上下是沒問題的,但是,一旦到了線上,資料量太大,那它這個方案必定超時。而其他的介面,就可以順利呼叫,不會超時。

  到這裡,一切真相大白了。

  最終,放棄了獲取source的介面,閹割了一個小功能,專案終於可以正常使用了!

總結和反思

  1. 不堅定,輕信運維

    域名無法解析,那就是運維沒有配置域名解析,一定要讓運維確定配置了域名解析,要堅定!(其實還是缺乏運維方面的知識)

  2. ping的通,並不代表呼叫正常

    潛意識的認為ping的通,網是通的,呼叫就正常的,有問題就是程式問題。其實不一定的,看真的是否被呼叫,得看專案的access log

  3. 一個介面不能用,並不代表所有介面不能用

    因為第一個介面就呼叫失敗,我就認為全部不能用,就沒有嘗試其他的介面了,其實,還是可以再試一試其他介面的,也許第一個介面比較特殊呢?