Openresty主動關閉連接與KeepAlive Requests
- 2019 年 11 月 20 日
- 筆記
keepalive_requests
作者:tweyseo (T神發稿件)
01最近客戶端(APP)換了新的網路庫,幾輪測試下來,功能和性能上都是正常的,只是網路庫對應的日誌里會有連接被關閉的提示,開始以為新的網路庫踩到坑了,客戶端的同學排查了幾輪下來,過濾抓包發現是服務端發fin包主動關閉的連接,於是找到我說幫忙排查下。
02先說下我們測試環境里的服務端的架構,客戶端使用基於HTTP/1.1的長連接直連服務端的一個基於lor的APIServer,APIServer再對應後端的其他服務。
03我這裡就直接在APIServer上抓包,發現果然是APIServer上發起的fin包。仔細觀察,發現fin包的前一個包,是一個響應客戶端請求的包,而且讓人比較困惑的是,這個包用HTTP協議解析出來,裡面的status竟然還是200(這樣就排除了是因為請求出錯,NGX主動關閉的這個連接),然後間隔200ms後就是fin包了,再來觀察這個響應包,發現HTTP協議解析出來的頭,有connection: close
的欄位:

可是在APIServer里列印了該響應包在ngx.print
之前的具體的頭部資訊,發現並沒有connection: close
的欄位,那麼這個欄位應該就算NGX內部添加的,並且還在200ms後主動發起fin包關閉了連接。
於是我想到是不是長連接超時了,查看ngx的配置,發現確實有配 keepalive_timeout 2m;
。但是按照客戶端同學的回饋的現象看來跟keepalive_timeout的NGX官方描述又不一致,因為是一直有在請求的。
04正當我一籌莫展的時候,突然發現keepalive_timeout上面的一個keepalive_requests的配置:
Sets the maximum number of requests that can be served through one keep-alive connection. After the maximum number of requests are made, the connection is closed.
而且他的默認值是100,也就是說當前連接在處理完100個請求後將會關閉掉這個連接。
於是在我自己的機器上配置keepalive_requests 2;
,然後做簡單的ping-pong測試,並且抓包:

從抓包的結果來看,在第二個ping的響應包的包頭裡添加了connection: close
的欄位,隨後NGX主動發起了fin包關閉了這個連接。
05總結,在NGX對客的HTTP/1.1的長連接的配置里,不僅有控制連接超時的keepalive_timeout,也還有控制針對單條連接的最大請求數的keepalive_requests。