現在django的應用基本都是使用uWSGI來部署,類似下面 listen queue of socket "127.0.0.1:9001" (fd: 3)
的錯誤說下這次錯誤出現的解決的過程。
出錯場景
- centos 7.4
- uWSGI 2.0
- nginx 1 .12
錯誤日志截取
*** uWSGI listen queue of socket "127.0.0.1:9001" (fd: 3) full !!! (101/100) *** Tue Jun 2 17:33:28 2015 - *** uWSGI listen queue of socket "127.0.0.1:9001" (fd: 3) full !!! (101/100) ***
-
第一次是因為聯通機房防火牆配置錯了,限制了服務器output,也就是外部發包給服務器沒有問題,但是服務器返回包給外部的時候非常慢,幾乎不可用,這個時候uwsgi日志中就出現了大量的錯誤
-
第二次是並發量劇增之后,活動鏈接保持在6000左右的時候,大量出現這個錯誤。
分析
以這個錯誤為基礎,查詢了下相關資料,應該是系統級別參數的問題,具體可以參考 linux man page listen(2).
簡單的理解就是每個監聽的socket,在沒有accept之前,等待處理的socket隊列長度,linux(至少在centos6.6中)默認是128,在我這個編譯的uwsgi中默認是100,也就是說沒有調整系統參數之前,最高也就是128。
那么怎樣才能把隊列的長度調整變長呢?
* 必須調整系統參數,使其生效
* 必須調整uwsgi配置,然后重啟應用
操作
修改系統參數
這里直接修改配置文件了,重啟后仍然有效。
修改/etc/sysctl.conf文件,添加或者修改這幾個參數值
# 用於設置內核無法及時處理網絡接口收到的數據包時允許發送到隊列的最大數據包數目,默認為128。也就是每個監聽的socket,在沒有accept之前,等待處理的socket隊列長度 net.core.somaxconn = 20480
修改完成之后要記得 sysctl -p
重新加載參數
uwsgi調整
不管是配置,還是命令行加一個選項,例如 uwsgi.ini 文件中在socket= 127.0.0.1:9001下面添加如下配置
listen=10240
之后重啟應用,重新加載配置。
錯誤
1. 當sysctl -p重新加載參數時報錯“sysctl: setting key ‘net.core.somaxconn’: Invalid argument” 無效的參數,
原因:net.core.somaxconn 的值設置的大於USHRT_MAX(Maximum value of a type unsigned short int. 無符號短整型最大值65535,也可以用命令:getconf USHRT_MAX 查看)
修改:net.core.somaxconn的值設置的小於USHRT_MAX就可以了,如10240
小結
通過修改配置,這種錯誤基本沒有出現過了,系統的吞吐量和並發數都大大提高了。所以系統特性和調優對於提高整個服務質量非常重要。