Broken pipe問題排查

2020-08-10 13:48:16

問題:

|ERROR|c.x.s.c.s.AccessPermissionFilter|b2a299e5a8cbe429.b2a299e5a8cbe429<:b2a299e5a8cbe429||Unexpected error occurred in AccessPermissionFilter: com.xueqiu.snowball.common.servlet.ExceptionWrapper: org.apache.catalina.connector.ClientAbortException: java.io.IOException: Broken pipe|||

描述:

AccessPermissionFilter元件是不是有點問題,最近部署的時候總報這個錯誤

 

10.10.54.21 版本com/xueqiu/snowball/snowball-common/4.17/snowball-common-4.17-sources.jar!/com/xueqiu/snowball/common/servlet/AccessPermissionFilter.java

復現:

IDEA後端介面打斷點,瀏覽器發起請求

在IDEA斷點沒有往下執行的情況下,瀏覽器停止接收(點選X)

或者你一直重新整理頁面,重新整理的速度比伺服器返回給你的速度快

IDEA就會出現錯誤,broken pipe(主機中的軟體中止了一個已建立的連線)。

tip:

並不是只有超時纔會導致這個問題,只要是連線斷開,再往這個斷開的連線上去執行寫操作,都會出現這個異常,用戶端超時斷開只是其中的一種情況

 

分析:

軟體方面:

Broken pipe產生的原因通常是當管道讀端沒有在讀,而管道的寫端繼續有執行緒在寫,就會造成管道中斷。(由於管道是單向通訊的) SIGSEGV(Segment fault)意味着指針所對應的地址是無效地址,沒有實體記憶體對應該地址。 
以下是UNIX的信號解釋: 
11 / SIGSEGV: Unerlaubter Zugriff auf Hauptspeicher (Adressfehler). 
12 / SIGUSER2: User-defined Signal 2 (POSIX). 
把_JAVA_SR_SIGNUM改成12只是將信號至成user-defined,讓它不報出來而已,不能解決問題。 

Tips:
「_JAVA_SR_SIGNUM=12」等號兩邊必須沒有空格,等號是半形 

 

sun的解釋: 
   --posted by: cooper 
Below is a clipping from Sun on working around JVM crashes under high thread counts in the JVM 1.3 for Linux.
On Linux, use a larger signal number for hotspot thread suspension/resumption handler. 
The signal number being used is specified by environment variable _JAVA_SR_SIGNUM. 
Setting it to a number larger than SIGSEGV (11) will solve the problem. 
A good number to use is 12, which is SIGUSR2. 
Using signal 16 to work around the problem might have potential problems. 
So on tcsh,"setenv _JAVA_SR_SIGNUM 12" can solve the problem.

系統方面:

用命令檢視ulimit系統限制:ulimit -a  通過 ulimit 改善系統效能

 

用命令檢視系統總控制代碼數:/proc/sys/fs/file-nr

 

用命令檢視當前應用開啓的檔案控制代碼數:ls -l /proc/{pid}/fd | wc -l

 

**上面這三部分,可以看出來**

1.系統已經佔用的控制代碼數遠遠小於系統最大控制代碼數

2.系統允許的單個進程建立的最大socket鏈接是524288,snowflake應用佔用的鏈接是1978遠小於允許最大值

以下部分是用在系統方面有問題時進一步排查

用命令檢視tcpip的狀態: netstat -n | awk '/^tcp/ {++state[$NF]} END {for(key in state) print key,"\t",state[key]}'  

 

用命令檢視系統的keepalive設定:sysctl -a |grep keepalive  

 

線上操作時,這個命令沒有許可權,op使用者檢視資訊爲空,我下面 下麪就擷取一張我這邊的一臺Linux虛擬機器做參考(因爲CLOSE_WAIT不多,這次問題不出現在這裏)

 

(由此便可以看出,當CLOSE_WAIT的佔用數量過多時,就需要優化keepalive的時間)當前咱們的系統明顯不存在此類問題

擴充套件:

這個異常是由於以下幾個原因造成。 

1、用戶端再發起請求後沒有等伺服器端相應完,點選了stop按鈕,導致伺服器端接收到取消請求。
     通常情況下是不會有這麼無聊的使用者,出現這種情況可能是由於使用者提交了請求,伺服器端相應緩慢,比如業務邏輯有問題等原因,導致頁面過了很久也沒有重新整理出來,使用者就有可能取消或重新發起請求。

2、Tomcat伺服器在接受使用者請求的時候,有其自身的處理能力,執行緒、伺服器等各個資源限制,超出Tomcat承載範圍的請求,就會被tomcat停掉,也可能產生該錯誤。 

