兩個流程鏈路問題的排查和總結


兩個流程鏈路問題的排查和總結

亂碼問題

 

現象

 

 

在一類簡單的業務場景下發起http請求的測試案例,返回的時候會100%有亂碼。如果跳過跟廠商定制的7層負載均衡設備,直接連后端一台機器,則100%無亂碼。在其他測試場景,則100%無亂碼。

 

注意,此處的100%是那段時間實際發起請求的情況中亂碼的占比,與SLA無關。

 

 

大家猜一猜,產生亂碼的原因在哪一層?

 

處理過程

首先自證清白,我負責處理1。直連是無亂碼的。其他場景是無亂碼的。代碼和線上穩定運行的版本是一套,線上是無亂碼的。這個場景和其他場景唯一不同的是返回數據的模板是放在測試數據庫中的。所以我將測試庫中的模板換成其他無亂碼場景的數據(避免編碼問題,直接拷貝),仍然不起作用。將模板數據改成12,也能返回一個亂碼。所以亂碼應該是和[處理1]程序無關。

 

與自己這邊無關,再看是上游的問題還是下游的問題?

 

下游[處理2]是新邏輯,像SSL和處理3都是線上穩定運行的。但是從日志里看,通過[處理1]的時候還不是亂碼,只是回到發起端才有亂碼的,說[處理2]有問題不合邏輯。

 

上游[跟廠商定制的7層負載均衡設備],因為有兩個場景的對比,所以還是有理由找負責的同事查一查的。他們調查的結果是沒有地方進行編碼轉換。

 

再往上游[案例發起端],要證明和案例發起模擬程序本身有沒有關系。因為是http請求我采用直接將請求頭和body使用在其他服務器上使用curl模擬請求的方式,結果與案例平台的結果一致:使用7層負載均衡設備會有亂碼,不使用則無亂碼。看來與模擬程序本身無關。

 

我們團隊內部也有一個模擬工具,可以模擬請求,將http請求的body體復制進去,無論是否使用7層負載均衡設備都沒有亂碼。

 

我們團隊內部模擬工具和案例發起端的區別 應該在請求頭上。這時我注意到了http請求頭的參數,里面有accept-encoding: gzip, deflate, br 。將這個參數去掉,果然無論是否使用7層負載均衡設備都沒有亂碼。

 

分析

通過處理過程,了解到問題原因是如果設置了accept-encoding: gzip, deflate, br。返回的數據在7層負載均衡設備會有處理。導致亂碼。我看了他們的官網,使用的設備是支持gzip壓縮解壓的。

 

 

我猜測是它將沒有加密的請求作為gzip解密處理了。找到7層負載均衡設備廠商的技術支持。已經將問題反饋給他們,請他們確認是根據哪個請求參數來確認是否加解密的。

 

這個問題更合理的步驟應該是這樣:

 

亂碼問題核心是要確認引起亂碼的變量:有可能是一個參數,也有可能是一個系統內部問題。

 

使用案例平台發起請求亂碼,然后使用我們團隊內部模擬工具發起相同的請求不是亂碼。這樣可以定位和案例平台的某個變量有關系。變量分為參數和系統。使用curl代替系統自動發起來驗證是否和系統有關。

 

使用curl模擬案例平台的請求亂碼。使用curl模擬我們團隊內部模擬工具發起相同的請求不是亂碼。確認和系統無關,問題在參數上。

 

找到兩個請求參數的差異,其中一個差異在accept-encoding上,並且這個參數和編碼有關。調整這個參數,確認相關性。

 

socketTimeOut問題

 

現象

 

 

測試案例發起端和執行程序分布在兩個機房,有防火牆。已經請網絡組的同事將鏈路中的機器對應端口的防火牆打開。但是發起的請求,有大約80%可以正常執行返回結果。另外20%直接返回socketTimeout,在[處理1]上確認,並沒有收到請求。

 

大家猜一猜,問題出在哪一個環節?

 

處理過程

