Linux過多TIME_WAIT問題解決

0x00 問題

一個(gè)服務(wù)器運(yùn)行用nginx的web服務(wù)哄陶,PHP訪問mysql;由于php需要頻繁的訪問數(shù)據(jù)庫,而且使用的都是短鏈接,因此一段時(shí)間內(nèi)產(chǎn)生并保持大量的TIME_WAIT卸奉。

$ netstat -an | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'

LAST_ACK 11
LISTEN 11
SYN_RECV 42
ESTABLISHED 172
FIN_WAIT1 13
FIN_WAIT2 11
CLOSING 1
SYN_SENT 38
TIME_WAIT 3792

0x01 危害

系統(tǒng)長期保持大量的TIME_WAIT,相應(yīng)的會占用大量的系統(tǒng)資源,同時(shí)還會占用大量的端口和連接數(shù)尚粘,導(dǎo)致新來的請求無法被服務(wù)器及時(shí)響應(yīng)處理择卦;默認(rèn)情況下敲长,linux臨時(shí)端口號范圍是(32768,61000)郎嫁,本機(jī)可用于調(diào)用的端口約3萬個(gè),進(jìn)而導(dǎo)致調(diào)用后端服務(wù)阻塞祈噪,頁面響應(yīng)變慢泽铛;

0x02 解決辦法

根據(jù)以上分析,需要對系統(tǒng)內(nèi)核參數(shù)進(jìn)行優(yōu)化辑鲤,啟用TIME_WAIT連接重用盔腔,TIME_WAIT連接回收、縮短連接保持時(shí)間、增加可用端口數(shù):

vi /etc/sysctl.conf

net.ipv4.tcp_tw_reuse = 1                   # 連接重用
net.ipv4.tcp_tw_recycle = 1                 # 連接回收
net.ipv4.tcp_fin_timeout = 30               # 連接保持時(shí)間
net.ipv4.ip_local_port_range=1024 65000     # 增加端口數(shù)量

sysctl -p    # 生效

通常情況下弛随,設(shè)置前三條即可瓢喉,減少了TIME_WAIT數(shù)量,端口占用也會緩解舀透,但如果服務(wù)的并發(fā)量本來就很大栓票,增加端口數(shù)量就很有必要;

優(yōu)化生效后愕够,TIME_WAIT明顯減少:

$ netstat -an | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'

LAST_ACK 17
LISTEN 11
SYN_RECV 25
ESTABLISHED 107
FIN_WAIT1 9
FIN_WAIT2 23
CLOSING 2
SYN_SENT 14
TIME_WAIT 217

0x03 注意

  • 需要確認(rèn) net.ipv4.tcp_timestamps = 1 是打開的(默認(rèn)是打開的)走贪,因?yàn)橹挥衪imestamps打開了,net.ipv4.tcp_tw_recycle = 1 才會生效惑芭;

  • 當(dāng) net.ipv4.tcp_timestampsnet.ipv4.tcp_tw_recycle 同時(shí)打開坠狡,對通過NAT網(wǎng)關(guān)訪問服務(wù)器的連接會有問題,因?yàn)?tcp_tw_recycle/tcp_timestamps 都開啟的條件下遂跟,60s內(nèi)同一源ip主機(jī)的socket connect請求中的timestamp必須是遞增的逃沿。而timestamp時(shí)間為系統(tǒng)啟動(dòng)到當(dāng)前的時(shí)間,因此幻锁,不同客戶端的timestamp不相同感挥,timestamp 大的客戶端可以正常訪問,timestamp小的客戶端則訪問失斣桨堋触幼; 這種情況建議關(guān)閉 tcp_tw_recycle 選項(xiàng),而不是 timestamp究飞;因?yàn)?在tcp timestamp關(guān)閉的條件下置谦,開啟tcp_tw_recycle是不起作用的;而tcp timestamp可以獨(dú)立開啟并起作用亿傅。

0x04 總結(jié)

  • 使用過多的短連接媒峡,導(dǎo)致了大量的TIME_WAIT;在服務(wù)設(shè)計(jì)時(shí)葵擎,應(yīng)盡量采用長連接谅阿,連接池,KEEPALIVE等技術(shù)減少對后端的連接次數(shù)酬滤,提高連接的效率签餐。

  • 這次的問題,因PHP本身的特性盯串,一個(gè)頁面處理完成后氯檐,所有相關(guān)連接就斷了,不太好使用長連接体捏,連接池冠摄,KEEPALIVE技術(shù)糯崎;

