在處理連續(xù)命令時,有些連續(xù)命令遺失,最後發(fā)現(xiàn)在sendBufferToWorker這個函數(shù)並沒有將收到的命令送到Worker去,好像在前一個命令處理完後即調(diào)用closeInnerClient($fd)將連線關(guān)閉。導(dǎo)致sendBufferToWorker沒有將命令送出去。
protected function sendBufferToWorker($bin_data)
{
print_r("\nsendBufferToWorker:".$this->currentDealFd);
if($this->currentDealFd = array_rand($this->workerConnections))
{
$this->sendToClient($bin_data);
echo("\nsend success!!!!");
}else{
echo("\nsend fault!!!!");
}
}
為什麼會發(fā)生這種情況?
謝謝。
workerman長連接應(yīng)用剛啟動時,Gateway于BusinessWorker之間會建立連接,在連接沒建立好時,會有數(shù)據(jù)丟失情況。workerman啟動到建立連接完畢大概需要1-2秒的時間,也就是說目前長連接應(yīng)用要等workerman啟動后需要等待1-2秒才能正常工作,后面會針對這個問題做優(yōu)化
如果不是上述問題導(dǎo)致,可以嘗試或者檢查以下項目:
1、請確認下配置是與線上一致,尤其是 persistent_connection ,max_requests
2、查看workerman/log/date/server.log 看是否有進程異常退出的日志
3、檢查php日志是否有FatalError等致命錯誤
您好,承上面的問題,我的程式是由 底下的 這個地方關(guān)閉鏈接,因為 $this->workerConnections 已經(jīng)清空了,導(dǎo)致後下一個命令無法送至Worker。
為什麼,會出現(xiàn) if('' == $buffer && '' == ($buffer = fread($connection, $this->recvBuffers))) 這個狀態(tài),然後關(guān)閉連線呢?
謝謝,您的回覆。
public function recvTcp($connection, $flag, $fd = null)
{
$this->currentDealFd = $fd;
$buffer = stream_socket_recvfrom($connection, $this->recvBuffers);
// 出錯了
if('' == $buffer && '' == ($buffer = fread($connection, $this->recvBuffers)))
{
if(!feof($connection))
{
return;
}
// 如果該鏈接對應(yīng)的buffer有數(shù)據(jù),說明發(fā)生錯誤
if(!empty($this->recvBuffers))
{
$this->statusInfo++;
$this->notice("INNER_CLIENT_CLOSE\nCLIENT_IP:".$this->getRemoteIp()."\nBUFFER:\n");
}
// 關(guān)閉鏈接
$this->closeInnerClient($fd);
if($this->workerStatus == self::STATUS_SHUTDOWN)
{
$this->stop();
}
return;
}
$this->recvBuffers .= $buffer;
$remain_len = $this->dealInnerInput($this->recvBuffers);
// 包接收完畢
if(0 === $remain_len)
{
// 執(zhí)行處理
try{
// 內(nèi)部通訊業(yè)務(wù)處理
$this->innerDealProcess($this->recvBuffers);
}
catch(\Exception $e)
{
$this->notice('CODE:' . $e->getCode() . ' MESSAGE:' . $e->getMessage()."\n".$e->getTraceAsString()."\nCLIENT_IP:".$this->getRemoteIp()."\nBUFFER:\n");
$this->statusInfo ++;
}
$this->recvBuffers = array('buf'=>'', 'remain_len'=>GatewayProtocol::HEAD_LEN);
}
// 出錯
else if(false === $remain_len)
{
// 出錯
$this->statusInfo++;
$this->notice("INNER_PACKET_ERROR\nCLIENT_IP:".$this->getRemoteIp()."\nBUFFER:\n");
$this->closeInnerClient($fd);
}
else
{
$this->recvBuffers = $remain_len;
}
// 檢查是否是關(guān)閉狀態(tài)或者是否到達請求上限
if($this->workerStatus == self::STATUS_SHUTDOWN )
{
// 停止服務(wù)
$this->stop();
// EXIT_WAIT_TIME秒后退出進程
pcntl_alarm(self::EXIT_WAIT_TIME);
}
}
我找到這個問題的原因,因為在做測試 將啟動行程數(shù)量改為1,您的BusinessWorker連接為
短連接,所以每處理一次命令就會中斷與 GateWay 的連線 , 在發(fā)送連續(xù)命令時剛好碰到
$this->workerConnections 連線數(shù)為零,就沒將數(shù)據(jù)送出。
您是否能設(shè)計保險一點,增加一個Queues,來保存沒有送出的命令。
protected function sendBufferToWorker($bin_data)
{
if($this->currentDealFd = array_rand($this->workerConnections))
{
$this->sendToClient($bin_data);
}else{
// 加到 佇列 Queues 等候再發(fā)送。
}
}
謝謝您。