高性能千万级定时任务管理服务 forsun 使用详解

Forsun 高性能高精度定时服务,轻松管理千万级定时任务。
项目地址: https://github.com/snower/forsun

使用 linux 系统定时器提供精确到秒级的定时调度,长时间运行保证无误差。
支持本地内存存储和 redis 持久化存储,使用 redis 可轻松管理数千万定时任务。
支持命令行创建删除任务,支持 Apache Thrift 接口调用创建和删除更新定时任务信息。
支持 shell、http、redis、thrift、beanstalk、mysql 六种到时触发回调方式,并可以通过扩展轻松自定义回调器。

背景

在实际项目中,存在大量需要定时或是延时触发的任务,比如电商中,延时需要检查订单是否支付成功,是否配送成功,定时给用户推送提醒等等,常规做法是用 crontab 每分钟扫码数据看是否到达时间,繁琐且扩展性伸缩性较差。

使用 forsun 服务,可以简单的针对每一个订单创建一个定时任务,配合异步队列,可以轻松实现扩展性伸缩性,Apache Thrift 的编程接口也可以很容易的和 celery、laravel 配合。

其他场景下,比如失败延时重试,使用 forsun 定时服务也可以很简单就可以实现。

安装启动

使用 pip 自动安装

pip install forsun

帮助

forsund -h
usage: forsund [-h] [--bind BIND_HOST] [--port BIND_PORT] [--demon DEMON]
[--log LOG_FILE] [--log-level LOG_LEVEL] [--driver DRIVER]
[--driver-mem-store-file STORE_MEM_STORE_FILE]
[--driver-redis-host DRIVER_REDIS_HOST]
[--driver-redis-port DRIVER_REDIS_PORT]
[--driver-redis-db DRIVER_REDIS_DB]
[--driver-redis-prefix DRIVER_REDIS_PREFIX]
[--driver-redis-server-id DRIVER_REDIS_SERVER_ID]
[--extension-path EXTENSION_PATH] [--extension EXTENSIONS]
High-performance timing scheduling service
optional arguments:
-h, --help show this help message and exit
--bind BIND_HOST bind host (default: 0.0.0.0)
--port BIND_PORT bind port (default: 6458)
--demon DEMON run demon mode
--log LOG_FILE log file
--log-level LOG_LEVEL
log level (defaul: INFO)
--driver DRIVER store driver mem or redis (defaul: mem)
--driver-mem-store-file STORE_MEM_STORE_FILE
store mem driver store file (defaul:
/tmp/forsun.session)
--driver-redis-host DRIVER_REDIS_HOST
store reids driver host (defaul: 127.0.0.1)
--driver-redis-port DRIVER_REDIS_PORT
store reids driver port (defaul: 6379)
--driver-redis-db DRIVER_REDIS_DB
store reids driver db (defaul: 0)
--driver-redis-prefix DRIVER_REDIS_PREFIX
store reids driver key prefix (defaul: forsun)
--driver-redis-server-id DRIVER_REDIS_SERVER_ID
store reids driver server id (defaul: 0)
--extension-path EXTENSION_PATH
extension path
--extension EXTENSIONS
extension name

使用内存持久化存储启动:

forsund --bind=0.0.0.0 --log=/var/log/forsun.log --log-level=INFO --driver=mem --driver-mem-store-file=/var/lib/fousun/forsun.session --demon

使用 redis 持久化存储启动:

forsund --bind=0.0.0.0 --log=/var/log/forsun.log --log-level=INFO --driver=redis --driver-redis-host=127.0.0.1 --driver-redis-db=1 --demon

注意:使用 mem 存储时只有进程正常退出时才会序列化任务保存到本地文件,下次启动时可能会丢失任务,建议使用性能更高的 redis 存储方式。

使用示例

命令行帮助

forsun -h
usage: forsun [-h] [--host HOST] [--port PORT] [--exe EXECUTE] [cmd]
High-performance timing scheduling service
positional arguments:
cmd execute cmd (default: )
optional arguments:
-h, --help show this help message and exit
--host HOST host (default: 127.0.0.1)
--port PORT port (default: 6458)
--exe EXECUTE execute cmd (default: )

延时运行示例

#每五秒运行redis命令,共运行一次
forsun "set redis */5/1 * * * * * redis 'host=172.16.0.2;command='SET b 1 EX 300'"
#每五秒运行shell命令,共运行二次
forsun "set shell */5/2 * * * * * shell 'cmd=ls"
#每五秒运行beanstalk命令,共运行一次
forsun "set beanstalk */5/1 * * * * * beanstalk 'host=10.4.14.14;name=etask;body={}'"
#每五秒请求thrift接口,重复运行
forsun "set thrift */5/0 * * * * * thrift 'host=10.4.14.14;port=4220"
#每五秒请求http接口,共运行一次
forsun "set http */5/1 * * * * * http 'url='http://www.baidu.com''"
#每五秒运行mysql命令,共运行一次
forsun "set mysql */5/1 * * * * * mysql 'host=172.16.0.2;user=root;passwd=123456;db=test;sql='update test set created_at=now() where id=1'"

定时运行示例

