webman,如何动态设置定时任务

evilk

需求:
根据用户的设置,比如每天凌晨3点,执行一个定时任务
这个定时任务,执行的时间,是根据用户的设置来的\

最关键的问题是,这个设置可能会经常变化
可能今天用户设置为每天凌晨3点执行
可能明天用户设置为每天凌晨7点执行

这种情况,有没有可行的思路或者方案呢?

3745 9 0
9个回答

nitron

设置一个定时任务每分钟跑一遍用来执行设置用户的定时任务

  • Tinywan 2022-03-31

    这个有什么好的方案吗?想写个插件

  • nitron 2022-03-31

    其实crontab如果不是那种要求精确到秒执行的,我更倾向走命令行,思路大概就是两种:

    1.一个MainCronTask在命令行下1分钟运行一次,逻辑就是检测是否有刚好这个时间需要执行的计划任务SubCronTask,有则执行
    2.还是MainCronTask在命令行下1分钟运行一次,逻辑就是执行所有的计划任务SubCronTask,至于实际是否执行,有具体计划任务自身判断

    但是要注意处理前一个计划任务执行时间过长,导致前一个计划任务(不管是Main还是Sub)没有执行完,又到了下一个执行时间的问题

  • Tinywan 2022-03-31

    看了一下,不好写

  • nitron 2022-03-31

    独立跑命令行,可以规避掉因为WM挂掉而导致无法执行计划任务的问题

  • Tinywan 2022-03-31

    意外情况太多了

yzh52521

放数据库
扫描数据库里的任务来执行

  • 暂无评论
li914

做一个专门单个定时任务进程,当有定时任务时,推送到定时任务进程上,然后在定时任务进程上 启动 定时任务 ,并且保存 定时任务对象,当需要关闭定时任务时,推送到 定时任务进程 在进程上拿 定时任务对象 进行关闭。 感觉这样子应该可以,没有实际操作过

  • 暂无评论
yzh52521

我本地已经测试的差不多了,有人需要么?

  • liziyu 2022-04-02

    🐂

  • weywey 2022-10-20

    大,数据库需要手动创建吗,还是composer直接安装

yzh52521

插件已经写好了

composer require yzh52521/webman-task

