{"id":18345822,"url":"https://github.com/hyperf/xxl-job-incubator","last_synced_at":"2025-04-06T08:32:17.613Z","repository":{"id":41855889,"uuid":"401974757","full_name":"hyperf/xxl-job-incubator","owner":"hyperf","description":null,"archived":false,"fork":false,"pushed_at":"2024-06-04T09:44:39.000Z","size":183,"stargazers_count":38,"open_issues_count":6,"forks_count":7,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-08-08T21:10:10.353Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/hyperf.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},"funding":{"open_collective":"hyperf","custom":"https://hyperf.wiki/#/zh-cn/donate"}},"created_at":"2021-09-01T07:42:28.000Z","updated_at":"2024-02-20T09:18:28.000Z","dependencies_parsed_at":"2023-12-01T03:22:14.804Z","dependency_job_id":"5150ac3b-2375-4fbb-a982-0953b82c9623","html_url":"https://github.com/hyperf/xxl-job-incubator","commit_stats":null,"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hyperf%2Fxxl-job-incubator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hyperf%2Fxxl-job-incubator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hyperf%2Fxxl-job-incubator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hyperf%2Fxxl-job-incubator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hyperf","download_url":"https://codeload.github.com/hyperf/xxl-job-incubator/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223245061,"owners_count":17112572,"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":[],"created_at":"2024-11-05T21:09:35.565Z","updated_at":"2025-04-06T08:32:17.574Z","avatar_url":"https://github.com/hyperf.png","language":"PHP","funding_links":["https://opencollective.com/hyperf","https://hyperf.wiki/#/zh-cn/donate"],"categories":[],"sub_categories":[],"readme":"# xxl-job-incubator\n\n此为 xxl-job 的 PHP 版本的任务执行器(Job Executor)，特别适配于 Hyperf 框架，其余框架尚未验证适配性\n\n### 优点\n\n- 分布式任务调度平台\n- 任务可以随时关闭与开启\n- 日志可通过服务端查看\n\n\n## 使用须知\n\n\u003e 1. xxl-job 服务端版本需 \u003e= 2.2.0\n\u003e 2. 阻塞处理策略:单机串行(未实现)，任务默认并行执行; 对于长时间的任务，建议使用`丢弃后续调度`\n\n## 安装\n\n```\ncomposer require hyperf/xxl-job-incubator\n```\n\n## 使用\n\n### 配置\n\n配置文件: `config/autoload/xxl_job.php`\n\n```php\nreturn [\n    // 是否启用\n    'enable' =\u003e env('XXL_JOB_ENABLE', true),\n    // XXL-JOB 服务端地址\n    'admin_address' =\u003e env('XXL_JOB_ADMIN_ADDRESS', 'http://127.0.0.1:8080/xxl-job-admin'),\n    // 对应的 AppName\n    'app_name' =\u003e env('XXL_JOB_APP_NAME', 'xxl-job-demo'),\n    // 访问凭证\n    'access_token' =\u003e env('XXL_JOB_ACCESS_TOKEN', ''),\n    // 执行器心跳间隔（秒）\n    'heartbeat' =\u003e env('XXL_JOB_HEARTBEAT', 30),\n    // 日志文件保存天数 [选填]: 过期日志自动清理, 限制值大于等于3时生效; 否则, 如-1, 关闭自动清理功能；\n    'log_retention_days' =\u003e -1,\n    // 执行器 HTTP Server 相关配置\n    'executor_server' =\u003e [\n        // HTTP Server 路由前缀\n        'prefix_url' =\u003e env('XXL_JOB_PREFIX_URL', 'php-xxl-job'),\n    ],\n];\n```\n\n如文件不存在可通过以下命令发布配置文件\n\n```bash\nphp bin/hyperf.php vendor:publish hyperf/xxl-job-incubator\n```\n\n### Bean 模式(类形式)\n\nBean 模式任务，支持基于类的开发方式，每个任务对应一个 PHP 类\n\n优点：与 Hyperf 整合性好，易于管理 \n缺点：任务运行于单独的，协程任务代码不能存在阻塞 IO，每个 Job 需占用一个类文件，Job 逻辑简单但数量过多时过于累赘\n\u003e swoole默认使用命令行模式执行，swow默认使用协程模式执行\n\u003e 如需要手动指定模式，执行器名称后缀为process(忽略大小写)，使用命令行模式执行;后缀为coroutine(忽略大小写)，使用协程执行\n\u003e swoole使用协程模式，无法使用:`关闭终止任务`|`以及阻塞处理策略`|`任务超时`\n\n#### 编写 Job 类\n\n编写一个实现 `Hyperf\\XxlJob\\Handler\\JobHandlerInterface` 的 Job 类，并为 Job 类添加注解 `#[XxlJob('value')]`，注解的 value 值对应的是调度中心新建任务的 JobHandler 属性的值，如下所示：\n\n\u003e Tips: 可直接继承 `Hyperf\\XxlJob\\Handler\\AbstractJobHandler` 得到对应的实现\n\n```php\nnamespace App\\Job;\n\nuse Hyperf\\Di\\Annotation\\Inject;\nuse Hyperf\\XxlJob\\Annotation\\XxlJob;\nuse Hyperf\\XxlJob\\Handler\\AbstractJobHandler;\nuse Hyperf\\XxlJob\\Logger\\JobExecutorLoggerInterface;\nuse Hyperf\\XxlJob\\Requests\\RunRequest;\n\n#[XxlJob(\"demoJobClassHandler\")]\nclass DemoJobClass extends AbstractJobHandler\n{\n\n    #[Inject]\n    protected JobExecutorLoggerInterface $jobExecutorLogger;\n\n    /**\n     * 执行任务\n     */\n    public function execute(RunRequest $request): void\n    {\n        // 获取参数\n        $params = $request-\u003egetExecutorParams();\n        // 获取 LogId\n        $logId = $request-\u003egetLogId();\n        $this-\u003ejobExecutorLogger-\u003einfo('demoJobClassHandler...');\n        $this-\u003ejobExecutorLogger-\u003einfo('params:' . $params);\n        for ($i = 1; $i \u003c 5; ++$i) {\n            sleep(2);\n            $this-\u003ejobExecutorLogger-\u003einfo($i);\n            $this-\u003ejobExecutorLogger-\u003einfo('logId:' . $logId);\n            $this-\u003ejobExecutorLogger-\u003einfo('params:' . $params);\n        }\n    }\n}\n```\n\n#### 在调度中心新建调度任务\n\n对新建的任务进行参数配置，运行模式选中 `BEAN模式`，JobHandler 属性填写注解 `#[XxlJob]`中定义 value 值\n![hMvJnQ](https://www.xuxueli.com/doc/static/xxl-job/images/img_ZAsz.png)\n\n### Bean 模式(方法形式)\n\n基于方法的开发方式，每个任务对应一个方法\n\n优点：相对比 `Bean(类形式)` 更加灵活   \n缺点：数量多时更难管理，代码复杂度高时多个任务间容易造成耦合度过高\n\n#### 编写 Job 方法\n\n对任意类中的 Public 方法增加 `#[XxlJob('value')]` 注解，注解的 value 值对应的是调度中心新建任务的 JobHandler 属性的值\n\n```php\nuse Hyperf\\XxlJob\\Annotation\\XxlJob;\n\nclass Foo {\n\n    #[XxlJob('demoJobHandler')]\n    public function demoJobHandler(){}\n\n}\n```\n\n#### 在调度中心新建调度任务\n\n对新建的任务进行参数配置，运行模式选中 `BEAN模式`，JobHandler 属性填写注解 `#[XxlJob]`中定义 value 值\n![hMvJnQ](https://www.xuxueli.com/doc/static/xxl-job/images/img_ZAsz.png)\n\n#### 使用案例\n\n```php\nnamespace App\\Job;\n\nuse Hyperf\\Di\\Annotation\\Inject;\nuse Hyperf\\XxlJob\\Annotation\\XxlJob;\nuse Hyperf\\XxlJob\\Logger\\JobExecutorLoggerInterface;\nuse Hyperf\\XxlJob\\Requests\\RunRequest;\n\nclass DemoJob\n{\n    \n    #[Inject]\n    protected JobExecutorLoggerInterface $jobExecutorLogger;\n    \n    /**\n     * 1.任务示例.\n     */\n    #[XxlJob('demoJobHandler')]\n    public function demoJobHandler(RunRequest $request)\n    {\n        //获取参数\n        $params = $request-\u003egetExecutorParams();\n        //获取logId\n        $logId = $request-\u003egetLogId();\n        $this-\u003ejobExecutorLogger-\u003einfo('params:' . $params);\n        for ($i = 1; $i \u003c 5; ++$i) {\n            sleep(2);\n            $this-\u003ejobExecutorLogger-\u003einfo($i);\n            $this-\u003ejobExecutorLogger-\u003einfo('logId:' . $logId);\n            $this-\u003ejobExecutorLogger-\u003einfo('params:' . $params);\n        }\n    }\n\n    /**\n     * 2、分片广播任务\n     */\n    #[XxlJob('shardingJobHandler')]\n    public function shardingJobHandler(RunRequest $request)\n    {\n        // 分片参数\n        $shardIndex = $request-\u003egetBroadcastIndex();\n        $shardTotal = $request-\u003egetBroadcastTotal();\n        $this-\u003ejobExecutorLogger-\u003einfo(sprintf('分片参数：当前分片序号 = %d, 总分片数 = %d', $shardIndex, $shardTotal));\n        // 业务逻辑\n        for ($i = 0; $i \u003c $shardTotal; ++$i) {\n            if ($i == $shardIndex) {\n                $this-\u003ejobExecutorLogger-\u003einfo('第 %d 片, 命中分片开始处理', $i);\n            } else {\n                $this-\u003ejobExecutorLogger-\u003einfo('第 %d 片, 忽略', $i);\n            }\n        }\n    }\n\n    /**\n     * 3、执行命令.\n     */\n    #[XxlJob('commandJobHandler')]\n    public function commandJobHandler(RunRequest $request)\n    {\n        //获取参数\n        //例子:php -v\n        $command = $request-\u003egetExecutorParams();\n        var_dump($command);\n        $result = System::exec($command);\n        $message = str_replace(\"\\n\", '\u003cbr\u003e', $result['output']);\n        $this-\u003ejobExecutorLogger-\u003einfo($message);\n    }\n\n    /**\n     * 4、param任务\n     *  参数示例：\n     *      \"url: http://www.baidu.com\\n\" +\n     *      \"method: get\".\n     */\n    #[XxlJob('paramJobHandler')]\n    public function paramJobHandler(RunRequest $request)\n    {\n        $param = $request-\u003egetExecutorParams();\n        $array = explode(PHP_EOL, $param);\n        /** array(2) {\n              [0]=\u003e\n              string(25) \"url: http://www.baidu.com\"\n              [1]=\u003e\n              string(11) \"method: get\"\n            }\n         */\n        var_dump($param, $array);\n    }\n\n    /**\n     * 5、任务示例：任务初始化与销毁时，支持自定义相关逻辑.\n     */\n    #[XxlJob(value: 'demoJob', init: 'initMethod', destroy: 'destroyMethod')]\n    public function demoJob()\n    {\n        $this-\u003ejobExecutorLogger-\u003einfo('demoJob run...');\n    }\n\n    public function initMethod()\n    {\n        $this-\u003ejobExecutorLogger-\u003einfo('initMethod');\n    }\n\n    public function destroyMethod()\n    {\n        $this-\u003ejobExecutorLogger-\u003einfo('destroyMethod');\n    }\n}\n```\n\n### Glue 脚本模式\n\n该模式下，可支持任务以将源码方式维护在调度中心，支持通过 XXL-JOB 提供的 Web IDE 在线编写代码和在线更新，因此不需要指定固定的 `JobHandler`   \n脚本模式支持多种脚本语言编写 Job 代码，包括 PHP、Python、NodeJs、Shell、PowerShell，在 XXL-JOB 新建任务时选择对应的模式即可，例如 `GLUE(PHP)` 即代表 PHP 语言的脚本模式，所有脚本模式的任务会以一个独立的进程来运行，故在 PHP 下也可支持编写存在 IO 阻塞的代码\n\n\u003e 要使用 `Glue 脚本模式` 必须配置 Access Token 方可启用\n\n优点：极度灵活，可以实现不重启新增和修改 Job 代码，支持多种脚本语言，独立进程   \n缺点：大批量任务时容易造成进程数过多，脚本代码由 XXL-JOB 远程编辑发放容易导致安全问题，Job 代码可对 Executor 所在服务器环境进行与启动 Hyperf 应用的权限相同的操作\n\n\n### 安装xxl-job-admin(3.0.0版本)\n#### 初始化“调度数据库”\n[初始化SQL脚本](https://github.com/xuxueli/xxl-job/blob/3.0.0/doc/db/tables_xxl_job.sql)\n#### docker安装\n```bash\ndocker run -d \\\n-e PARAMS=\"--spring.datasource.url=jdbc:mysql://127.0.0.1:3306/xxl_job?Unicode=true\u0026characterEncoding=UTF-8\u0026autoReconnect=true\u0026serverTimezone=Asia/Shanghai\n--spring.datasource.username=root\n--spring.datasource.password=123456\n--xxl.job.accessToken=123456\" \\\n-p 8080:8080 --name xxl-job --restart=always xuxueli/xxl-job-admin:3.0.0\n```\n\u003e 替换:数据库地址/账号/密码和accessToken\n\n### 引用\n\n关于 XXL-JOB 更多的使用细节可参考 [XXL-JOB 官方文档](https://www.xuxueli.com/xxl-job/#%E3%80%8A%E5%88%86%E5%B8%83%E5%BC%8F%E4%BB%BB%E5%8A%A1%E8%B0%83%E5%BA%A6%E5%B9%B3%E5%8F%B0XXL-JOB%E3%80%8B)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhyperf%2Fxxl-job-incubator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhyperf%2Fxxl-job-incubator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhyperf%2Fxxl-job-incubator/lists"}