热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

laravel异步mysql_基于Swoole在Laravel中实现异步任务队列

基于Swoole在Laravel中实现异步任务队列由学院君创建于1年前,最后更新于1年前版本号#114019views10likes2collectsSwoole异步任务实现原理我

基于 Swoole 在 Laravel 中实现异步任务队列

由 学院君 创建于1年前, 最后更新于 1年前

版本号 #1

14019 views

10 likes

2 collects

Swoole 异步任务

实现原理

我们知道,PHP 本身的设计是同步阻塞的,不支持多线程和异步 IO,所以当我们执行一些耗时的操作,比如发送广播,或者邮件,如果直接在当前进程中操作,会导致服务器响应变慢,因此要借助一些第三方服务来处理以实现异步功能,比如队列,而 Swoole 作为 PHP 异步网络通信引擎,自然也对异步任务处理提供了支持,其底层的实现原理和常见的异步队列类似:将耗时任务投递到 TaskWorker 进程池后返回(相应任务会通过 TaskWorker 异步执行,执行成功后可以调用事先注册的回调函数进行后续处理),继续后续业务逻辑的执行,而不影响当前请求的处理速度。关于 TaskWorker 后面我们介绍 Swoole 底层原理的时候还会详细介绍。

示例代码

我们可以基于 Swoole 入门教程中编写的 TCP 服务器为基础来实现一个异步任务服务器用来处理异步任务,只需添加一个任务处理和一个任务完成回调即可,此外,还需要配置 TaskWorker 进程数以保证任务处理的速度,可以根据任务的耗时和任务量配置其值,通常我们可以将其配置为 CPU 数量的两倍:

$server = new \Swoole\Server("127.0.0.1", 9503);

// 设置异步任务的工作进程数量

$server->set(array('task_worker_num' => 4));

//收到请求时触发

$server->on('receive', function(\Swoole\Server $server, $fd, $from_id, $data) {

//投递异步任务

$task_id = $server->task($data);

echo "异步任务投递成功: id=$task_id\n";

$server->send($fd, "数据已接收,处理中...");

});

// 处理异步任务

$server->on('task', function (\Swoole\Server $server, $task_id, $from_id, $data) {

echo "新的待处理异步任务[id=$task_id]".PHP_EOL;

// todo 处理异步任务

// 返回任务执行的结果

$server->finish("$data -> OK");

});

// 处理异步任务的结果

$server->on('finish', function (\Swoole\Server $server, $task_id, $data) {

echo "异步任务[$task_id] 处理完成: $data".PHP_EOL;

});

$server->start();

我们将该文件保存为 async_task_server.php,然后在命令行启动这个服务器:

php async_task_server.php

php tcp_client.php

服务器投递任务到 TaskWorker 后会立即将处理信息发送给客户端:

d3d44a326b177928ef1448159e442151.png

然后服务器会异步处理任务:

71269a7b5fa18ac889a6fae6e3c95a23.png

在 Laravel 中基于 Swoole 实现异步任务队列

还是以 LaravelS 扩展包为基础,我们在 Laravel 项目中实现基于 Swoole 实现异步任务队列功能,其原理就是上面介绍的 Swoole 异步任务,只不过该扩展包对其做了封装而已。

编写任务类

首先我们创建一个继承自 Hhxsv5\LaravelS\Swoole\Task\Task 基类的待处理任务类 TestTask:

namespace App\Jobs;

use Hhxsv5\LaravelS\Swoole\Task\Task;

use Illuminate\Support\Facades\Log;

class TestTask extends Task

{

// 待处理任务数据

private $data;

// 任务处理结果

private $result;

public function __construct($data)

{

$this->data = $data;

}

// 任务投递调用 task 回调时触发,等同于 Swoole 中的 onTask 逻辑

public function handle()

{

Log::info(__CLASS__ . ': 开始处理任务', [$this->data]);

// todo 耗时任务具体处理逻辑在这里编写

sleep(3); // 模拟任务需要3秒才能执行完毕

$this->result = 'The result of ' . $this->data . ' is balabalabala';

}

// 任务完成调用 finish 回调时触发,等同于 Swoole 中的 onFinish 逻辑

public function finish()

{

Log::info(__CLASS__ . ': 任务处理完成', [$this->result]);

// 可以在这里触发后续要执行的任务,或者执行其他善后逻辑

}

}

编写测试代码

然后在 routes/web.php 编写投递异步任务的测试代码如下:

Route::get('/task/test', function () {

$task = new \App\Jobs\TestTask('测试异步任务');

$success = \Hhxsv5\LaravelS\Swoole\Task\Task::deliver($task); // 异步投递任务,触发调用任务类的 handle 方法

var_dump($success);

});

修改配置文件

此外还要在配置文件 config/laravels.php 中取消 task_worker_num 配置项前面的注释:

'swoole' => [

...

'task_worker_num' => function_exists('swoole_cpu_num') ? swoole_cpu_num() * 2 : 8,

...

]

测试异步任务执行

接下来,我们重启启动 Swoole 服务器(基于 Swoole HTTP 服务器访问路由才能成功投递异步任务):

