需要3秒请求一次 API接口,不管3秒内是否请求到,必须在上一次请求的3秒后再次发出请求。
第1次请求--------2024-06-03 01:32:28
第2次请求--------2024-06-03 01:32:31
第3次请求--------2024-06-03 01:32:34
第4次请求--------2024-06-03 01:32:37
。
。
。
目前使用的是Crontab结合异步请求。
疑问:请问大佬们,这种方案会出现什么异常,如:连接过多或者跑满内存等问题?
代码1如下
<?php
use Workerman\Worker;
require __DIR__ . '/vendor/autoload.php';
use Workerman\Crontab\Crontab;
$worker = new Worker();
// 设置时区,避免运行结果与预期不一致
date_default_timezone_set('PRC');
$worker->onWorkerStart = function () {
// 每分钟的第1秒执行.
$http = new Workerman\Http\Client();
new Crontab('*/3 * * * * *', function() use ($http){
$http->request('https://www.workerman.net', [
'method' => 'POST',
'version' => '1.1',
'headers' => ['content-type' => 'application/json','Connection' => 'keep-alive'],
'data' => json_encode(['detail' => true]),
'success' => function ($response) {
$result = $response->getBody();
$result = json_decode($response->getBody(),true);
echo date('Y-m-d H:i:s')."\n";
},
'error' => function ($exception) {
echo $exception;
}
]);
});
};
Worker::runAll();
代码2如下
<?php
use Workerman\Worker;
use Workerman\Timer;
require_once __DIR__ . '/vendor/autoload.php';
//发送请求
function request($http)
{
$http->request('https://www.workerman.net/', [
'method' => 'POST',
'version' => '1.1',
'headers' => ['content-type' => 'application/json','Connection' => 'keep-alive'],
'data' => json_encode(['detail' => true]),
'success' => function ($response) {
$result = $response->getBody();
$result = json_decode($response->getBody(),true);
},
'error' => function ($exception) {
echo $exception;
}
]);
}
$task = new Worker();
// 开启多少个进程运行定时任务,注意业务是否在多进程有并发问题
$task->count = 1;
$task->onWorkerStart = function(Worker $task)
{
$http = new Workerman\Http\Client();
Timer::add(3, 'request',[$http],true);
};
// 运行worker
Worker::runAll();
那你不应该使用定时器 应该使用Timer::add() persistent参数传false;
我是这样想的,你可以尝试一下是否能够满足需求,我并没有实际使用过这种方式
这段代码的意思就是请求后3s后再次执行$cb方法,persistent-false表示定时器不循环执行,就是执行一次的意思
如果按照这样说,请求成功后才会Timer::add,如果请求返回结果为2秒,加上定时器的3秒 那么第一次请求和第二次请求就是5秒了
这个你可以自己进行计算的嘛 比如开始获取一下$start = time() 然后请求后获取一下time()-$start
这样还是不能保证3秒执行,如果请求时间超过5秒了就嘎了
如果一定的3s执行 那就不管http请求呗 反正
Workerman\Http\Client
本来就是异步的你就Timer::add(3,$cb) 发送一个请求就完了 不管请求执行了几秒
OK 好的 我尝试一下 感谢
那其实你现在的逻辑并没问题,就是3s发送一次请求嘛
Workerman\Http\Client
是异步的 又不管时间,我理解错了题意思,我以为是请求后才能在发送下一个请求麻烦帮我看下代码2是否有问题,目前测试执行效果和代码1是一致
这里为啥不直接Timer::add(3, fn),然后fn去异步处理
使用定时器结合http-client吗?或者说我现在的方案是有什么问题
没看出有啥问题,但要是我的话就选方案二了,在webman里面有Timer了就直接用了
好来哥。我听你的