要說清楚事情,不介紹下背景和環境好像不行啊
公司内部有一套RPC服務架構,java開發的,rpc協定用的redis
我所在的部門沒java人手,但誇部門的資料互動又越來越多,一開始用http 接口性能不好,qps到2-3千的時候調用方經常發生各種curl 網絡錯誤,導緻拿不到資料,影響很不好
是以後來自己拿 php+swoole 實作RPC服務,延用公司的架構,協定和服務注冊啥的都保持一緻,就是具體業務用php來實作

綠色那塊-中間橢圓的就是這次出問題的服務
我們可能會被PHP-FPM和其他RPC服務請求,也可能請求其他RPC服務和DB, 這樣說應該清楚了吧
發現:收到zabbix發的報警 <code>PROBLEM: system close_wait [9522>5300], 首次報警</code>
腦子想了下,通常如果出問題都是調用方回報,這次調用方沒回報應該沒影響到具體業務,也沒啥其它好确認的,直接上伺服器看吧
<code>ss -ant | grep CLOSE-WAIT</code> 确認下果然是這樣
close-wait 具體含義簡單說下,看圖
這是tcp的揮手圖,<code>當主動關閉的一方發出FIN包,被動方回複ACK後自己就進入CLOSE_WAIT狀态,正常情況下,被動方稍後就應該發出FIN包,并确認收到ACK回複,然後連接配接就可以正常關閉了</code>
很顯然由于某些原因,我們的swoole程式(被動方)沒能發出FIN包,這個為什麼回頭再分析,先把報警解決了
close_wait 是不會自動消失的,根據上面<code>ss -ant</code> 結果配合 <code>lsof -i :{$port}</code> 查到具體的服務,<code>隔離-重新開機-恢複</code>這個服務, 當然了<code>ss -ant</code> 的結果要儲存下來,等下要分析具體誰跟我斷了。。。
<code>ss -ant</code> 的結果看了下,close_wait 的 <code>Foreign Address</code> 基本都是RPC(java), 很多都是常用服務,整個公司都在用,基本排除是對方的原因
這次有2台機器都出現了問題,但2台機器上引起close_wait的service程序是不一樣的,但有個特征就是<code>請求量很少</code>
因為 swoole 不忙,導緻建立的socket連接配接超過了<code>閑置時間</code>,然後對方就覺得timeout了,然後主動斷開了
還注意到close_wait 對方很多是按理不應該用到的rpc服務,我猜這個應該是php代碼沒寫好有關系。 看開頭的背景也知道,用swoole搭服務時間還是很緊張的,業務邏輯基本都是直接用的http api那套代碼,而swoole是常駐記憶體的,本來某些變量/連接配接在api那套裡面随着請求結束就回收了,但是在swoole裡不會
我覺得基本就是onClose這裡出了問題;我看了下php的error log, 沒發現fatal error;
我們4台機器,其中2台發生問題,而且是不同的服務。加上用關鍵字<code>swoole close wait</code> google 沒有發現案例。基本排除是swoole的問題,還是我使用的姿勢不對然後有幾率導緻發生這個問題
然後就沒有然後了,這4個機器的服務也跑了一年多了,第一次發生這個情況,我又不懂系統原理和c,加上案發現場現在也關閉了
這2個不活躍的服務配置的worker num 都是96個, 其中一個是同僚開發的,使用的預設配置(預設配置是有個配置檔案,我弄的,我好像沒講過要調低),另一個一開始請求量多,後來業務下了,也忘了調低
整理了下,請求量低的服務 worker number 都調低
<code>系統原理</code> 、 <code>網絡</code>、 <code>c語言</code> 要盡量多學習, 不然承擔這種<code>基礎架構</code>服務,萬一出了底層問題,你就不太能搞的定了,都是隻能治标,不能治本