http-client 最大并发数

兔白白

问题描述

我发现 http-client 是有最大并发数的
比如修改配置参数 中的max_conn_per_addr 就能调整最大并发参数了
$options = [
'max_conn_per_addr' => 1000, // 每个域名最多维持多少并发连接
'keepalive_timeout' => 30, // 连接多长时间不通讯就关闭
'connect_timeout' => 30, // 连接超时时间
'timeout' => 30, // 请求发出后等待响应的超时时间
];

因为我在响应的位置 增加了一个 接口日志的输出
然后就发现有个奇怪的现象,有时候我发起了请求。 但是 接口日志中是不存在输出的
我猜测是因为 并发的连接数 达到了上限 所以 调用 $http->request() 方法的时候 他实际上没有发起请求,直接忽略了

对此,我首先的解决方案 就是 直接调大了 max_conn_per_addr 参数 从最开始的 128 改成了 5000,
上面的那种 奇怪的现象就不存在了,但是 随着请求量的增加。 服务器的负载跟cpu 极速上升,直接来到了100% 网站也直接504了

所以,我后来就想了下 我需要在发起请求之前。 再增加一个请求队列
先把要发起的请求 都丢到队列中去。
然后 定频的去从队列中 获取 要请求的数据。 然后发起请求
但是 这又带来一个问题。 因为 被请求方,有时候响应快 有时候响应慢。
我就不知道 http-client 当前有多少并发连接数了。 我要怎么获取到当前的并发连接数呢?
因为如果 并发连接数满了的话, 我这时候去发去请求,他是无效的 彷佛直接未执行该动作一样

记录并发请求数。 我暂时相当的方法就是 在发起请求的时候 往redis 中+1
请求响应回来的时候 -1 这样 完成数值的记录。
但是。又怕不准确。

所以 http-client 类的话有直接获取到当前并发的请求数嘛?

280 1 1
1个回答

walkor 打赏

升级下http-client,刚刚发了一个新版 v2.2.8
2.2.7 可能有bug,导致超过并发的请求无法发起。

http-client 自带一个内存队列,一般不用再加队列。

  • 兔白白 14天前

    哈哈哈 辛苦老大啦。 我升级看看。

  • 兔白白 14天前

    感觉好像还是有问题。 现在的问题是 对方有收到请求,但是我这边没有接收到响应 我是这样写的 但是那个 记录请求日志 记录的日志数非常的少。 发起了 数千条请求, 但是只有几百条日志
    try {
    // 请求计数
    $http->request($url,[
    'method'=>$op['type'],// 请求类型
    'headers'=>(array)$op['header'],// 请求头
    'proxy'=>$op['proxy']?:'',// 代理
    'data'=>$op['data']??[],// post参数
    'success'=>function(\Workerman\Http\Response $res) use ($url,$op,$callback,$key){
    // QueueService::removeTask($key);
    // 记录请求日志
    $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,// 记录结束时间
    ]);
    if($callback){
    $callback($res);
    }
    },
    'error'=>function($err) use ($url,$op,$key){
    // QueueService::removeTask($key);
    // 记录请求日志
    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,// 记录结束时间
    ]);
    }
    ]);
    }catch (\Throwable $e){
    // QueueService::removeTask($key);
    Logger::debug(['api请求出错',$e->getMessage()]);
    }

  • 兔白白 14天前

    最大并发数 调低 比如说 改成64 然后就会出现很多 意料之外的情况。 比如 这个日志不输出了,最大并发数 我改成1000后。 日志的输出就感觉又正常了。 不过是 cpu 有点顶不住, 但是 改成64的时候 cpu和负载刚开始是正常的, 到后面 也开始顶不住。 进入满负载了。。

  • walkor 14天前

    看下日志,比如workerman.log
    有问题的时候 php start.php status 截图下。注意是有问题的时候截图。

  • 兔白白 11天前

    今天有时间, 又围着这个组件 进行了测试, 是都有发起请求的, 之前没有日志 应该是 接口那边超时后, 错误的响应我没有处理好, 不过 对于 它的配置信息 $options = [
    'max_conn_per_addr' => 128, // 每个域名最多维持多少并发连接
    'keepalive_timeout' => 15, // 连接多长时间不通讯就关闭
    'connect_timeout' => 30, // 连接超时时间
    'timeout' => 30, // 请求发出后等待响应的超时时间
    ]; connect_timeout 是指 正式发起请求后的超时时间吗(不含在队列中等待的时间) timeout 则是含在队列中等待的时间 ,那 keepalive_timeout 是什么呢 并发会申请链接,这个链接15秒内没有发送过请求,就会关闭, 老大我理解有问题不 QwQ

  • walkor 11天前

    http1.1协议支持复用连接, 也就是可以在一个连接上实现多次http请求响应, 当连接没有请求时需要回收连接,
    比如keepalive_timeout = 30 就是连接上超过30秒没有请求则回收连接
    在队列里还没执行不算超时时间,只有发起请求后才开始请求才算

×
🔝