1. 程式人生 > >nginx:TIME_WAIT過多或者CLOSE_WAIT過多的狀態

nginx:TIME_WAIT過多或者CLOSE_WAIT過多的狀態

1 起因

線上伺服器nginx日誌執行一段時間後,會報如下錯誤:

1024 worker_connections are not enough

一般做法是修改worker_connections。
但實際上:該服務是用於時間比較短的連線裡,並且一天最多才4000個請求。不可能會耗盡worker_connections。
除非每次連線都沒有釋放對應的連線。

shell>netstat -n | awk ‘/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}’
CLOSE_WAIT 802
ESTABLISHED 106
shell>lsof -n | grep “nginx對應的一個程序id”
MvLogServ 31125 mv 111u IPv4 76653578 0t0 TCP 10.1.138.60:8996->10.1.138.60:51977 (CLOSE_WAIT)
MvLogServ 31125 mv 112u IPv4 76659698 0t0 TCP 10.1.138.60:8996->10.1.138.60:52015 (CLOSE_WAIT)
MvLogServ 31125 mv 113u IPv4 76662836 0t0 TCP 10.1.138.60:8996->10.1.138.60:52042 (CLOSE_WAIT)
MvLogServ 31125 mv 114u IPv4 76663435 0t0 TCP 10.1.138.60:8996->10.1.138.60:52051 (CLOSE_WAIT)
MvLogServ 31125 mv 115u IPv4 76682134 0t0 TCP 10.1.138.60:8996->10.1.138.60:52136 (CLOSE_WAIT)
MvLogServ 31125 mv 116u IPv4 76685095 0t0 TCP 10.1.138.60:8996->10.1.138.60:52159 (CLOSE_WAIT)
……………….

TIME_WAIT:表示主動關閉,通過優化系統核心引數可容易解決。
CLOSE_WAIT:表示被動關閉,需要從程式本身出發。
ESTABLISHED:表示正在通訊
則可知:nginx:CLOSE_WAIT過多的狀態

2 解決

2.1 TIME_WAIT 通過優化系統核心引數可容易解決

TIME_WAIT大量產生很多通常都發生在實際應用環境中。
TIME_WAIT產生的原因:在通訊過程中A主動關閉造成的,
在A傳送了最後一個FIN包後,系統會等待 Double時間
的MSL(Max Segment Lifetime)【注:按不同的作業系統有不同時間】用於等待接受B傳送過來的FIN_ACK和FIN,
這段時間A的對應的socket的fd是不能夠重新利用的,
這樣在大量的短連線服務中,會出現TIME_WAIT過多的現象。

解決方案:
調整TIME_WAIT超時時間
vi /etc/sysctl.conf
#表示開啟SYN Cookies。
#當出現SYN等待佇列溢位時,啟用cookies來處理,可防範少量SYN攻擊,預設為0,表示關閉
net.ipv4.tcp_syncookies = 1
#表示開啟重用。
#允許將TIME-WAIT sockets重新用於新的TCP連線,預設為0,表示關閉
net.ipv4.tcp_tw_reuse = 1
#表示開啟TCP連線中TIME-WAIT sockets的快速回收,預設為0,表示關閉
net.ipv4.tcp_tw_recycle = 1
#表示如果套接字由本端要求關閉。
#這個引數決定了它保持在FIN-WAIT-2狀態的時間
#生效,如下命令
/sbin/sysctl -p


  • 注:
    已經主動關閉連線了為啥還要保持資源一段時間呢?
    這個是TCP/IP的設計者規定的,主要出於以下兩個方面的考慮:
  1. 防止上一次連線中的包,迷路後重新出現,影響新連線(經過2MSL,上一次連線中所有的重複包都會消失)
    即:允許老的重複分節在網路中消逝。
  2. 可靠的關閉TCP連線。在主動關閉方傳送的最後一個 ack(fin) ,有可能丟失,這時被動方會重新發fin, 如果這時主動方處於 CLOSED 狀態 ,就會響應 rst 而不是 ack。所以主動方要處於 TIME_WAIT 狀態,而不能是 CLOSED 。
    另外這麼設計TIME_WAIT 會定時的回收資源,並不會佔用很大資源的,除非短時間內接受大量請求或者受到攻擊。
    即:可靠地實現TCP全雙工連線的終止。(確保最後的ACK能讓被關閉方接收)

2.2 CLOSE_WAIT 需要從程式本身出發