0x05 確有頻繁訪問時(shí),以上設(shè)置并不能減少 TIME_WAIT

  • 當(dāng)服務(wù)器卻又很多用戶頻繁訪問河泳,以上針對系統(tǒng)的優(yōu)化并不能達(dá)到效果沃呢。

  • 原因試試php頁面訪問mysql采用的是短連接,用完就斷開拆挥,頻繁訪問必然產(chǎn)生很多TIME_WAIT樟插;

  • 解決辦法, 采用長連接的方式訪問數(shù)據(jù)庫竿刁,這里采用php的PDO擴(kuò)展訪問mysql黄锤,長連接還能提高性能:

   lang="php">$db_host="localhost:3306";
    $db_username="user";
    $db_password="";
    $dsn = "mysql:host=$db_host;dbname=$database;";
    
    try {
     $sql = new PDO($dsn,$db_username,$db_password,array(PDO::ATTR_PERSISTENT => true));//PDO::ATTR_PERSISTENT => true 表示采用持久化連接;
    } catch(PDOException $e){
     die($e->getMessage());
    }
    
    try{
     $result = $sql->query("select * from accounts where id = '".$sn."';");
     } catch(PDOException $e){
     die($e->getMessage());
     }
     $rows = $result->fetchAll(PDO::FETCH_ASSOC);// 這里要注意食拜,查詢結(jié)果只能調(diào)用一次fetch鸵熟,后面再調(diào)用就返回空了,所以這個(gè)地方第一次調(diào)用就要保存下來給后續(xù)使用负甸;
     if(count($rows) == 1){
     $row = $rows[0];// 多個(gè)結(jié)果時(shí)流强,foreach 遍歷即可
     .....
     }
    或者:
     foreach($dbh->query('SELECT * from FOO') as $row) {
     print_r($row);
     }
  • php7.2 設(shè)置支持PDO擴(kuò)展

vim /etc/php/7.2/cli/php.ini 這個(gè)配置文件是配置php命令行運(yùn)行環(huán)境;
vim /etc/php/7.2/fpm/php.ini 這個(gè)配置 php-fpm呻待,里面 extension=pdo_mysql 是注釋掉的打月,但是 /etc/php/7.2/fpm/conf.d/20-pdo_mysql.ini 中有定義,所以應(yīng)該是默認(rèn)支持pdo的蚕捉;</pre>

打開注釋: extension=pdo_mysql 即可奏篙;

系統(tǒng)優(yōu)化后,再使用PDO長連接訪問mysql迫淹,TIME_WAIT連接數(shù)秘通,直線下跌幾乎沒有;

原文

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末敛熬,一起剝皮案震驚了整個(gè)濱河市肺稀,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌应民,老刑警劉巖话原,帶你破解...
    沈念sama閱讀 211,194評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異诲锹,居然都是意外死亡繁仁,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評論 2 385
  • 文/潘曉璐 我一進(jìn)店門辕狰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來改备,“玉大人控漠,你說我怎么就攤上這事蔓倍⌒” “怎么了?”我有些...
    開封第一講書人閱讀 156,780評論 0 346
  • 文/不壞的土叔 我叫張陵偶翅,是天一觀的道長默勾。 經(jīng)常有香客問我,道長聚谁,這世上最難降的妖魔是什么母剥? 我笑而不...
    開封第一講書人閱讀 56,388評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮形导,結(jié)果婚禮上环疼,老公的妹妹穿的比我還像新娘。我一直安慰自己朵耕,他們只是感情好炫隶,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著阎曹,像睡著了一般伪阶。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上处嫌,一...
    開封第一講書人閱讀 49,764評論 1 290
  • 那天栅贴,我揣著相機(jī)與錄音,去河邊找鬼熏迹。 笑死檐薯,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的注暗。 我是一名探鬼主播厨剪,決...
    沈念sama閱讀 38,907評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼友存!你這毒婦竟也來了祷膳?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,679評論 0 266
  • 序言:老撾萬榮一對情侶失蹤屡立,失蹤者是張志新(化名)和其女友劉穎直晨,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體膨俐,經(jīng)...
    沈念sama閱讀 44,122評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡勇皇,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了焚刺。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片敛摘。...
    茶點(diǎn)故事閱讀 38,605評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖乳愉,靈堂內(nèi)的尸體忽然破棺而出兄淫,到底是詐尸還是另有隱情屯远,我是刑警寧澤,帶...
    沈念sama閱讀 34,270評論 4 329
  • 正文 年R本政府宣布捕虽,位于F島的核電站慨丐,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏泄私。R本人自食惡果不足惜房揭,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望晌端。 院中可真熱鬧捅暴,春花似錦、人聲如沸咧纠。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽惧盹。三九已至乳幸,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間钧椰,已是汗流浹背粹断。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留嫡霞,地道東北人瓶埋。 一個(gè)月前我還...
    沈念sama閱讀 46,297評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像诊沪,于是被迫代替她去往敵國和親养筒。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評論 2 348

推薦閱讀更多精彩內(nèi)容