{"id":25098580,"url":"https://github.com/yuntian001/multi-process-queue","last_synced_at":"2025-08-08T18:57:22.058Z","repository":{"id":42373345,"uuid":"359651076","full_name":"yuntian001/multi-process-queue","owner":"yuntian001","description":"基于 swoole 的多进程队列系统，低延时(最低毫秒级)、低资源占用, 支持一键化协程、超时控制、失败重试。可与 laravel thinkphp 等框架配合使用","archived":false,"fork":false,"pushed_at":"2023-03-13T09:26:32.000Z","size":214,"stargazers_count":94,"open_issues_count":0,"forks_count":11,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-04-08T05:05:43.508Z","etag":null,"topics":["laravel","mp-queue","php","queue","swoole","thinkphp","worker"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/yuntian001.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-04-20T01:48:55.000Z","updated_at":"2024-12-17T05:23:25.000Z","dependencies_parsed_at":"2025-02-07T18:47:11.012Z","dependency_job_id":null,"html_url":"https://github.com/yuntian001/multi-process-queue","commit_stats":null,"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yuntian001%2Fmulti-process-queue","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yuntian001%2Fmulti-process-queue/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yuntian001%2Fmulti-process-queue/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yuntian001%2Fmulti-process-queue/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/yuntian001","download_url":"https://codeload.github.com/yuntian001/multi-process-queue/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249699485,"owners_count":21312407,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["laravel","mp-queue","php","queue","swoole","thinkphp","worker"],"created_at":"2025-02-07T18:33:06.811Z","updated_at":"2025-04-19T12:57:15.012Z","avatar_url":"https://github.com/yuntian001.png","language":"PHP","readme":"# multi-process-queue\n\n基于swoole的多进程队列系统，manage进程管理子进程，master进程监听队列分发任务，worker进程执行任务，\n多进程、低延时(最低毫秒级)、低资源占用、高可用、可多服务器分布式部署。可与 laravel thinkphp 等框架配合使用。\n\n版本要求：\n\n - php\u003e=7.1\n - swoole \u003e= 4.4\n\n当前支持的驱动 \n - redis （redis版本需大于3.0.2,redis扩展版本建议\u003e=4.0.0）\n\n### 特性\n - 最低毫秒级任务延时\n - 自定义重试次数和错误回调\n - 自定义超时时间\n - 自定义启动预执行函数，方便初始化其他框架与其他项目配合使用\n - master协程监听队列降低延时\n - 多worker进程消费任务  \n - worker进程支持一键化协程\n - 支持后台守护运行,无需其余进程管理工具\n - 支持多服务器分布式部署\n - 高可用，根据超时时间判断，确保进程挂掉后,回调函数执行成功。\n\n### 进程结构图\n\n![](process_structure.png)\n\n### 配置说明\n\n| 配置项 | 类型 | 是否必填 | 默认值 | 说明 |\n| --- | --- | --- | --- | --- |\n| basics | array | 是 | 无 | 基础配置项 |\n| basics.name | string | 是 | 无 | 当前队列服务名称,多个服务同时启动时需要分别设置名字(名字自定义确保队列服务名字不重复即可) |\n| basics.pid_path | string | 否 | /tmp | 主进程pid文件存放路径 |\n| basics.driver | string | 是 | 无 | 队列驱动必须是MPQueue\\Queue\\Driver\\DriverInterface的实现类 |\n| worker_start_handle | callable | 否 | 空字符串 |worker进程启动后会调用(当前服务所有队列有效) |\n| log | array | 是 | 无 | 日志配置 | \n| log.path | string | 否 | /tmp | 日志存放路径 | \n| log.level | int | 否 | Monolog\\Logger::INFO |日志记录级别 Monolog\\Logger::DEBUG/Monolog\\Logger::INFO |\n| log.dirver | string/class | 否 | RotatingFileLogDriver | 日志驱动，必须是MPQueue\\Log\\Driver\\LogDriverInterface的实现 |\n| queue | 二维数组 | 是 | 无 | 队列配置 |\n|queue[0].name | string | 是 | 无 |队列名称 | \n|queue[0].worker_number | int | 否 | 3 | 工作进程数量 |\n|queue[0].memory_limit | int | 否 | 128 | 工作进程最大使用内存数(单位mb)(0无限制)|\n|queue[0].sleep_seconds | floot | 否 | 1 | 监视进程休眠时间（秒，最小到0.001） |\n|queue[0].timeout | int | 否 | 120 | 超时时间(s)以投递任务方为准 |\n|queue[0].fail_number | int | 否 | 3 | 最大失败次数以投递任务方为准,达到最大次数前(包括次数)失败后会重新投递(即任务最多允许执行fail_number+1次) |\n|queue[0].fail_expire | int | 否 | 3 | 失败延时投递时间(s 支持小数精度到0.001)以投递任务方为准 |\n|queue[0].fail_handle | callable | 否 | 空 | 任务失败执行函数(当任务超时或者达到最大投递次数后会执行) |\n|queue[0].worker_start_handle | callable | 否 | 空 | worker进程启动加载函数（当前队列有效） |\n|queue[0].model | int | 否 | \\MPQueue\\Config\\QueueConfig::MODEl_DISTRIBUTE |队列运行模式（\\MPQueue\\Config\\QueueConfig::MODEl_DISTRIBUTE 分发模式 \\MPQueue\\Config\\QueueConfig::MODEL_GRAB 抢占模式）\n\nfail_handle 会传入两个参数 $jobInfo 任务详细信息、$e出错的异常类\nfail_handle的执行时间也受timeout的控制\n#### 注意：任务超时后会直接记录为失败，不会根据fail_number进行失败重试,可以在fail_handle中根据$jobInfo['type']判断是否是超时任务。\n\n#### 2.0改动\n1. 取消超时回调，超时后记录为失败，触发失败回调。\n2. 由原来的每次失败都触发失败回调改为，超时或超过失败重试次数后才触发。\n3. 增加抢占模式:此模式下worker进程会主动抢任务会增加数据库查询和连接数量（1.0版本的模式为分发模式）\n4. 增加高可用性，超时时间适用于失败回调，如果进程在失败回调执行期间挂掉，其余进程会在超时时间到达后再次执行失败回调。\n5. 优化分发模式性能,按当前空闲进程数一次获取多个任务进行分发，qps大大提高。\n### 下个版本规划\n  - redis集群(Redis Cluster)支持\n\n### 配置示例\n```\n[\n    'basics'=\u003e[\n        'name'=\u003e'mp-queue-1',//多个服务器同时启动时需要分别设置名字\n        'driver'=\u003e new \\MPQueue\\Queue\\Driver\\Redis('127.0.0.1'),\n    ],\n    'queue' =\u003e [\n        [\n            'name' =\u003e 'test',//队列名称\n            'fail_handle'=\u003efunction(){\n                var_dump('失败了');\n            },//失败执行函数\n        ],\n        [\n            'name' =\u003e 'test2',//队列名称\n            'worker_number' =\u003e 4,//当前队列工作进程数量\n            'memory_limit' =\u003e 0, //当前队列工作进程的最大使用内存，超出则重启。单位 MB\n        ]\n    ]\n]\n```\n\n## 快速上手\n ### 1.安装\n - composer 安装\n ```\n  composer require yuntian001/multi-process-queue\n ```\n - 或者直接下载压缩包 然后执行composer install\n ### 2. 启动队列\n - 新建 main.php\n ```\n\u003c?php\ndefine('MP_QUEUE_CLI', true);\nuse MPQueue\\Config\\Config;\nrequire_once __DIR__ . '/vendor/autoload.php';\n$config = [\n    'basics' =\u003e [\n        'name' =\u003e 'mp-queue-1',//多个服务器同时启动时需要分别设置名字\n        'driver' =\u003e new \\MPQueue\\Queue\\Driver\\Redis('127.0.0.1'),\n    ],\n    'queue' =\u003e [\n        [\n            'name' =\u003e 'test',//队列名称\n            'fail_handle' =\u003e function () {\n                var_dump('失败了');\n            },//失败执行函数\n        ],\n        [\n            'name' =\u003e 'test2',//队列名称\n            'worker_number' =\u003e 4,//当前队列工作进程数量\n            'memory_limit' =\u003e 0, //当前队列工作进程的最大使用内存，超出则重启。单位 MB\n        ]\n    ]\n];\nConfig::set($config);\n(new \\MPQueue\\Console\\Application())-\u003erun();\n ```\n - 执行命令 worker:start 启动队列\n ```\n    php master.php worker:start\n ```\n - 或者后台运行\n ```\n   php master.php worker:start -d\n ``` \n - 支持的命令（help命令可查看）\n ```\n  php master.php help\n```\n```\n  queue:clean 清空队列内容 --queue test 清空指定队列:test\n  queue:status 查看队列信息 --queue test 指定队列:test\n  queue:failed 打印失败信息详情 必须指定队列 --queue test 指定队列:test\n  worker:start 启动 携带参数-d 后台启动\n  worker:stop 停止\n  worker:restart 重启 携带参数-d 后台启动\n  worker:reload 平滑重启\n  worker:status 查看进程运行状态\n ```\n ### 3. 投递任务\n  - 执行以下代码投递任务（可web调用，调用进程无需加载swoole扩展）\n```\n    require_once __DIR__ . '/vendor/autoload.php';//require composer 加载文件 如果已加载则无需重复require\n    $config = [\n        'basics' =\u003e [\n            'name' =\u003e 'mp-queue-1',//多个服务器同时启动时需要分别设置名字\n            'driver' =\u003e new \\MPQueue\\Queue\\Driver\\Redis('127.0.0.1'),\n        ],\n        'queue' =\u003e [\n            [\n                'name' =\u003e 'test',//队列名称\n                'fail_handle' =\u003e function () {\n                    var_dump('失败了');\n                },//失败执行函数\n            ],\n            [\n                'name' =\u003e 'test2',//队列名称\n                'worker_number' =\u003e 4,//当前队列工作进程数量\n                'memory_limit' =\u003e 0, //当前队列工作进程的最大使用内存，超出则重启。单位 MB\n            ]\n        ]\n    ];\n     Config::set($config);\n     $job = function(){\n        var_dump('hello wordQ!');\n     }\n     MPQueue\\Queue\\Queue::push('test', $job,10);\n```\nMPQueue\\Queue\\Queue::push 接收三个参数：\n- $queue 队列名称\n- $job   投递的任务\n \n  $job 允许的类型为callable 或 \\MPQueue\\Job的子类 或 \\MPQueue\\Job的子类创建的对象 具体测试可参考test文件夹\n  \n  $job为匿名函数时队列执行进程 和 投递任务进程无需再同一项目下。\n\n  $job为静态方法/\\MPQueue\\Job的实现类/函数时 队列执行进程需要含有对应静态方法/\\MPQueue\\Job的实现类/函数。\n  \n  强烈建议投递$job使用\\MPQueue\\Job子类，子类中可自定义 超时时间、允许失败次数、延时重试时间、超时执行函数、失败执行函数。具体参数说明请进入[src/Job.php](src/Job.php)进行查看\n\n- $delay 延时投递时间(s) 默认为0（立即投递）\n\n任务投递示例，请参考test和test/Job文件夹下的normal.php、failed.php、timeout.php、pressure.php\n## 注意事项\n- worker:reload会让worker进程执行完当前任务后进程重启，worker:restart会暴力重启manage、master、worker进程，可能会造成任务执行一半被断掉。 \n- 因进程是在启动后直接加载到内存中的，更改代码后不会立即生效 需要执行worker:reload 或者 worker:start使其生效。\n- worker:reload 只会重启worker进程，不会重新加载配置文件，更改配置文件后需要worker:restart后才有效。\n\n## 在laravel中使用\n- 安装\n```\n  composer require yuntian001/multi-process-queue\n```\n- 在config文件夹中建立配置文件mp-queue.php\n```\n\u003c?php\n//当前仅为示例，具体配置可按文档自定义\nreturn [\n    'basics'=\u003e[\n        'name'=\u003e'mp-queue-1',//多个服务器同时启动时需要分别设置名字\n        'driver'=\u003e new \\MPQueue\\Queue\\Driver\\Redis('127.0.0.1'),\n        'worker_start_handle'=\u003efunction(){\n            //加载laravel核心程序\n            defined('LARAVEL_START') || define('LARAVEL_START', microtime(true));\n            $app = require_once __DIR__.'/../bootstrap/app.php';\n            $app-\u003emake(Illuminate\\Contracts\\Console\\Kernel::class)-\u003ebootstrap();\n        }\n    ],\n    'queue' =\u003e [\n        [\n            'name' =\u003e 'test',//队列名称\n            'fail_handle'=\u003efunction($info,$e){\n                //自定义逻辑如存储到mysql\n            },//失败执行函数\n        ],\n        [\n            'name' =\u003e 'test2',//队列名称\n            'worker_number' =\u003e 4,//当前队列工作进程数量\n            'memory_limit' =\u003e 0, //当前队列工作进程的最大使用内存，超出则重启。单位 MB\n        ]\n    ],\n    'log' =\u003e [\n        'path' =\u003e __DIR__.'/../storage/logs',//日志存放目录需要可写权限\n    ]\n];\n\n```\n - 在项目根目录建立启动文件 mp-queue\n```\n#!/usr/bin/env php\n\u003c?php\ndefine('MP_QUEUE_CLI', true);\nuse MPQueue\\Config\\Config;\n\nrequire __DIR__.'/vendor/autoload.php';\nConfig::set(include(__DIR__.'/config/mp-queue.php'));\n(new \\MPQueue\\Console\\Application())-\u003erun();\n```\n - 创建job类 App\\Job\\HelloWord\n```\n\u003c?php\n//位置位于app/Job/HelloWord.php\nnamespace App\\Job;\n\nuse Illuminate\\Support\\Facades\\Log;\nuse MPQueue\\Job;\n\nClass HelloWord extends Job{\n    //handle内可调用laravel方法和函数，但handle函数不支持依赖注入传参\n    public function handle()\n    {\n        var_dump('hello word!');\n        Log::info('hello word!');\n    }\n}\n\n```\n - 后台启动队列(或不加-d直接启动)\n```\n php mp-queue worker:start -d\n```\n\n  - 投递任务 在任意位置(如控制器)加入以下代码进行投递\n```\n    \\MPQueue\\Config\\Config::set(config('mp-queue'));//配置项设置也可放在app容器中AppServiceProvider boot() 统一加载\n    \\MPQueue\\Queue\\Queue::push('test',\\App\\Job\\HelloWord::class);\n```\n## 在thinkphp5.0中使用\n- 安装\n```\n  composer require yuntian001/multi-process-queue\n```\n- 在application/extra文件夹中建立配置文件mp-queue.php\n```\n\u003c?php\n//当前仅为示例，具体配置可按文档自定义\nreturn [\n    'basics'=\u003e[\n        'name'=\u003e'mp-queue-1',//多个服务器同时启动时需要分别设置名字\n        'driver'=\u003e new \\MPQueue\\Queue\\Driver\\Redis('127.0.0.1'),\n        'worker_start_handle'=\u003efunction(){\n            //加载thinkphp核心应用\n            \\think\\App::initCommon();\n        }\n    ],\n    'queue' =\u003e [\n        [\n            'name' =\u003e 'test',//队列名称\n            'fail_handle'=\u003efunction($info,$e){\n                //自定义逻辑如存储到mysql\n            },//失败执行函数\n        ],\n        [\n            'name' =\u003e 'test2',//队列名称\n            'worker_number' =\u003e 4,//当前队列工作进程数量\n            'memory_limit' =\u003e 0, //当前队列工作进程的最大使用内存，超出则重启。单位 MB\n        ]\n    ],\n    'log' =\u003e [\n        'path' =\u003e __DIR__.'/../../runtime',//日志存放目录需要可写权限\n    ]\n];\n\n```\n - 在项目根目录建立启动文件mp-queue\n```\n#!/usr/bin/env php\n\u003c?php\ndefine('MP_QUEUE_CLI', true);\ndefine('APP_PATH', __DIR__ . '/application/');\n// ThinkPHP 基础文件\nrequire __DIR__ . '/thinkphp/base.php';\n\\MPQueue\\Config\\Config::set(include(__DIR__.'/application/extra/mp-queue.php'));\n(new \\MPQueue\\Console\\Application())-\u003erun();\n```\n- 创建job类 app\\job\\HelloWord\n```\n\u003c?php\n//application/job/HelloWord.php\nnamespace app\\job;\nuse MPQueue\\Job;\nuse think\\Log;\n\nClass HelloWord extends Job{\n    //handle内可调用thinkphp方法和函数，但handle函数不支持依赖注入传参\n    public function handle()\n    {\n        var_dump('hello word!');\n        Log::info('hello word!');\n    }\n}\n```\n- 后台启动队列(或不加-d直接启动)\n```\n php mp-queue worker:start -d\n```\n- 投递任务 在任意位置(如控制器)加入以下代码进行投递\n```\n    \\MPQueue\\Config\\Config::set(config('mp-queue'));//配置项设置也可注册在初始化化行为(app_init)中 统一加载\n    \\MPQueue\\Queue\\Queue::push('test',\\app\\job\\HelloWord::class);\n```\n\n## 在thinkphp6.0中使用\n- 安装\n```\n  composer require yuntian001/multi-process-queue\n```\n- 在config文件夹中建立配置文件mp-queue.php\n```\n\u003c?php\n//当前仅为示例，具体配置可按文档自定义\nreturn [\n    'basics'=\u003e[\n        'name'=\u003e'mp-queue-1',//多个服务器同时启动时需要分别设置名字\n        'driver'=\u003e new \\MPQueue\\Queue\\Driver\\Redis('127.0.0.1'),\n        'worker_start_handle'=\u003efunction(){\n            //加载thinkphp核心应用\n            (new \\think\\App())-\u003einitialize();\n        }\n    ],\n    'queue' =\u003e [\n        [\n            'name' =\u003e 'test',//队列名称\n            'fail_handle'=\u003efunction($info,$e){\n                //自定义逻辑如存储到mysql\n            },//失败执行函数\n        ],\n        [\n            'name' =\u003e 'test2',//队列名称\n            'worker_number' =\u003e 4,//当前队列工作进程数量\n            'memory_limit' =\u003e 0, //当前队列工作进程的最大使用内存，超出则重启。单位 MB\n        ]\n    ],\n    'log' =\u003e [\n        'path' =\u003e __DIR__.'/../runtime',//日志存放目录需要可写权限\n    ]\n];\n```\n - 在项目根目录建立启动文件mp-queue\n```\n#!/usr/bin/env php\n\u003c?php\ndefine('MP_QUEUE_CLI', true);\nrequire __DIR__ . '/vendor/autoload.php';\n// 加载基础文件\n\\MPQueue\\Config\\Config::set(include(__DIR__.'/config/mp-queue.php'));\n(new \\MPQueue\\Console\\Application())-\u003erun();\n```\n- 创建job类 app\\job\\HelloWord.php\n```\n\u003c?php\n//app/job/HelloWord.php\nnamespace app\\job;\nuse MPQueue\\Job;\nuse think\\facade\\Log;\n\nClass HelloWord extends Job{\n    //handle内可调用thinkphp方法和函数，但handle函数不支持依赖注入传参\n    public function handle()\n    {\n        var_dump('hello word!'.app_path());\n        Log::info('hello word!'.app_path());\n        Log::info(config('database'));\n    }\n}\n```\n- 后台启动队列(或不加-d直接启动)\n```\n php mp-queue worker:start -d\n```\n- 投递任务 在任意位置(如控制器)加入以下代码进行投递\n```\n    \\MPQueue\\Config\\Config::set(config('mp-queue'));//配置项设置也可注册在初始化文件中统一加载\n    \\MPQueue\\Queue\\Queue::push('test',\\app\\job\\HelloWord::class);\n```\n\n## 项目推荐\n在这里推荐下，我自己开源的vue中后台模版项目（vue3+vite3+element-plus），如果想搭建后台可以使用下\n\ngithub地址： [https://github.com/meadmin-cn/meadmin-template](https://github.com/meadmin-cn/meadmin-template)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyuntian001%2Fmulti-process-queue","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyuntian001%2Fmulti-process-queue","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyuntian001%2Fmulti-process-queue/lists"}