zoukankan      html  css  js  c++  java
  • TASK异步进程处理场景

    如消息队列,可以把复杂任务异步交给swoole的task进程处理。
    大数据处理,如发送10000个EMAIL,可以异步交给swoole的task进程处理。

    服务端应用程序

    CLI 挂载启动服务端程序:php server.php

    $serv = new swoole_server('127.0.0.1', 9501);
    
    // 配置多少进程处理,传递给task函数是异步的
    // 如果配置的是1,task会单进程方式把所有授予的任务依次处理完毕
    $serv->set([
        'task_worker_num' => 1,
    ]);
    
    $serv->on('Connect', function ($serv, $fd) {
        echo "new client connected." . PHP_EOL;
    });
    
    $serv->on('Receive', function ($serv, $fd, $fromId, $data) {
        echo "worker received data: {$data}" . PHP_EOL;
    
        // 投递一个任务到task进程中
        $serv->task($data);
    
        // 通知客户端server收到数据了
        $serv->send($fd, 'This is a message from server.');
    
        // 为了校验task是否是异步的,这里和task进程内都输出内容,看看谁先输出
        echo "worker continue run."  . PHP_EOL;
    });
    
    /**
     * $serv swoole_server
     * $taskId 投递的任务id,因为task进程是由worker进程发起,所以多worker多task下,该值可能会相同
     * $fromId 来自那个worker进程的id
     * $data 要投递的任务数据
     */
    $serv->on('Task', function ($serv, $taskId, $fromId, $data) {
        echo "task start. --- from worker id: {$fromId}." . PHP_EOL;
        for ($i=0; $i < 100; $i++) {
            sleep(1);
            echo "task runing. --- {$i}" . PHP_EOL;
        }
        echo "task end." . PHP_EOL;
    });
    
    /**
     * 只有在task进程中调用了finish方法或者return了结果,才会触发finish
     */
    $serv->on('Finish', function ($serv, $taskId, $data) {
        echo "finish received data '{$data}'" . PHP_EOL;
    });
    
    $serv->start();
    

    客户端应用程序

    客户端启动发送数据:php client.php

    $client = new swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_SYNC);
    
    // 随后建立连接,连接失败直接退出并打印错误码
    $client->connect('127.0.0.1', 9501) || exit("connect failed. Error: {$client->errCode}\n");
    // 向服务端发送数据
    $client->send("hello server.");
    // 从服务端接收数据
    $response = $client->recv();
    // 输出接受到的数据
    echo $response . PHP_EOL;
    
    // 关闭连接
    $client->close();
    

    本篇总结:

    1. 没有耗时任务的情况下,worker直接运行,无需开启task

    2. 对于耗时的任务,可以在worker内调用task函数,把异步任务投递给task进程进行处理,task进程的数量取决于task_worker_num的配置

    3. task进程内可以选择调用finish方法或者return,来通知worker进程此任务已完成,worker进程会在onFinish回调中对task的执行结果进一步处理。如果worker进程不关心任务的结果,finish就不需要了。

  • 相关阅读:
    Set,List,Map,Vector,ArrayList的区别
    关于List,Set,Map能否存储null
    JAVA集合 DelayQueue 的使用 (同步的超时队列)
    FluentScheduler .Net 定时Job
    BeanFactory和FactoryBean
    ansj 分词,超过了标准的 IK 分词.
    Python字典、集合结构详解
    Python列表、元组结构详解
    C语言--结构体&文件
    C语言--指针
  • 原文地址:https://www.cnblogs.com/lxwphp/p/15452924.html
Copyright © 2011-2022 走看看