关于自定义进程的问题

redsky

问题描述

应用场景:学校,同步钉钉数据

我有个需求,系统每天定时同步钉钉数据,管理人员也可以手动同步钉钉数据。
每个学校同步数据根据学校规模耗时大概1-5分钟不等,现有近150所学校需要进行数据同步,如果不做异步任务处理,进程阻塞,整个业务肯定会受影响,因此,我想是否可以将接收到的这些任务,交给新开的进程去做(不影响业务自身的进程数,即新开的进程是在cpu_count() * 2这个数量以外的),后端接收到任务后,直接返回任务提交成功的数据。

为此你搜索到了哪些方案及不适用的原因

我大致看了下自定义进程的内容,不是太明白。请老大指点,具体做哪几步?

1161 2 4
2个回答

2548a

逻辑大概就是: 开一个自定义进程,里面监听text 协议,然后里面接收到正确同步消息的时候,去同步数据.
你api接口收到同步请求,接着发送同步请求消息到自定义进程里面,然后响应前端任务提交成功.

  • redsky 2022-12-24

    首先非常感谢,我按照官方和大家的思路,做了如下三步。

    process配置如下:
    'sync_task' => [
    'handler' => process\SyncTask::class,
    'listen' => 'text://0.0.0.0:8888',
    'count' => 5,
    'reusePort' => true
    ],

    SyncTask:

    public function onMessage(AsyncTcpConnection $connection, $data)
    {
        Cache::set('send', $data, false);
        $connection->send($data.'1111');
    
    }
    public function onClose(AsyncTcpConnection $connection)
    {
        Cache::set('onClose', true, false);
    }

    controller:

      $task_connection = new AsyncTcpConnection('text://127.0.0.1:8888');
      $task_connection->send('aa');
      $task_connection->onMessage = function (AsyncTcpConnection $connection, $result) use ($task_connection) {
           Cache::set('task', $result);
      };
      $task_connection->connect();
      return $this->success('ok');

    以上不知道是否正确,前端请求直接返回成功,但是缓存中没有存入任何数据,是没有执行异步任务吗?不知道这样哪里错了,请大佬们指点。

2548a

1 控制器代码用下面函数通知自定义进程.
2 SyncTask 里面onMessage 里面send 后直接调用$connection->close();关闭链接.
3 执行异步任务是在自定义进程 SyncTask 里面调用同步数据代码,你上面没看到有调用逻辑.

/**
 * @param $port int 端口
 * @param array $data 发送的数据
 * @return mixed
 * 发送text协议
 */
function sendTextSocket($port, $data = [])
{

    // 建立socket连接到内部推送端口
    $client = stream_socket_client('tcp://127.0.0.1:' . $port, $errno, $errmsg, 1);

    // 发送数据,注意5678端口是Text协议的端口,Text协议需要在数据末尾加上换行符
    fwrite($client, json_encode($data) . "\n");
    // 读取推送结果
    $res = fread($client, 8192);
}
年代过于久远,无法发表回答
🔝