首先自證清白,我負責處理1。從日志上看沒有收到請求並不能證明請求沒有到達,因為有可能是在請求在排隊,沒有到達處理環節就直接被丟棄了。因為用的是jetty,所以首先調大work線程數。再次發起請求,失敗比例沒有變化。用top命令查看cpu、mem使用都很低。運行中線程數遠遠低於設置的work線程數閾值。調大jvm內存再次發起請求,失敗比例沒有變化。所以socketTimeout的請求應該沒有到達[處理1]。

 

如果[處理1]沒有收到,則一定不是下游的問題。要向前來排查。在之前沒有經過防火牆的時候,並發量更大的情況下,都可以正常處理,應該與7層負載均衡設備無關。

 

再看防火牆這一層,部分請求不正常,是否是限流造成的?搜索了一下防火牆的相關文檔,防護牆是可以配置限流策略的。所以咨詢了配置防火牆的同事,回復說沒有限流策略。

 

再往前看發起端。查到發起端共10台機器。用linux命令grep socketTimeout | wc -l 發現異常主要集中在其中兩台機器上。將請求數和socketTimeout數做對比,發現這兩台機器都是失敗的。並且這兩台機器與其他機器是不同的網段。

 

禁用了有問題的兩台機器,問題解決。

 

分析

通過處理過程,問題已經很清楚了。部分網段網絡不通。這個問題的更合理的排查步驟應該是這樣:

 

案例發起時返回socketTimeout,那先要判定到底是什么問題。因為socketTimeout有兩種可能。一種是網絡不通,一種是等待超時。如果從找出問題根因這個角度出發,從一開始就應該先看案例發起的機器與連接方網絡是不是通的。如果使用的是ansible運維工具,可以用下面命令批量查看

ansible -i  hosts XX -m shell -a "curl http://XXXX:8080/健康檢查接口 --connect-timeout 5"

 

 

這樣很快就能診斷出問題原因。

 

總結反思

在兩個問題的處理過程一開始,都是以自證清白開始的,而不是以解決問題開始的。我在反思這個思路是不是存在格局上的問題。

 

之所以以自證清白開始,是出於兩方面的考慮。第一,吃過虧。我之前總是解決問題就好,把問題查清楚了,但是本着有問題大家一起擔的原則,結果很多問題責任都被算在我們團隊身上。這樣會造成我們團隊總有問題的表象。第二,我也剛做這個項目,很多環節並不清楚。對最終能不能解開這個問題也沒有信心。所以至少要證明自己團隊沒有問題。

 

先來分析一下自己的兩點考慮是否是正確的思路。對於第一點,達則兼濟天下,窮則獨善其身。首先需要先讓別的團隊對我們團隊建立信任。如果不是我們團隊的問題,是一定需要明白的表述清楚的。有個詞叫:現實理想主義者,看網上意思說要胸懷理想,但是接受現實。用在這件事上,我理解就是自己心懷着有問題是大家一起的問題,一起解決就好這是對的理念,是要堅持的。但是為了實現正確的理念,方法是問題事實結論還是要擺清楚。讓別人對自己或自己團隊建立信任和影響力。

 

對於第二點,我所謂的自證清白實際上不能證明清白。這兩個問題,特別是第一個問題,據說在我來這邊之前很久了,一直沒能解決。很大一個原因是大家都認為自己這邊沒有問題,所以就不管了。所謂的沒有問題有可能是自己的知識盲區,只有真正找到唯一的真相,才能證明清白。

 

所以總的來說要做到兩點:第一:一開始就要以查清楚問題為目標。第二:查清楚問題之后要把結論讓大家知道,建立好自己團隊的形象。

 

這個認知的明確和排查問題的快慢有直接的關系。如果兩個問題不是從先看自己的部分開始向外輻射,就能運用更科學的流程來解決,速度會更快。如果一開始就以整體大局的思路來看問題,在整個鏈路上花的時間會更均勻,而不是偏重於自己負責的項目。對整個鏈路的理解會更清晰深刻。這也是格局對人的結果產生重大影響的原因之一吧。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM