Laravel+workman+redis实现多线程异步任务处理

前言


PHP本身并不直接支持多线程编程,因为PHP的设计初衷是作为一个脚本语言,主要面向的是Web开发。不过我们可以使用一些扩展和库来实现多线程的功能,比如workerman和swoole。通过多线程异步执行任务,可以大大提高代码的执行效率。

安装workman


  • 简介

    官网:高性能PHP应用容器 workerman

    文档:

    workerman 手册

  • 环境要求

    • PHP >= 7.2
    • Composer >= 2.0
    • Linux系统
  • 安装扩展

    composer require workerman/gateway-worker
    

Laravel中使用workman创建多线程任务


  • 1.创建 artisan命令

    目录下建立命令行文件WorkermanCommand

    php artisan make:command WorkermanCommand
    

    文件内容如下

    protected $signature = 'workman {action} {--d}';protected $description = 'Start a Workerman server.';public function handle(){global $argv;$action = $this->argument('action');$argv[0] = 'wk';$argv[1] = $action;$argv[2] = $this->option('d') ? '-d' : '';$this->start();}private function start(){$this->startGateWay();$this->startBusinessWorker();$this->startRegister();Worker::runAll();}private function startBusinessWorker(){$worker                  = new BusinessWorker();$worker->name            = 'BusinessWorker';$worker->count           = 1;$worker->registerAddress = '127.0.0.1:1236';$worker->eventHandler    = \App\Workerman\Events::class; //指定workman监听事件文件}private function startGateWay(){$gateway = new Gateway("websocket://0.0.0.0:2346");$gateway->name                 = 'Gateway';$gateway->count                = 1;$gateway->lanIp                = '127.0.0.1';$gateway->startPort            = 2300;$gateway->pingInterval         = 30;$gateway->pingNotResponseLimit = 0;$gateway->pingData             = '{"type":"@heart@"}';$gateway->registerAddress      = '127.0.0.1:1236';}private function startRegister(){new Register('text://0.0.0.0:1236');}
    
  • 2.创建监听事件

    创建app/Workerman/Events.php文件来监听处理Workman的各种事件

    <?phpnamespace App\Workerman;class Events
    {public static function onWorkerStart($worker){echo 'workman进程启动,进程id ' . $worker->id . PHP_EOL;//监听redis队列$redis = app('redis.connection');while (true) {//读取redis队列$data = $redis->lPop('test-queue');if ($data) {//处理业务echo '进程id ' . $worker->id . ' 开始处理业务数据' . $data . PHP_EOL;//模拟耗时任务sleep(5);echo '进程id ' . $worker->id . ' 处理业务数据' . $data . ' 完成' . PHP_EOL;} else {echo '进程id ' . $worker->id . ' 空闲中,休息5秒' . PHP_EOL;sleep(5);}}}public static function onConnect($client_id){}public static function onWebSocketConnect($client_id, $data){}public static function onMessage($client_id, $message){}public static function onClose($client_id){}
    }
    
  • 3.启动workman

    php artisan workman start -d
    

    看到下面的信息说明启动成功

    root@2e870aece68b:/var/www/hello# php artisan workman start
    Workerman[wk] start in DEBUG mode
    -------------------------------------------- WORKERMAN ---------------------------------------------
    Workerman version:4.1.15          PHP version:7.4.33           Event-Loop:\Workerman\Events\Select
    --------------------------------------------- WORKERS ----------------------------------------------
    proto   user            worker            listen                      processes    status
    tcp     root            Gateway           websocket://0.0.0.0:2346    4             [OK]
    tcp     root            BusinessWorker    none                        4             [OK]
    tcp     root            Register          text://0.0.0.0:1236         1             [OK]
    ----------------------------------------------------------------------------------------------------
    
  • 4.在laravel框架中新增api接口将任务加入redis队列,例如我这里写一个添加redis列表元素的方法

    <?phpnamespace App\Http\Controllers;class IndexController extends Controller
    {//新增队列数据public function addQueue(){$redis = app('redis.connection');$redis->rPush('test-queue', '1');$redis->rPush('test-queue', '2');$redis->rPush('test-queue', '3');$redis->rPush('test-queue', '4');$redis->rPush('test-queue', '5');$redis->rPush('test-queue', '6');$redis->rPush('test-queue', '7');echo 'success';}
    }
    

    加完方法后记得新增路由

  • 5.访问上面的将任务加入redis队列接口,直接用浏览器或者命令行curl访问http://网站域名/api/index/addQueue即可,然后你就可以看到所有的redis队列将被workman线程分配并执行,以下是我启动workman->添加redis队列->workman处理->队列处理结束打印的结果:

    root@2e870aece68b:/var/www/hello# php artisan workman start
    Workerman[wk] start in DEBUG mode
    -------------------------------------------- WORKERMAN ---------------------------------------------
    Workerman version:4.1.15          PHP version:7.4.33           Event-Loop:\Workerman\Events\Select
    --------------------------------------------- WORKERS ----------------------------------------------
    proto   user            worker            listen                      processes    status
    tcp     root            Gateway           websocket://0.0.0.0:2346    4             [OK]
    tcp     root            BusinessWorker    none                        4             [OK]
    tcp     root            Register          text://0.0.0.0:1236         1             [OK]
    ----------------------------------------------------------------------------------------------------
    Press Ctrl+C to stop. Start success.
    workman进程启动,进程id 2
    workman进程启动,进程id 0
    workman进程启动,进程id 1
    进程id 0 空闲中,休息5秒
    workman进程启动,进程id 3
    进程id 2 空闲中,休息5秒
    进程id 1 空闲中,休息5秒
    进程id 3 空闲中,休息5秒
    进程id 0 开始处理业务数据1
    进程id 2 开始处理业务数据3
    进程id 3 开始处理业务数据4
    进程id 1 开始处理业务数据2
    进程id 0 处理业务数据1 完成
    进程id 0 开始处理业务数据5
    进程id 3 处理业务数据4 完成
    进程id 2 处理业务数据3 完成
    进程id 1 处理业务数据2 完成
    进程id 3 开始处理业务数据6
    进程id 2 开始处理业务数据7
    进程id 1 空闲中,休息5秒
    进程id 0 处理业务数据5 完成
    进程id 0 空闲中,休息5秒
    进程id 3 处理业务数据6 完成
    进程id 2 处理业务数据7 完成
    进程id 2 空闲中,休息5秒
    进程id 3 空闲中,休息5秒
    进程id 1 空闲中,休息5秒
    

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/754629.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java 学习和实践笔记(40):String类详解

示例代码&#xff1a; public class TestString {public static void main(String[] args) {String s0 null;//这是什么都没有&#xff0c;连对象都没有&#xff0c;也就是指针还没有指到某一个地址String s1 "";//这是有对象了&#xff08;指针已指向某一个地址了…

ocp考试通过率如何?ocp考试内容有哪些?

OCP考试通过率如何 通过率30%左右。考试笔试和上机都考。OCP认证想考好&#xff0c;自己必须有点能力撒&#xff0c;不要想着通过率怎么样&#xff0c;学的不怎么好&#xff0c;你学了那个不通过的就是你&#xff0c;这方面还是要看下自己的动力&#xff0c;每天不怎么学习&…

如何使用 ArcGIS Pro 生成TIN

三角网是一种常用于表示地表地形的数字地球模型&#xff08;DEM&#xff09;方式&#xff0c;我们可以通过 ArcGIS Pro 将等高线和高程点转换为TIN&#xff0c;这里为大家介绍一下转换方法&#xff0c;希望能对你有所帮助。 数据来源 教程所使用的数据是从水经微图中下载的高…

Java | 集合中正确使用Stream流

大家好&#xff0c;我是程序员影子 一名致力于帮助更多朋友快速入门编程的程序猿 今天来聊一聊关于Java 中的集合中正确使用Stream流 一、Stream的创建 Java 8 引入了Stream API&#xff0c;它可以让你以一种声明的方式处理数据。Stream可以由集合创建&#xff0c;使用stre…

智能合约 - 部署ERC20

Remix介绍 Remix是一个由以太坊社区开发的在线集成开发环境&#xff08;IDE&#xff09;&#xff0c;旨在帮助开发者编写、测试和部署以太坊智能合约。它提供了一个简单易用的界面&#xff0c;使得开发者可以在浏览器中直接进行智能合约的开发&#xff0c;而无需安装任何额外的…

springboot整合springsecurity,从数据库中认证

概述&#xff1a;springsecurity这个东西太容易忘了&#xff0c;这里写点东西&#xff0c;避免忘掉 目录 第一步&#xff1a;引入依赖 第二步&#xff1a;创建user表 第三步&#xff1a;创建一个用户实体类&#xff08;User&#xff09;和一个用于访问用户数据的Repository…

第十四届蓝桥杯省赛C++B组题解

考点 暴力枚举&#xff0c;搜索&#xff0c;数学&#xff0c;二分&#xff0c;前缀和&#xff0c;简单DP&#xff0c;优先队列&#xff0c;链表&#xff0c;LCA&#xff0c;树上差分 A 日期统计 暴力枚举&#xff1a; #include<bits/stdc.h> using namespace std; int …

Transformer的前世今生 day01(预训练、统计语言模型)

预训练 在相似任务中&#xff0c;由于神经网络模型的浅层是通用的&#xff0c;如下图&#xff1a; 所以当我们的数据集不够大&#xff0c;不能产生性能良好的模型时&#xff0c;可以尝试让模型B在用模型A的浅层基础上&#xff0c;深层的部分自己生成参数&#xff0c;减小数据集…

RabbitMQ的幂等性、优先级队列和惰性队列

文章目录 前言一、幂等性1、概念2、消息重复消费3、解决思路4、消费端的幂等性保障5、唯一 ID指纹码机制6、Redis 原子性 二、优先级队列1、使用场景2、如何添加3、实战 三、惰性队列1、使用场景2、两种模式3、内存开销对比 总结 前言 一、幂等性 1、概念 2、消息重复消费 3、…

【uniapp】表单验证不生效的解决方案

表单验证这个常见的功能&#xff0c;明明在element ui等框架已经用的很熟了&#xff0c;在uniapp开发时还是处处碰壁&#xff1f;这篇文章我会提示uni-forms表单验证的几个注意点&#xff0c;帮助大家排查。 示例 下面是一份包含普通验证和自定义验证的示例&#xff1a; <…

通过Pytest 多数据库连接实例了解Python工厂模式与单例模式的区别

1. 前言 在做自动化测试时&#xff0c;有些特殊项目需要连接不同的数据库进行造数或者断言。自动化框架中&#xff0c;一般使用Pytest yaml 数据驱动的居多&#xff0c;如果一个项目中有上百条数据库相关测试用例&#xff0c;在数据库测试时&#xff0c;如果设计不合理的连接模…

【大模型】直接在VS Code(Visual Studio Code)上安装CodeGeeX插件的过程

文章目录 一、什么是CodeGeeX&#xff08;一&#xff09;我理解的CodeGeeX&#xff08;二&#xff09;优缺点 二、CodeGeex下载、安装、注册&#xff08;一&#xff09;安装VS Code(Visual Studio Code)&#xff08;二&#xff09;下载安装CodeGeeX&#xff08;三&#xff09;注…

Java项目:59 ssm小型企业办公自动化系统的设计和开发+vue

作者主页&#xff1a;源码空间codegym 简介&#xff1a;Java领域优质创作者、Java项目、学习资料、技术互助 文中获取源码 项目介绍 系统可以提供信息显示和相应服务&#xff0c; 其管理员管理部门经理&#xff0c;管理总经理&#xff0c;管理员工和员工留言以及员工工资&…

[经验分享]OpenCV显示上一次调用的图片的处理方法

最近在研究OpenCV时发现&#xff0c;重复调用cv::imshow("frame", frame)时&#xff0c;会显示出上一次的图片。 网上搜索了方法&#xff0c;有以下3种因素可能导致&#xff1a; 1. 图像变量未正确更新&#xff1a;可能在更新 frame 变量之前就已经调用了 imshow。…

Stream流将List列表中的每个对象赋值给另外一个List列表中的每个对象

源代码&#xff1a; public void repetition(Long id) {// 查询当前用户idLong userId BaseContext.getCurrentId();// 根据订单id查询当前订单详情List<OrderDetail> orderDetailList orderDetailMapper.getByOrderId(id);// 将订单详情对象转换为购物车对象List<…

搭建 es 集群

一、VMware准备机器 首先准备三台机器 这里我直接使用 VMware 构建三个虚拟机 都是基于 CentOS7 然后创建新用户 部署 es 需要单独创建一个用户&#xff0c;我这里在构建虚拟机的时候直接创建好了 然后将安装包上传 可以使用 rz 命令上传&#xff0c;也可以使用工具上传 工…

RK3588_Qt交叉编译环境搭建

buildroot编译 进入 /home/linux/plat/rk3588/sdk/buildroot 目录下&#xff0c;执行 Source ./envsetup.sh 选择具体平台编译&#xff0c;后再执行make编译 /home/linux/plat/rk3588/sdk/buildroot/output/OK3568/images 生成的rootfs.ext2镜像重新烧写到rk3568开发板中&…

PHP姓名快速匿名化工具(重组脱敏)

PHP姓名重组工具(脱敏/匿名化工具) 将excel数据姓名列粘贴提交&#xff0c;得到随机姓随机中间字随机尾字的重组姓名 那些年自用瞎搞的代码&#xff0c;今日整理成网页交提交得到结果的交互功能分享。 <?php //PHP姓名重组工具(脱敏/匿名化工具) //将excel数据姓名列粘贴…

elk收集k8s微服务日志

一、前言 使用filebeat自动发现收集k8s的pod日志&#xff0c;这里分别收集前端的nginx日志&#xff0c;还有后端的服务java日志&#xff0c;所有格式都是用json格式&#xff0c;建议还是需要让开发人员去输出java的日志为json&#xff0c;logstash分割java日志为json格式&#…

C#、ASP、ASP.NET、.NET、ASP.NET CORE区别、ASP.NET Core其概念和特点、ASP.NET Core个人心得体会

C#是一种面向对象的编程语言&#xff0c;主要用于开发跨平台的应用程序。它是.NET框架的一部分&#xff0c;并且可以在.NET平台上运行。 ASP&#xff08;Active Server Pages&#xff09;是一种用于构建动态Web页面的技术&#xff0c;使用VBScript或JScript作为服务器端脚本语…