我發(fā)現(xiàn) http-client 是有最大并發(fā)數(shù)的
比如修改配置參數(shù) 中的max_conn_per_addr 就能調(diào)整最大并發(fā)參數(shù)了
$options = [
'max_conn_per_addr' => 1000, // 每個(gè)域名最多維持多少并發(fā)連接
'keepalive_timeout' => 30, // 連接多長(zhǎng)時(shí)間不通訊就關(guān)閉
'connect_timeout' => 30, // 連接超時(shí)時(shí)間
'timeout' => 30, // 請(qǐng)求發(fā)出后等待響應(yīng)的超時(shí)時(shí)間
];
因?yàn)槲以陧憫?yīng)的位置 增加了一個(gè) 接口日志的輸出
然后就發(fā)現(xiàn)有個(gè)奇怪的現(xiàn)象,有時(shí)候我發(fā)起了請(qǐng)求。 但是 接口日志中是不存在輸出的
我猜測(cè)是因?yàn)? 并發(fā)的連接數(shù) 達(dá)到了上限 所以 調(diào)用 $http->request() 方法的時(shí)候 他實(shí)際上沒(méi)有發(fā)起請(qǐng)求,直接忽略了
對(duì)此,我首先的解決方案 就是 直接調(diào)大了 max_conn_per_addr 參數(shù) 從最開始的 128 改成了 5000,
上面的那種 奇怪的現(xiàn)象就不存在了,但是 隨著請(qǐng)求量的增加。 服務(wù)器的負(fù)載跟cpu 極速上升,直接來(lái)到了100% 網(wǎng)站也直接504了
所以,我后來(lái)就想了下 我需要在發(fā)起請(qǐng)求之前。 再增加一個(gè)請(qǐng)求隊(duì)列
先把要發(fā)起的請(qǐng)求 都丟到隊(duì)列中去。
然后 定頻的去從隊(duì)列中 獲取 要請(qǐng)求的數(shù)據(jù)。 然后發(fā)起請(qǐng)求
但是 這又帶來(lái)一個(gè)問(wèn)題。 因?yàn)?被請(qǐng)求方,有時(shí)候響應(yīng)快 有時(shí)候響應(yīng)慢。
我就不知道 http-client 當(dāng)前有多少并發(fā)連接數(shù)了。 我要怎么獲取到當(dāng)前的并發(fā)連接數(shù)呢?
因?yàn)槿绻?并發(fā)連接數(shù)滿了的話, 我這時(shí)候去發(fā)去請(qǐng)求,他是無(wú)效的 彷佛直接未執(zhí)行該動(dòng)作一樣
記錄并發(fā)請(qǐng)求數(shù)。 我暫時(shí)相當(dāng)?shù)姆椒ň褪? 在發(fā)起請(qǐng)求的時(shí)候 往redis 中+1
請(qǐng)求響應(yīng)回來(lái)的時(shí)候 -1 這樣 完成數(shù)值的記錄。
但是。又怕不準(zhǔn)確。
所以 http-client 類的話有直接獲取到當(dāng)前并發(fā)的請(qǐng)求數(shù)嘛?
升級(jí)下http-client,剛剛發(fā)了一個(gè)新版 v2.2.8
2.2.7 可能有bug,導(dǎo)致超過(guò)并發(fā)的請(qǐng)求無(wú)法發(fā)起。
http-client 自帶一個(gè)內(nèi)存隊(duì)列,一般不用再加隊(duì)列。
感覺好像還是有問(wèn)題。 現(xiàn)在的問(wèn)題是 對(duì)方有收到請(qǐng)求,但是我這邊沒(méi)有接收到響應(yīng) 我是這樣寫的 但是那個(gè) 記錄請(qǐng)求日志 記錄的日志數(shù)非常的少。 發(fā)起了 數(shù)千條請(qǐng)求, 但是只有幾百條日志
try {
// 請(qǐng)求計(jì)數(shù)
$http->request($url,[
'method'=>$op['type'],// 請(qǐng)求類型
'headers'=>(array)$op['header'],// 請(qǐng)求頭
'proxy'=>$op['proxy']?:'',// 代理
'data'=>$op['data']??[],// post參數(shù)
'success'=>function(\Workerman\Http\Response $res) use ($url,$op,$callback,$key){
// QueueService::removeTask($key);
// 記錄請(qǐng)求日志
$body = $res->getBody()->getContents();
Redis::send(QueueName::HTTPL_LOG, [
'url'=>$op['name'],
'method'=>$op['type'],
'data'=>$op['log_data']?:$op['data'],
'response'=>$body,
'exception'=>$res->getStatusCode(),
'exec_time'=>(microtime(true) - $op['start_time'])1000,// 記錄結(jié)束時(shí)間
]);
if($callback){
$callback($res);
}
},
'error'=>function($err) use ($url,$op,$key){
// QueueService::removeTask($key);
// 記錄請(qǐng)求日志
Redis::send(QueueName::HTTPL_LOG, [
'url'=>$op['name'],
'method'=>$op['type'],
'data'=>$op['data'],
'response'=>json_encode($err),
'exception'=>500,
'exec_time'=>(microtime(true) - $op['start_time'])1000,// 記錄結(jié)束時(shí)間
]);
}
]);
}catch (\Throwable $e){
// QueueService::removeTask($key);
Logger::debug(['api請(qǐng)求出錯(cuò)',$e->getMessage()]);
}
最大并發(fā)數(shù) 調(diào)低 比如說(shuō) 改成64 然后就會(huì)出現(xiàn)很多 意料之外的情況。 比如 這個(gè)日志不輸出了,最大并發(fā)數(shù) 我改成1000后。 日志的輸出就感覺又正常了。 不過(guò)是 cpu 有點(diǎn)頂不住, 但是 改成64的時(shí)候 cpu和負(fù)載剛開始是正常的, 到后面 也開始頂不住。 進(jìn)入滿負(fù)載了。。
看下日志,比如workerman.log
有問(wèn)題的時(shí)候 php start.php status 截圖下。注意是有問(wèn)題的時(shí)候截圖。
今天有時(shí)間, 又圍著這個(gè)組件 進(jìn)行了測(cè)試, 是都有發(fā)起請(qǐng)求的, 之前沒(méi)有日志 應(yīng)該是 接口那邊超時(shí)后, 錯(cuò)誤的響應(yīng)我沒(méi)有處理好, 不過(guò) 對(duì)于 它的配置信息 $options = [
'max_conn_per_addr' => 128, // 每個(gè)域名最多維持多少并發(fā)連接
'keepalive_timeout' => 15, // 連接多長(zhǎng)時(shí)間不通訊就關(guān)閉
'connect_timeout' => 30, // 連接超時(shí)時(shí)間
'timeout' => 30, // 請(qǐng)求發(fā)出后等待響應(yīng)的超時(shí)時(shí)間
]; connect_timeout 是指 正式發(fā)起請(qǐng)求后的超時(shí)時(shí)間嗎(不含在隊(duì)列中等待的時(shí)間) timeout 則是含在隊(duì)列中等待的時(shí)間 ,那 keepalive_timeout 是什么呢 并發(fā)會(huì)申請(qǐng)鏈接,這個(gè)鏈接15秒內(nèi)沒(méi)有發(fā)送過(guò)請(qǐng)求,就會(huì)關(guān)閉, 老大我理解有問(wèn)題不 QwQ
http1.1協(xié)議支持復(fù)用連接, 也就是可以在一個(gè)連接上實(shí)現(xiàn)多次http請(qǐng)求響應(yīng), 當(dāng)連接沒(méi)有請(qǐng)求時(shí)需要回收連接,
比如keepalive_timeout = 30 就是連接上超過(guò)30秒沒(méi)有請(qǐng)求則回收連接
在隊(duì)列里還沒(méi)執(zhí)行不算超時(shí)時(shí)間,只有發(fā)起請(qǐng)求后才開始請(qǐng)求才算