LOSE_WAIT產生的原因是客戶端B主動關閉,
伺服器A收到FIN包,應用層卻沒有做出關閉操作引起的。
CLOSE_WAIT在Nginx上面的產生原因還是因為Nagle’s演算法加Nginx本身EPOLL的ET觸發模式導致。

ET出發模式在資料就緒的時候會觸發一次回撥操作,Nagle’s演算法會累積TCP包,如果最後的資料包和

FIN包被Nagle’s演算法合併,會導致EPOLL的ET模式只觸發一次。
然而在應用層的SOCKET是讀取返回0才代表連結關閉,
而讀取這次合併的資料包時是不返回0的,
然後SOCKET以後都不會觸發事件,
所以導致應用層沒有關閉SOCKET,
從而產生大量的CLOSE_WAIT狀態連結。
關閉TCP_NODELAY,在Nginx配置中加上

tcp_nodelay on;

3 總結

  • TIME_WAIT狀態可以通過優化伺服器引數得到解決。
    因為發生TIME_WAIT的情況是伺服器自身可控的,
    要麼就是對方連線的異常,要麼就是自己沒有迅速回收資源,
    總之不是由於自己程式錯誤導致的。

  • CLOSE_WAIT需要通過程式本身。
    如果一直保持在CLOSE_WAIT狀態,那麼只有一種情況,就是在對方關閉連線之後伺服器程式自己沒有進一步發出ack訊號。
    即在對方連線關閉之後,程式裡沒有檢測到,或者程式沒有關閉連線,於是這個資源就一直被程式佔著。
    伺服器對於程式搶佔的資源沒有主動回收的功能。只能修改程式本身。
    程式碼需要判斷socket,一旦讀到0,斷開連線,read返回負,
    檢查一下errno,如果不是AGAIN,就斷開連線。

相關推薦

nginxTIME_WAIT過多或者CLOSE_WAIT過多狀態

1 起因 線上伺服器nginx日誌執行一段時間後,會報如下錯誤: 1024 worker_connections are not enough 一般做法是修改worker_connections。 但實際上:該服務是用於時間比較短的連線裡,並且一

TCP CLOSE_WAIT過多解決方案

就上邊原因進行分析: 一、都是開發搞的鍋 二、linux下 CLOSE_WAIT過多的解決方法 情景描述:系統產生大量“Too many open files” 原因分析:在伺服器與客戶端通訊過程中,因伺服器發生了socket未關導致的closed_wait發生,致使監聽port開啟的控制代碼數到了1

TCP CLOSE_WAIT過多解決方案

資源 ssh net proc 使用 基本上 for 進行 響應 就上邊原因進行分析: 一、都是開發搞的鍋 二、linux下 CLOSE_WAIT過多的解決方法 情景描述:系統產生大量“Too many open files” 原因分析:在服務器與客戶端通信過程中,因服務器

CLOSE_WAIT過多,Jetty伺服器無響應

一開始,記錄到的資訊只有網路方面的資料,包括併發數和網路引數,如下: 321(專案的併發數) TIME_WAIT 533 CLOSE_WAIT 970 FIN_WAIT1 25 FIN_WAIT2 46 ESTABLISHED 592 SYN

linux 下埠close_wait 過多

轉自:[url]http://blog.163.com/helj_2001/blog/static/346345682009728111725235/[/url]情景描述:系統產生大量“Too many open files” 原因分析:在伺服器與客戶端通訊過程中,因伺服器發

[Nginx筆記]關於線上環境CLOSE_WAITTIME_WAIT過高

運維的同學和Team裡面的一個同學分別遇到過Nginx在線上環境使用中會遇到TIME_WAIT過高或者CLOSE_WAIT過高的狀態 先從原因分析一下為什麼,問題就迎刃而解了。 首先是TIME_WAIT:   理解一下TIME_WAIT狀態產生的原因,這個問題已經被很多很多的書說爛了,但是為什麼很多

【JAVAEE學習筆記】hibernate02實體規則、對象狀態、緩存、事務、批量查詢和實現客戶列表顯示

使用 ins tro trace ges create 綁定 criteria 命名 一、hibernate中的實體規則 實體類創建的註意事項  1.持久化類提供無參數構造  2.成員變量私有,提供共有get/set方法訪問.需提供屬性  3.持久化類中的屬性,應盡量使用包

Android 推斷程序在手機中是否是活動狀態或者正在執行狀態