php bin/laravels restart

然后在浏览器中通过 http://todo-s.test/task/test 访问测试路由,页面立即显示投递成功:

bool(true)

然后我们去 storage/logs 目录下查看最新的日志信息,可以看到任务执行其实耗费了 3 秒:

[2019-05-30 16:31:32] local.INFO: App\Jobs\TestTask: 开始处理任务 ["测试异步任务"]

[2019-05-30 16:31:35] local.INFO: App\Jobs\TestTask: 任务处理完成 ["The result of 测试异步任务 is balabalabala"]

这样,我们就成功在 Laravel 项目中基于 Swoole 实现了异步任务消费队列,很简单吧。



推荐阅读
  • 本文介绍了Python高级网络编程及TCP/IP协议簇的OSI七层模型。首先简单介绍了七层模型的各层及其封装解封装过程。然后讨论了程序开发中涉及到的网络通信内容,主要包括TCP协议、UDP协议和IPV4协议。最后还介绍了socket编程、聊天socket实现、远程执行命令、上传文件、socketserver及其源码分析等相关内容。 ... [详细]
  • 本文介绍了Hyperledger Fabric外部链码构建与运行的相关知识,包括在Hyperledger Fabric 2.0版本之前链码构建和运行的困难性,外部构建模式的实现原理以及外部构建和运行API的使用方法。通过本文的介绍,读者可以了解到如何利用外部构建和运行的方式来实现链码的构建和运行,并且不再受限于特定的语言和部署环境。 ... [详细]
  • http:my.oschina.netleejun2005blog136820刚看到群里又有同学在说HTTP协议下的Get请求参数长度是有大小限制的,最大不能超过XX ... [详细]
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • 本文介绍了计算机网络的定义和通信流程,包括客户端编译文件、二进制转换、三层路由设备等。同时,还介绍了计算机网络中常用的关键词,如MAC地址和IP地址。 ... [详细]
  • 本文介绍了通过ABAP开发往外网发邮件的需求,并提供了配置和代码整理的资料。其中包括了配置SAP邮件服务器的步骤和ABAP写发送邮件代码的过程。通过RZ10配置参数和icm/server_port_1的设定,可以实现向Sap User和外部邮件发送邮件的功能。希望对需要的开发人员有帮助。摘要长度:184字。 ... [详细]
  • 分享2款网站程序源码/主题等后门检测工具
    本文介绍了2款用于检测网站程序源码和主题中是否存在后门的工具,分别是WebShellkiller和D盾_Web查杀。WebShellkiller是一款支持webshell和暗链扫描的工具,采用多重检测引擎和智能检测模型,能够更精准地检测出已知和未知的后门文件。D盾_Web查杀则使用自行研发的代码分析引擎,能够分析更为隐藏的WebShell后门行为。 ... [详细]
  • Linux如何安装Mongodb的详细步骤和注意事项
    本文介绍了Linux如何安装Mongodb的详细步骤和注意事项,同时介绍了Mongodb的特点和优势。Mongodb是一个开源的数据库,适用于各种规模的企业和各类应用程序。它具有灵活的数据模式和高性能的数据读写操作,能够提高企业的敏捷性和可扩展性。文章还提供了Mongodb的下载安装包地址。 ... [详细]
  • Java在运行已编译完成的类时,是通过java虚拟机来装载和执行的,java虚拟机通过操作系统命令JAVA_HOMEbinjava–option来启 ... [详细]
  • Oracle优化新常态的五大禁止及其性能隐患
    本文介绍了Oracle优化新常态中的五大禁止措施,包括禁止外键、禁止视图、禁止触发器、禁止存储过程和禁止JOB,并分析了这些禁止措施可能带来的性能隐患。文章还讨论了这些禁止措施在C/S架构和B/S架构中的不同应用情况,并提出了解决方案。 ... [详细]
  • 搭建Windows Server 2012 R2 IIS8.5+PHP(FastCGI)+MySQL环境的详细步骤
    本文详细介绍了搭建Windows Server 2012 R2 IIS8.5+PHP(FastCGI)+MySQL环境的步骤,包括环境说明、相关软件下载的地址以及所需的插件下载地址。 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • 如何用UE4制作2D游戏文档——计算篇
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了如何用UE4制作2D游戏文档——计算篇相关的知识,希望对你有一定的参考价值。 ... [详细]
  • 本文介绍了使用PHP实现断点续传乱序合并文件的方法和源码。由于网络原因,文件需要分割成多个部分发送,因此无法按顺序接收。文章中提供了merge2.php的源码,通过使用shuffle函数打乱文件读取顺序,实现了乱序合并文件的功能。同时,还介绍了filesize、glob、unlink、fopen等相关函数的使用。阅读本文可以了解如何使用PHP实现断点续传乱序合并文件的具体步骤。 ... [详细]
  • 本文介绍了操作系统的定义和功能,包括操作系统的本质、用户界面以及系统调用的分类。同时还介绍了进程和线程的区别,包括进程和线程的定义和作用。 ... [详细]
author-avatar
sylvia
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有