3、linux的執行緒機制 機製會產生JVM出錯的問題,特別是在連線高峯期間經常出現這樣的問題,tomcat在linux下也出現類似情況。


建議: 

1. 資源沒有完全釋放,用完後要至NULL 值(JAVA的GC沒那麼完善)

2. 數據庫連線順序關閉!(RS,PS,CONN) 

3. 優化JAVA虛擬機器 加入相應的記憶體參數! 

4. 不要在數據庫中獲取大段文字(即一個欄位的值不要太大)

5. JAVA 不推薦 用String 獲取大量資訊。(容易造成記憶體泄露,建議用StringBuffer)

6. 頁面重複提交 

7. 儘量將METHOD移到JAVA中,在JSP中所有的方法都看做全域性變數,編譯執行本身就有很多問題。 

8. 如果是查詢功能,儘可能的使用非XA(事務)。 

9. 儘量用較新較穩定版本的JDK,低版本的JVM本身也有很多BUG,比如1。5的垃圾回收比起1.2,1.3一定是非常明顯的進步。 

10. LINUX系統本身沒有這麼穩定,有些問題無法避免的~~:)

**以下是數據庫鏈接的問題,不在web問題範圍內**

XA協定由Tuxedo首先提出的,並交給X/Open組織,作爲資源管理器(數據庫)與事務管理器的介面標準。目前,Oracle、Informix、DB2和Sybase等各大數據庫廠家都提供對XA的支援。XA協定採用兩階段提交方式來管理分佈式事務。
XA介面提供資源管理器與事務管理器之間進行通訊的標準介面。XA協定包括兩套函數,以xa_開頭的及以ax_開頭的。

解決方案:

1.egprogress公司解決方案 忽略這種異常

 

**雪球應該來忽略嗎?爲了防止頻繁報警的引起的誤會,將該異常捕獲記錄爲warn**

2.後來又發現一個版塊與APP的通道有關:Broken pipe異常分析及解決

 

    • 咱們的matrix監控,snowflake的QPS不到1000,由上面伺服器的參數來看,看來不是併發導致的
    • client端的併發請求?
      用ab來模擬APP端上的併發請求,control+C中斷,出現大量報錯,

 

借用他人的結論:

1.問題原因
client端使用者在殺死進程時,介面的TCP請求尚未完成(未完成的原因是處理時間長)。 
導致server端write數據時,收到SIGPIPE信號,拋出Broken pipe異常。 
但由於已經殺死了進程,並不會對使用者產生任何影響。

2.其他結論
ios和android在處理1M以內(尚不清楚有沒有最大值)大小報文時,沒有問題
ios和android均是阻塞請求,本次請求不會對上次請求造成影響,即使上次請求尚未完成
ios切換至後臺,短時間內(5000ms以內,最大值根據系統不同而不同)並不會中斷已經存在的TCP連線。
android切換至後臺,並不會中斷已經存在的TCP連線。
ios、android殺死進程會一併關閉已經存在的TCP連線。
android框架(公司基於google改造的框架)預設併發5執行緒一組。
3.解決方案
由於kill進程我們無法控制,故只能通過降低介面處理時間,減少使用者kill進程時未完成的TCP連線數量。

**具體**

      1. 對談列表翻頁
      2. 對談列表限制展示數量
      3. 用戶端分組獲取對談列表數據

3.另外,經過內部討論,部分產品APP端不直接請求SERVER,大部分由NGINX代理,因此,此問題應該是大部分出現在微服務之間的相互呼叫

1.微服務的非同步呼叫沒有約定一個response wait time,呼叫方主動關閉

2.呼叫方微服務的重新部署,沒有實現graceful shutdown,暴力關閉

過程:

1.問題原因已經make sure ✔️

2.目前公司的架構服務都存在這種問題,不影響線上,故本次先不進行處理,issues狀態留存

參考資料:

https://confluence.atlassian.com/jirakb/clientabortexception-java-io-ioexception-broken-pipe-225122378.html

https://stackoverflow.com/questions/642061/error-commiting-response-java-io-ioexception-broken-pipe-at-sun-nio-ch-filedisp

https://stackoverflow.com/questions/15785175/java-io-ioexception-broken-pipe

http://www.cnblogs.com/liu1989/p/3383714.html

https://blog.csdn.net/zqz_zqz/article/details/52235479

https://community.oracle.com/thread/1347653

https://issues.apache.org/jira/browse/WW-4386

https://gaoyaohuachina.iteye.com/blog/2399765

https://blog.csdn.net/zqz_zqz/article/details/52235479

https://www.ibm.com/developerworks/cn/linux/l-cn-ulimit/index.html

https://blog.csdn.net/ooppookid/article/details/54891771