systems scrip post manage art 推送通知 auth bool 當前 沈陽斌子在今天項目需求上碰到個這種問題,在Service中須要推斷當前的程序是否是活動狀態,換句話說也就是說後臺跑的服務中有業務需求檢測當前程序是否是該服務的程序 這樣好讓點

奪命雷公狗---linux NO:37 linux下nginx的URL重寫或者偽靜態頁面

com linu .com usr gin 也有 sbin 技術分享 images 最終效果如下所示: 其實很簡單,首先在 html 目錄下創建一個test.php 的文件,如下所示: 然後使用vi打開他,寫份測試源碼,源碼如下所示: 然後保存退出,去到 /

編譯安裝 nginx的http_stub_status_module監控其運行狀態

訪問量 tle bak 8.0 soft -h 數據說明 lnmp pts 編譯安裝 nginx的http_stub_status_module監控其運行狀態 從nginx升級(平滑升級)開始說起: 1)# rm -rf nginx-1.8.0 //刪掉原來的n

解決VMware Horizon View 虛擬機狀態始終為“正在刪除 缺少”或“錯誤 缺少”狀態

mark 版本 文件 href 08 r2 onf 打開方式 51cto 關鍵字 操作環境 桌面虛擬化版本:VMware Horizon 7.4 服務器虛擬化版本:VMware vSphere 6.5 U2 數據庫類型:Microsoft SQL Server 2008

技術進階Kubernetes高階架構與應用狀態部署

在瞭解Kubernetes應用狀態部署前,我們先看看Kubernetes的高階架構,方便更好的理解Kubernetes的狀態。 Kubernetes 的高階架構 包括應用程式部署模型,服務發現和負載均衡,內部/外部路由分離、persistentvolume 的使用,部署節點守護程式,部

Xfermode改變按鈕背景或者drawable的狀態顏色

按鈕圖示顏色隨著點選改變顏色,如果用selector就會增大記憶體,特別是按鈕背景顏色不是春色的時候,就要用到兩張drawable資源。 1.如果用view的api設定forceground呢?,先見這個api的前後效果 int color=ContextCompat.ge

分享知識-快樂自己Hibernate物件的三種狀態

圖解:   1):瞬時狀態(Transient)   物件與session沒有關聯,資料庫中沒有對應的資料。   一般new出來的物件便是瞬時物件。   對瞬時物件使用save()方法便使之成為持久物件。   由於資料庫中沒有對應的資料,所以對瞬時物件使用update()方法無效。

HDU - 6185 Covering(矩陣乘法&狀態壓縮)

Bob's school has a big playground, boys and girls always play games here after school. To protect boys and girls from getting hurt when playing happi

nginxnot a directory

專案需要在nginx中提供一個配置檔案返回介面的資訊,於是就添加了location來實現,本以為很簡單的操作,結果訪問配置檔案時一直返回404,nginx的error log中輸出:not a directory。 nginx的配置如下所示: 日誌中的報錯如下: 找了半天沒發現有啥問題,在另臺測

併發程式設計實戰(1)執行緒安全性之有狀態和無狀態物件

程序和執行緒的區別 程序是具有一定獨立功能的程式關於某個資料集合上的一次執行活動,程序是系統進行資源分配和排程的一個獨立單位. 執行緒是程序的一個實體,是CPU排程和分派的基本單位,它是比程序更小的能獨立執行的基本單位. 程序在執行過程中擁有獨立的記憶體單元,程序

深入理解Nginx模組開發與架構解析

讀書筆記 第一部分         Nginx能幫我們做什麼 第1章 研究Nginx前的準備工作         1.1Nginx是什麼         1.2

火箭我今天不在最佳狀態 威爾遜定會拿世界冠軍

11月29日訊息,@北京商報從度小滿金融人士處獲悉,百度正式拿到准許經營證券期貨的許可證。據許可證顯示,機構名稱為北京百度百盈科技有限公司(下稱“百度百盈”),證券期貨業務經營範圍為基金銷售。而今年8月22日,根據北京證監局官網顯示,證監局已核准百度百盈證券投資基金銷售業務資格。 企查查資訊顯示,百度百盈成

寫if-else不外乎兩種場景異常邏輯處理和不同狀態處理。

寫if-else不外乎兩種場景:異常邏輯處理和不同狀態處理。 異常邏輯處理說明只能一個分支是正常流程,而不同狀態處理都所有分支都是正常流程。 第一個例子`if (obj != null)`是異常處理,是程式碼健壯性判斷,只有if裡面才是正常的處理流程,`else`分支是出錯處理流程 //舉例一:異