框架 thinkPHP5.0.24 + workerman + GatewayWorker + gatewayclient
使用AsyncTcpConnection類連接歐易交易所 執(zhí)行的業(yè)務(wù)邏輯是每收到一條信息就推送給所有客戶端 如圖
一共有兩個(gè)任務(wù) (因?yàn)榻涌诓灰粯?所以啟動(dòng)了兩個(gè)workerman)
GatewayWorker里面沒(méi)有什么業(yè)務(wù)代碼 只是提供連接 都是通過(guò) gatewayclient推送 下方有截圖
啟動(dòng)時(shí)是沒(méi)有問(wèn)題 過(guò)兩三個(gè)小時(shí)就會(huì)報(bào)錯(cuò)以下錯(cuò)誤
stream_socket_client(): Unable to connect to tcp://127.0.0.1:2900 (通常每個(gè)套接字地址(協(xié)議/網(wǎng)絡(luò)地址/端口)只允許使用一次。) in E:\php\amm\vendor\workerman\gatewayclient\Gateway.php:1254
windows php8啟動(dòng)腳本
復(fù)現(xiàn)步驟我也不清楚 像是隨機(jī)出現(xiàn) 有時(shí)候運(yùn)行半個(gè)小時(shí)就會(huì)直接報(bào)錯(cuò) 有時(shí)候五六個(gè)小時(shí)才會(huì)報(bào)錯(cuò)
我也遇到和你差不多的情況,我的分析是workerman的原因.
從報(bào)錯(cuò)理解上來(lái)看,應(yīng)該是端口耗光了.
我是做壓測(cè)的時(shí)候遇到的,
此時(shí)重啟workerman該問(wèn)題還存在,說(shuō)明它并沒(méi)有請(qǐng)求結(jié)束就關(guān)閉通信,
再等個(gè)幾秒鐘,就會(huì)自己就好了.我猜測(cè)有定時(shí)器再檢測(cè),導(dǎo)致關(guān)閉不及時(shí),所以耗光了端口
這個(gè)是網(wǎng)絡(luò)編程基礎(chǔ)知識(shí)。
作為客戶端(例如gatewayClient)每發(fā)起一個(gè)TCP連接會(huì)占用本地一個(gè)臨時(shí)端口,連接關(guān)閉后這個(gè)端口不會(huì)被操作系統(tǒng)立刻釋放,端口進(jìn)入timewait狀態(tài),大概持續(xù)60-240s,用來(lái)保證連接安全的關(guān)閉。如果頻繁的發(fā)起連接建立和關(guān)閉,這個(gè)timewait狀態(tài)的端口數(shù)會(huì)迅速增加,最終占滿所有端口。還有這個(gè)端口數(shù)不是想象中的6萬(wàn),一般是1-3萬(wàn),操作系統(tǒng)保留了一些,通過(guò)內(nèi)核配置可以修改增加數(shù)量。
你用ab壓測(cè)nginx也一樣,壓測(cè)個(gè)1-3萬(wàn)個(gè)請(qǐng)求就報(bào)這個(gè)錯(cuò)了。重啟nginx也不行,要等一會(huì)兒timewait的狀態(tài)的端口被操作系統(tǒng)釋放掉才行。