基于supervisor秒级Laravel定时任务
背景介绍
公司需要实现X分钟内每隔Y秒轮训某个接口,Linux自带的crontab貌似只精确到分钟,虽然可以到精确到秒,但是并不满足需求。
选型
公司项目都是 基于 Laravel 框架,所以这个没得选。守护进程用的 supervisor,看看这个家伙能不能满足我们的需求
代码
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Cache;
use Carbon\Carbon;
class TaskCommand extends Command {
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'ue:task
{--id= : 当前编号}
{--max= : 最大线程}
{--sleep= : 休眠多少毫秒}
{--debug= : 是否调试模式}
';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Command description';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct() {
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle() {
$this->id = $this->option('id') ?? '00';
$this->max = $this->option('max') ?? 32;
$this->sleep = $this->option('sleep') ?? 700;
$this->debug = $this->option('debug') ?? false;
if ($this->id > $this->max) {
return true;
}
while (true) {
$this->doRun();
}
}
/**
*
* @param int $taskId
* @return boolean
*/
protected function doRun() {
$lock = sprintf('task:%03d:%s', $this->id, time());
$data = [
'id' => $this->id,
'max' => $this->max,
'time' => (new Carbon)->format('Y-m-d H:i:s.u'),
'key' => $lock,
];
try {
$result = cache()->get($lock);
if ($result) {
$data['message'] = 'Task Has been executed.';
$this->wait($this->sleep);
return true;
}
cache()->put($lock, true, 2);
$data['message'] = 'Task Executed.';
$this->logger($data);
$this->wait($this->sleep);
} catch (\Exception $ex) {
$data['message'] = $ex->getMessage();
cache()->put($data, true, 2);
$this->wait($this->sleep);
}
}
/**
* 毫秒
* @param string $time
*/
protected function wait($time) {
$wait = $time * 1000;
usleep($wait);
}
protected function logger($message) {
if($this->debug){
$time = (new Carbon)->format('Y-m-d H:i:s.u');
$this->line(array_get($message, 'message') .' - '. $time);
}
logger()->stack(['task'])->debug(null, $message);
}
}
进程守护
```
[program:task-worker]
process_name=%(program_name)s_%(process_num)02d
command=/usr/bin/php /home/wwwroot/demo/artisan ue:task --id=%(process_num)02d --max=8
autostart=true
autorestart=true
user=www
numprocs=8
redirect_stderr=true
stdout_logfile=/home/wwwroot/demo/storage/logs/worker.log
```
上面是supervisor的配置
效果图
Task Executed. - 2018-08-14 22:17:18.985094
Task Executed. - 2018-08-14 22:17:19.336115
Task Executed. - 2018-08-14 22:17:20.038236
Task Executed. - 2018-08-14 22:17:21.090470
Task Executed. - 2018-08-14 22:17:22.142716
Task Executed. - 2018-08-14 22:17:23.195126
Task Executed. - 2018-08-14 22:17:24.247698
Task Executed. - 2018-08-14 22:17:25.300066
Task Executed. - 2018-08-14 22:17:26.352638
Task Executed. - 2018-08-14 22:17:27.054124
Task Executed. - 2018-08-14 22:17:28.106420
Task Executed. - 2018-08-14 22:17:29.158906
Task Executed. - 2018-08-14 22:17:30.211438
Task Executed. - 2018-08-14 22:17:31.263542
Task Executed. - 2018-08-14 22:17:32.315923
Task Executed. - 2018-08-14 22:17:33.017096
Task Executed. - 2018-08-14 22:17:34.068963
Task Executed. - 2018-08-14 22:17:35.121267
Task Executed. - 2018-08-14 22:17:36.173600
Task Executed. - 2018-08-14 22:17:37.226165
输出日志
[2018-08-14 22:12:24] local.DEBUG: {"id":"1","max":"32","time":"2018-08-14 22:12:24.389224","key":"task:001:1534255944","message":"Task Executed."}
[2018-08-14 22:12:25] local.DEBUG: {"id":"1","max":"32","time":"2018-08-14 22:12:25.390158","key":"task:001:1534255945","message":"Task Executed."}
[2018-08-14 22:12:26] local.DEBUG: {"id":"1","max":"32","time":"2018-08-14 22:12:26.391594","key":"task:001:1534255946","message":"Task Executed."}
[2018-08-14 22:12:27] local.DEBUG: {"id":"1","max":"32","time":"2018-08-14 22:12:27.393196","key":"task:001:1534255947","message":"Task Executed."}
[2018-08-14 22:12:28] local.DEBUG: {"id":"1","max":"32","time":"2018-08-14 22:12:28.395124","key":"task:001:1534255948","message":"Task Executed."}
[2018-08-14 22:12:29] local.DEBUG: {"id":"1","max":"32","time":"2018-08-14 22:12:29.396796","key":"task:001:1534255949","message":"Task Executed."}
[2018-08-14 22:12:30] local.DEBUG: {"id":"1","max":"32","time":"2018-08-14 22:12:30.398666","key":"task:001:1534255950","message":"Task Executed."}
[2018-08-14 22:12:31] local.DEBUG: {"id":"1","max":"32","time":"2018-08-14 22:12:31.400561","key":"task:001:1534255951","message":"Task Executed."}
[2018-08-14 22:12:32] local.DEBUG: {"id":"1","max":"32","time":"2018-08-14 22:12:32.402462","key":"task:001:1534255952","message":"Task Executed."}
[2018-08-14 22:12:33] local.DEBUG: {"id":"1","max":"32","time":"2018-08-14 22:12:33.404092","key":"task:001:1534255953","message":"Task Executed."}
[2018-08-14 22:12:34] local.DEBUG: {"id":"1","max":"32","time":"2018-08-14 22:12:34.405550","key":"task:001:1534255954","message":"Task Executed."}
[2018-08-14 22:12:35] local.DEBUG: {"id":"1","max":"32","time":"2018-08-14 22:12:35.407197","key":"task:001:1534255955","message":"Task Executed."}
[2018-08-14 22:12:36] local.DEBUG: {"id":"1","max":"32","time":"2018-08-14 22:12:36.408920","key":"task:001:1534255956","message":"Task Executed."}
[2018-08-14 22:12:37] local.DEBUG: {"id":"1","max":"32","time":"2018-08-14 22:12:37.410841","key":"task:001:1534255957","message":"Task Executed."}
[2018-08-14 22:12:38] local.DEBUG: {"id":"1","max":"32","time":"2018-08-14 22:12:38.412764","key":"task:001:1534255958","message":"Task Executed."}
[2018-08-14 22:12:39] local.DEBUG: {"id":"1","max":"32","time":"2018-08-14 22:12:39.414518","key":"task:001:1534255959","message":"Task Executed."}
[2018-08-14 22:12:40] local.DEBUG: {"id":"1","max":"32","time":"2018-08-14 22:12:40.416229","key":"task:001:1534255960","message":"Task Executed."}
[2018-08-14 22:12:41] local.DEBUG: {"id":"1","max":"32","time":"2018-08-14 22:12:41.418001","key":"task:001:1534255961","message":"Task Executed."}
[2018-08-14 22:12:42] local.DEBUG: {"id":"1","max":"32","time":"2018-08-14 22:12:42.419476","key":"task:001:1534255962","message":"Task Executed."}
[2018-08-14 22:12:43] local.DEBUG: {"id":"1","max":"32","time":"2018-08-14 22:12:43.421388","key":"task:001:1534255963","message":"Task Executed."}
[2018-08-14 22:12:44] local.DEBUG: {"id":"1","max":"32","time":"2018-08-14 22:12:44.423164","key":"task:001:1534255964","message":"Task Executed."}
[2018-08-14 22:12:45] local.DEBUG: {"id":"1","max":"32","time":"2018-08-14 22:12:45.424798","key":"task:001:1534255965","message":"Task Executed."}
[2018-08-14 22:12:46] local.DEBUG: {"id":"1","max":"32","time":"2018-08-14 22:12:46.426667","key":"task:001:1534255966","message":"Task Executed."}
[2018-08-14 22:12:47] local.DEBUG: {"id":"1","max":"32","time":"2018-08-14 22:12:47.428553","key":"task:001:1534255967","message":"Task Executed."}
[2018-08-14 22:12:48] local.DEBUG: {"id":"1","max":"32","time":"2018-08-14 22:12:48.430427","key":"task:001:1534255968","message":"Task Executed."}
[2018-08-14 22:12:49] local.DEBUG: {"id":"1","max":"32","time":"2018-08-14 22:12:49.432118","key":"task:001:1534255969","message":"Task Executed."}
[2018-08-14 22:12:50] local.DEBUG: {"id":"1","max":"32","time":"2018-08-14 22:12:50.433893","key":"task:001:1534255970","message":"Task Executed."}
[2018-08-14 22:12:51] local.DEBUG: {"id":"1","max":"32","time":"2018-08-14 22:12:51.435711","key":"task:001:1534255971","message":"Task Executed."}
[2018-08-14 22:12:52] local.DEBUG: {"id":"1","max":"32","time":"2018-08-14 22:12:52.437015","key":"task:001:1534255972","message":"Task Executed."}
[2018-08-14 22:12:53] local.DEBUG: {"id":"1","max":"32","time":"2018-08-14 22:12:53.438352","key":"task:001:1534255973","message":"Task Executed."}
[2018-08-14 22:12:54] local.DEBUG: {"id":"1","max":"32","time":"2018-08-14 22:12:54.439989","key":"task:001:1534255974","message":"Task Executed."}
[2018-08-14 22:12:55] local.DEBUG: {"id":"1","max":"32","time":"2018-08-14 22:12:55.441580","key":"task:001:1534255975","message":"Task Executed."}
[2018-08-14 22:12:56] local.DEBUG: {"id":"1","max":"32","time":"2018-08-14 22:12:56.443116","key":"task:001:1534255976","message":"Task Executed."}
[2018-08-14 22:12:57] local.DEBUG: {"id":"1","max":"32","time":"2018-08-14 22:12:57.445006","key":"task:001:1534255977","message":"Task Executed."}
原文地址:https://segmentfault.com/a/1190000016012148
基于supervisor秒级Laravel定时任务的更多相关文章
- 基于Flink秒级计算时CPU监控图表数据中断问题
基于Flink进行秒级计算时,发现监控图表中CPU有数据中断现象,通过一段时间的跟踪定位,该问题目前已得到有效解决,以下是解决思路: 一.问题现象 以SQL02为例,发现本来10秒一 ...
- Swoft 2.0.5 更新,新增高效秒级定时任务、异常管理组件
什么是 Swoft ? Swoft 是一款基于 Swoole 扩展实现的 PHP 微服务协程框架.Swoft 能像 Go 一样,内置协程网络服务器及常用的协程客户端且常驻内存,不依赖传统的 PHP-F ...
- Linux下实现秒级的crontab定时任务
crontab的格式如下 * * * * * command 分 时 日 月 周 命令 第1列表示分钟1-59 每分钟用*或者 */1表示 第2列表示小时1-23(0表示0点) 第3列表示日期1-31 ...
- Linux下实现秒级定时任务的两种方案
Linux下实现秒级定时任务的两种方案(Crontab 每秒运行): 第一种方案,当然是写一个后台运行的脚本一直循环,然后每次循环sleep一段时间. while true ;do command s ...
- 百亿级别数据量,又需要秒级响应的案例,需要什么系统支持呢?下面介绍下大数据实时分析工具Yonghong Z-Suite
Yonghong Z-Suite 除了提供优秀的前端BI工具之外,Yonghong Z-Suite让用户可以选购分布式数据集市来支持实时大数据分析. 对于这种百亿级的大数据案例,Yonghong Z- ...
- java中基于TaskEngine类封装实现定时任务
主要包括如下几个类: 文章标题:java中基于TaskEngine类封装实现定时任务 文章地址: http://blog.csdn.net/5iasp/article/details/10950529 ...
- Freeline--Android平台上的秒级编译方案
Freeline 技术揭秘 Freeline是什么? Freeline是蚂蚁金服旗下一站式理财平台蚂蚁聚宝团队15年10月在Android平台上的量身定做的一个基于动态替换的编译方案,5月阿里集团内部 ...
- 《阿里如何实现秒级百万TPS?搜索离线大数据平台大数据平台架构解读》读后感
在使用淘宝时发现搜索框很神奇,它可以将将我们想要的商品全部查询出来,但是我们并感觉不到数据库查询的过程,速度很快.通过阅读这篇文章让我知道了搜索框背后包含着很多技术,对我以后的学习可能很有借鉴. 平时 ...
- 软件架构自学笔记-- 转载“虎牙在全球 DNS 秒级生效上的实践”
虎牙在全球 DNS 秒级生效上的实践 这次分享的是全球 DNS 秒级生效在虎牙的实践,以及由此产生的一些思考,整体上,分为以下 5 各部分: 背景介绍: 方案设计和对比: 高可用: 具体实践和落地: ...
随机推荐
- jQuery--编辑表格
表格操作是我们常常遇到的,还记得刚開始学习牛腩新闻公布系统时.跟着视频进行表格的一些基本操作.而对它的原理与概念全然不懂,不过跟着老师的操作而进行操作. 通过这次学习,对表格的操作有了进一步的了解与掌 ...
- 批量将网页转换成图片或PDF文档技巧分享
工作中我们有时要将一些批量的网页转换成图片或者PDF文档格式,尽管多数浏览器具有滚动截屏或者打印输出PDF文档功能.可是假设有几十上百张网页须要处理,那也是要人命的.所以我一直想找一款可以批量处理该工 ...
- 为PhoneGap写一个android插件
为PhoneGap写一个android插件,要怎么做? 其实这句话应该反过来说,为android写一个PhoneGap插件,要怎么做? 这里以最简单的Hello World!为例,做个说明: 1.第一 ...
- 关于PowerDesigner导出数据库表到word文档
关于PowerDesigner导出数据库表到word文档 一.查看全部模板: powerdesigner默觉得我们提供了非常多的模版,在工具栏中选择[Report(报告)--->Report T ...
- AngularJS2.0 hello world例子——引入这么多额外的依赖库真是很忧伤啊
初识Angular2 写一个Angular2的Hello World应用相当简单,分三步走: 1. 引入Angular2预定义类型 import {Component,View,bootstrap} ...
- NodeJs函数式编程
虽然标题是NodeJS函数式编程,但实际上NodeJS 是一个框架,不是一种语言,其采用的语言是 JavaScript.而JavaScript是一种典型的多范式编程语言,算不上是函数式语言,但它有函数 ...
- bzoj3105 [cqoi2013]新Nim游戏——贪心+线性基
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3105 首先,要先手必胜,就不能取后让剩下的火柴中存在异或和为0的子集,否则对方可以取成异或和 ...
- WP处理事件
(1).Launching事件 Launching(进入)事件是每一个第三方应用在第一次运行时都必须执行的事件,它主要负责应用程序的初始化.这个事件与Closing事件是对应的,一个运行正常的应用程序 ...
- flux,redux,vuex状态集管理工具之间的区别
一:redux和flux的区别 1)redux是flux中的一个实现 2))在redux中我们只能定义一个store,在flux中我们可以定义多个 3)在redux中,store和dispatch都放 ...
- BZOJ 1845 Simpson积分
思路: Simpson积分直接上 限制一下递归深度+精度就好了 (难以理解为什么这么多人写扫描线) //By SiriusRen #include <bits/stdc++.h> usi ...