欢迎大家测试

  • ala3246875 2022-04-03

    是数据库控制的吗??

  • yzh52521 2022-04-03

    必须数据库控制啊

  • xiaoyuan136 2022-04-12

    webman启动后运行有报错是哪里还需要设置吗,ErrorException: stream_socket_client(): unable to connect to tcp://0.0.0.0:2345 (在其上下文中,该请求的地址无效。
    ) in D:\www\webman\vendor\yzh52521\webman-task\src\Client.php:14

  • yzh52521 2022-04-12

    plugin.yzh52521.task.cron_task 进程启动了么

  • xiaoyuan136 2022-04-12

    启动了webman,默认端口是8787,cron_task好像没有启动,没有这个文件

  • 智佳思远 2022-04-12

    unable to connect to tcp://0.0.0.0:2345,看起来是ip地址不对,应该是127.0.0.1 才对吧

  • yzh52521 2022-04-12

    那你修改下 plugin.yzh52521.task.app.task.listen 为127.0.0.1:2345

  • xiaoyuan136 2022-04-12

    不行的,刚开始我以为也是这个问题,后面换了ip也是不对

  • yzh52521 2022-04-12

    cron_task进程就没有启动起来

  • yzh52521 2022-04-12

    安装 think-orm ,crontab 这些插件了么?

  • xiaoyuan136 2022-04-12

    1.think-orm已安装,少安装了crontab(后面已安装)
    2.ip地址改成了127.0.0.1:8787(没有报ip错误了)
    现在日志里的错误是:default.ERROR: json_decode() expects parameter 1 to be string, bool given {"exception":"TypeError: json_decode() expects parameter 1 to be string, bool given in D:\www\webman\vendor\yzh52521\webman-task\src\Client.php:33

  • yzh52521 2022-04-12

    你怎么调用的 ?

  • xiaoyuan136 2022-04-12

    <?php
    namespace app\controller;

    use support\Request;
    use support\log;
    use think\facade\Db;
    use Workerman\Crontab\Crontab;
    class Test
    {
    public function add(Request $request)
    {
    return json(Db::name('users')->select()->toArray());
    }
    //定时任务
    public function crontab()
    {
    $crontab = new Crontab('1 ', function(){
    echo date('Y-m-d H:i:s')."\n";
    });
    Log::info('log test123',['AAA'=>123,'BB'=>222]);
    /
    $param = [
    'method' => 'crontabIndex',//计划任务列表
    'args' => ['limit' => 10, 'page' => 1]//参数
    ];/
    $param = [
    'method' => 'crontabCreate',//计划任务列表
    'args' => [
    'title' => '输出webman版本',
    'frequency' => '
    /30 *',
    'shell' => 'php webman version',
    'remark' => '每30秒执行',
    'sort' => 0,
    'status' => 1
    ]//参数
    ];
    $result = \yzh52521\Task\Client::instance()->request($param);
    print_r($result);
    //return json($result);
    //return response($result);
    }
    }

  • yzh52521 2022-04-12

    列表

    public function cron_index()
        {
            $request = [
                'method' => 'crontabIndex',
                'args'   => ['limit' => 10, 'page' => 1]
            ];
            $result  = \yzh52521\Task\Client::instance()->request($request);
            return json($result);
        }
    

    添加

    public function cron_create()
        {
            $request = [
                'method' => 'crontabCreate',
                'args'   => [
                    'title'     => '输出 webman 版本',
                    'frequency' => '*/20 * * * * *',
                    'shell'     => 'php webman version',
                    'status'    => 1,
                    'remark'    => '20秒',
                ]
            ];
            $result  = \yzh52521\Task\Client::instance()->request($request);
            return json($result);
        }
  • xiaoyuan136 2022-04-12

    我调用的写法没问题,复制你的也是一样。。你的webman启动后能看到任务进程吗

  • yzh52521 2022-04-12

    可以啊 加我qq好友我帮你看看?

  • xiaoyuan136 2022-04-12

    好,你qq多少我加你

  • yzh52521 2022-04-12

    QQ:396751927

  • xianrenqh 2022-05-27

    TypeError: json_decode() expects parameter 1 to be string, bool given in E:\www\1043huicmf_webman\vendor\yzh52521\webman-task\src\Client.php:36
    Stack trace:

    0 E:\www\1043huicmf_webman\vendor\yzh52521\webman-task\src\Client.php(36): json_decode(false)

    1 E:\www\1043huicmf_webman\app\admin\controller\system\CrontabController.php(50): yzh52521\Task\Client->request(Array)

    2 E:\www\1043huicmf_webman\vendor\workerman\webman-framework\src\App.php(251): app\admin\controller\system\CrontabController->add(Array)

    3 E:\www\1043huicmf_webman\app\admin\middleware\SystemLog.php(46): Webman\App::Webman{closure}(Object(support\Request))

    4 E:\www\1043huicmf_webman\vendor\workerman\webman-framework\src\App.php(245): app\admin\middleware\SystemLog->process(Object(support\Request), Object(Closure))

    5 E:\www\1043huicmf_webman\app\admin\middleware\AuthCheckAccess.php(75): Webman\App::Webman{closure}(Object(support\Request))

    6 E:\www\1043huicmf_webman\vendor\workerman\webman-framework\src\App.php(245): app\admin\middleware\AuthCheckAccess->process(Object(support\Request), Object(Closure))

    7 E:\www\1043huicmf_webman\app\admin\middleware\AccessControl.php(21): Webman\App::Webman{closure}(Object(support\Request))

    8 E:\www\1043huicmf_webman\vendor\workerman\webman-framework\src\App.php(245): app\admin\middleware\AccessControl->process(Object(support\Request), Object(Closure))

    9 E:\www\1043huicmf_webman\vendor\webman\action-hook\src\ActionHook.php(30): Webman\App::Webman{closure}(Object(support\Request))

    10 E:\www\1043huicmf_webman\vendor\workerman\webman-framework\src\App.php(245): Webman\ActionHook\ActionHook->process(Object(support\Request), Object(Closure))

    11 E:\www\1043huicmf_webman\app\middleware\AccessControl.php(21): Webman\App::Webman{closure}(Object(support\Request))

    12 E:\www\1043huicmf_webman\vendor\workerman\webman-framework\src\App.php(245): app\middleware\AccessControl->process(Object(support\Request), Object(Closure))

    13 E:\www\1043huicmf_webman\vendor\workerman\webman-framework\src\App.php(330): Webman\App::Webman{closure}(Object(support\Request))

    14 E:\www\1043huicmf_webman\vendor\workerman\webman-framework\src\App.php(147): Webman\App::findRoute(Object(Workerman\Connection\TcpConnection), '/admin/system/c...', 'GET/admin/syste...', Object(support\Request))

    15 E:\www\1043huicmf_webman\vendor\workerman\workerman\Connection\TcpConnection.php(638): Webman\App->onMessage(Object(Workerman\Connection\TcpConnection), Object(support\Request))

    16 E:\www\1043huicmf_webman\vendor\workerman\workerman\Events\Select.php(295): Workerman\Connection\TcpConnection->baseRead(Resource id #338)

    17 E:\www\1043huicmf_webman\vendor\workerman\workerman\Worker.php(2435): Workerman\Events\Select->loop()

    18 E:\www\1043huicmf_webman\vendor\workerman\workerman\Worker.php(1430): Workerman\Worker->run()

    19 E:\www\1043huicmf_webman\vendor\workerman\workerman\Worker.php(1373): Workerman\Worker::forkWorkersForWindows()

    20 E:\www\1043huicmf_webman\vendor\workerman\workerman\Worker.php(549): Workerman\Worker::forkWorkers()

    21 E:\www\1043huicmf_webman\start.php(112): Workerman\Worker::runAll()

    22 {main}

xianrenqh

@yzh52521
报错


  • yzh52521 2022-05-27

    确实一个字段 frequency

  • xianrenqh 2022-05-27

    大佬怎么改

  • yzh52521 2022-05-27
    CREATE TABLE `system_crontab` (
      `id` int unsigned NOT NULL AUTO_INCREMENT,
      `title` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '任务标题',
      `type` tinyint(1) NOT NULL DEFAULT '1' COMMENT '任务类型 (1 command, 2 class, 3 url, 4 eval)',
      `rule` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '任务执行表达式',
      `target` varchar(150) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '调用任务字符串',
      `running_times` int NOT NULL DEFAULT '0' COMMENT '已运行次数',
      `last_running_time` int NOT NULL DEFAULT '0' COMMENT '上次运行时间',
      `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '备注',
      `sort` int NOT NULL DEFAULT '0' COMMENT '排序,越大越前',
      `status` tinyint NOT NULL DEFAULT '0' COMMENT '任务状态状态[0:禁用;1启用]',
      `create_time` int NOT NULL DEFAULT '0' COMMENT '创建时间',
      `update_time` int NOT NULL DEFAULT '0' COMMENT '更新时间',
      `singleton` tinyint(1) NOT NULL DEFAULT '1' COMMENT '是否单次执行 (0 是 1 不是)',
      `parameter` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '任务调用参数',
      PRIMARY KEY (`id`) USING BTREE,
      KEY `title` (`title`) USING BTREE,
      KEY `create_time` (`create_time`) USING BTREE,
      KEY `status` (`status`) USING BTREE,
      KEY `type` (`type`) USING BTREE
    ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='定时器任务表';
    CREATE TABLE `system_crontab_log` (
      `id` bigint unsigned NOT NULL AUTO_INCREMENT,
      `crontab_id` bigint unsigned NOT NULL COMMENT '任务id',
      `target` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT '任务调用目标字符串',
      `parameter` varchar(500) COLLATE utf8mb4_general_ci NOT NULL COMMENT '任务调用参数',
      `exception` text COLLATE utf8mb4_general_ci NOT NULL COMMENT '异常信息输出',
      `return_code` tinyint(1) NOT NULL DEFAULT '0' COMMENT '执行返回状态[0成功; 1失败]',
      `running_time` varchar(10) COLLATE utf8mb4_general_ci NOT NULL COMMENT '执行所用时间',
      `create_time` int NOT NULL DEFAULT '0' COMMENT '创建时间',
      `update_time` int NOT NULL DEFAULT '0' COMMENT '更新时间',
      PRIMARY KEY (`id`) USING BTREE,
      KEY `create_time` (`create_time`) USING BTREE,
      KEY `crontab_id` (`crontab_id`) USING BTREE
    ) ENGINE=InnoDB AUTO_INCREMENT=392 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='定时器任务执行日志表';
    

    你对照下数据库是不是少字段

  • xianrenqh 2022-05-27

    对比后,没有少字段

  • yzh52521 2022-05-27

    我知道了, https://www.workerman.net/plugin/42 你看下 文档

    $param = [
                'method' => 'crontabCreate',
                'args'   => [
                    'title'     => '输出 webman 版本',
                    'type' =>1,
                    'rule' => '*/30 * * * * *',
                    'target'     => 'php webman version',
                    'status'    => 1,
                    'remark'    => '每30秒执行',
                ]
            ];

    最新版 字段有变动

  • xianrenqh 2022-05-27

    这次可以了

xianrenqh

@yzh52521
代码有个小问题:

  • xianrenqh 2022-05-27

    因composer安装后创建的数据可靠 parameter字段是不能为空且不能为null的,而代码中 默认为空的时候返回的是null,这样在写入数据库的时候一直会报错无法写入成功

  • yzh52521 2022-05-27

    感谢反馈 已修复

mayibanjia

第三方项目有一个你可以参考

  • 暂无评论
owenzhang
  • owenzhang 2022-05-31

    new Crontab('/1 ', function () { '/1 '这个你可以写入redis,然后从redis读取,动态修改

  • 晚安。 2022-08-16

    打不开你的文章

  • owenzhang 2022-08-17

    现在呢?

  • 晚安。 2022-08-17

    new Crontab('/1 ', function () { '/1 '这个你可以写入redis,然后从redis读取,动态修改
    这个redis里面值改了 要重启服务才会生效把

  • owenzhang 2022-08-17

    你可以试下,我没弄过,我想值改了,不用重启也可以,,你试下,告诉我结果,我也备注记录下

  • 晚安。 2022-08-17

    我试了,值改了,没有生效,重启之后才会生效

  • owenzhang 2022-08-18

    好的

  • 晚安。 2022-08-19

    可以修改redis里面值后,然后代码里面执行重启webman服务吗,让其修改生效

  • owenzhang 2022-08-20

    代码里面执行重启webman服务,可以试下

  • 晚安。 2022-08-20

    代码里面怎么重启webman

  • liziyu 2022-08-20

    shell_exec("php start.php restart");

    哈哈。

  • owenzhang 2022-08-20

    你还是参考这个插件吧 composer require yzh52521/webman-task

年代过于久远,无法发表回答
×
🔝