于每天16:32:00运行redis命令
forsun "set redis 0 32 16 * * * redis 'host=172.16.0.2;command='SET b 1 EX 300'"
于每小时32:00运行shell命令
forsun "set shell 0 32 * * * * shell 'cmd=ls"
于每分钟1秒时运行beanstalk命令
forsun "set beanstalk 1 * * * * * beanstalk 'host=10.4.14.14;name=etask;body={}'"
于每月3日16:32:00请求thrift接口
forsun "set thrift 0 32 16 3 * * thrift 'host=10.4.14.14;port=4220"
于每天16:32:00请求http接口
forsun "set http 0 32 16 * * * http 'url='http://www.baidu.com''"
于每天16:32:00运行mysql命令
forsun "set mysql 32 16 * * * mysql 'host=172.16.0.2;user=root;passwd=123456;db=test;sql='update test set created_at=now() where id=1'"

Apache Thrift 接口文件定义

exception ForsunPlanError{
1:i16 code,
2:string message
}
struct ForsunPlan {
1: required bool is_time_out,
2: required string key,
3: required i16 second,
4: i16 minute = -1,
5: i16 hour = -1,
6: i16 day = -1,
7: i16 month = -1,
8: i16 week = -1,
9: required i32 next_time,
10: i16 status = 0,
11: i16 count = 0,
12: i16 current_count = 0,
13: i32 last_timeout = 0,
14:string action = "shell",
15:map<string, string> params = {}
}
service Forsun{
i16 ping(),
创建固定时间运行任务
ForsunPlan create(1:string key, 2:i16 second, 3:i16 minute = -1, 4:i16 hour = -1, 5:i16 day = -1, 6:i16 month = -1, 7:i16 week = -1, 8:string action="shell", 9:map<string, string> params={}) throws (1:ForsunPlanError err),
创建延时运行任务
ForsunPlan createTimeout(1:string key, 2:i16 second, 3:i16 minute = -1, 4:i16 hour = -1, 5:i16 day = -1, 6:i16 month = -1, 7:i16 week = -1, 8:i16 count=1, 9:string action="shell", 10:map<string, string> params={}) throws (1:ForsunPlanError err),
删除任务
ForsunPlan remove(1:string key) throws (1:ForsunPlanError err),
获取任务信息
ForsunPlan get(1:string key) throws (1:ForsunPlanError err),
获取当前即将运行任务列表
list<ForsunPlan> getCurrent(),
获取某个时间运行任务列表
list<ForsunPlan> getTime(1:i32 timestamp),
查询某些key前缀任务列表
list<string> getKeys(1:string prefix),
thrift回调器请求函数定义
void forsun_call(1:string key, 2:i32 ts, 3:map<string, string> params)
}
回调器参数详解

回调器参数详解

  • 回调器参数为 create 和 createTimeout 最后一个参数 params key和 value 的 map。

shell 参数

  • cmd shell 命令
  • cwd 工作目录
  • env 环境变量,以;分割=号连接的字符串,如:a=1;b=c

http 参数

  • url 请求接口 URL 字符串
  • method 请求方法,只支持 get,post,put,delete,head 五种方法
  • body 请求体字符串
  • header_ 以 header_为前缀的 key 都会放到请求 header 中
  • auth_username 校验用户名
  • auth_password 校验密码
  • auth_mode 校验方法
  • user_agent 请求 User-Agent
  • connect_timeout 连接超时时间,默认5秒
  • request_timeout 请求超时时间,默认60秒

redis 参数

  • host redis 服务器地址,默认 127.0.0.1
  • port redis 服务器端口,默认 6379
  • selected_db redis 运行命令 db
  • max_connections 连接 redis 服务器最大连接数,第一次连接时的命令中的值有效
  • command 需要执行的命令,多条命令以;分割

mysql 参数

  • host mysql 服务器地址,默认 127.0.0.1
  • port mysql 服务器端口,默认 3306
  • db mysql 运行命令 db,默认 mysql
  • user mysql 登陆用户名,默认 root
  • passwd mysql 登陆密码,默认空字符串
  • max_connections 连接 redis 服务器最大连接数,第一次连接时的命令中的值有效
  • sql 需要执行的 sql

beanstalk 参数

  • host beanstalk 服务器地址,默认127.0.0.1
  • port beanstalk 服务器端口,默认11300
  • name 队列名称,默认 default
  • body 推送的消息体

thrift 参数
回调 thrift 接口时,固定请求 void forsun_call(1:string key, 2:i32 ts, 3:map<string, string> params) 该函数,第三个 params 参数即为任务定义时的 params 值。

  • host thrift 服务器地址,默认 127.0.0.1
  • port thrift 服务器端口,默认 5643
  • max_connections 连接 thrift 服务器最大连接数,第一次连接时的命令中的值有效

转载|出处:http://t.cn/REkSl1C

扫码添加小助手微信,备注"公开课,来源简书",进入分享群
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,294评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,493评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,790评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,595评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,718评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,906评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,053评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,797评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,250评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,570评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,711评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,388评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,018评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,796评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,023评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,461评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,595评论 2 350

推荐阅读更多精彩内容