{"id":16367156,"url":"https://github.com/snower/forsun","last_synced_at":"2025-10-27T04:12:47.637Z","repository":{"id":33408255,"uuid":"37053464","full_name":"snower/forsun","owner":"snower","description":"高性能的定时调度服务。","archived":false,"fork":false,"pushed_at":"2022-07-12T08:07:40.000Z","size":186,"stargazers_count":220,"open_issues_count":0,"forks_count":29,"subscribers_count":12,"default_branch":"master","last_synced_at":"2025-03-30T07:07:55.548Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Python","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/snower.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}},"created_at":"2015-06-08T07:57:30.000Z","updated_at":"2024-09-03T04:24:34.000Z","dependencies_parsed_at":"2022-07-13T11:50:33.442Z","dependency_job_id":null,"html_url":"https://github.com/snower/forsun","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/snower%2Fforsun","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/snower%2Fforsun/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/snower%2Fforsun/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/snower%2Fforsun/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/snower","download_url":"https://codeload.github.com/snower/forsun/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247451653,"owners_count":20940939,"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-10-11T02:48:45.445Z","updated_at":"2025-10-27T04:12:47.571Z","avatar_url":"https://github.com/snower.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n# forsun\n\n[![Build Status](https://travis-ci.org/snower/forsun.svg?branch=master)](https://travis-ci.org/snower/forsun)\n\n高性能的定时调度服务。\n\n使用Linux系统定时器产生精确到秒的定时，长时间运行无误差，支持内存存储和redis持久化存储，轻松支持千万级定时任务调度，支持shell、http、reids、thrift、beanstalk、mysql六种到时触发回调方式，并可以通过扩展轻松自定义回调器。\n\n使用crontab相似命令创建管理任务，同时Thrift接口创建和取消任务，支持大量语言接入。\n\t\n- [安装](#安装)\n- [Docker](#docker)\n- [启动服务](#启动服务)\n- [Bash接口](#bash接口)\n- [Thrift接口](#thrift接口)\n- [HTTP接口](#http接口)\n- [Action参数详解](#action参数详解)\n\n# 安装\n\n```\npip install forsun\n\nor \n\ngit clone https://github.com/snower/forsun.git\npython setup.py install\n```\n\n# Docker\n\n使用docker运行，注意：使用docker运行时，shell和宿主机在同一环境，执行shell时将在docker中运行。\n\n```\ndocker run -d -p 6458:6458 -p 9002:9002 sujin190/forsun:latest\n\n# 使用redis持久化\ndocker run -d -p 6458:6458 -p 9002:9002 -e ARG_DRIVER=redis -e ARG_DRIVER_REDIS_HOST=127.0.0.1 \\\n-e ARG_DRIVER_REDIS_PORT=6379 -e ARG_DRIVER_REDIS_PASSWORD=123456 -e ARG_DRIVER_REDIS_DB=0 sujin190/forsun:latest\n```\n\n```\n# 使用docker-compose\ngit clone https://github.com/snower/forsun.git\ncd forsun\ndocker-compose up -d\n```\n\n# 启动服务\n\n```\nusage: forsund [-h] [--conf CONF] [--bind BIND_HOST] [--port BIND_PORT]\n               [--http HTTP_BIND] [--demon [DEMON]] [--nodemon [NODEMON]]\n               [--log LOG_FILE] [--log-level LOG_LEVEL] [--driver DRIVER]\n               [--driver-mem-store-file STORE_MEM_STORE_FILE]\n               [--driver-redis-host DRIVER_REDIS_HOST]\n               [--driver-redis-port DRIVER_REDIS_PORT]\n               [--driver-redis-db DRIVER_REDIS_DB]\n               [--driver-redis-password DRIVER_REDIS_PASSWORD]\n               [--driver-redis-prefix DRIVER_REDIS_PREFIX]\n               [--driver-redis-server-id DRIVER_REDIS_SERVER_ID]\n               [--extension-path EXTENSION_PATH] [--extension EXTENSIONS]\n\nHigh-performance timing scheduling service\n\noptional arguments:\n  -h, --help            show this help message and exit\n  --conf CONF           conf filename\n  --bind BIND_HOST      bind host (default: 127.0.0.1)\n  --port BIND_PORT      bind port (default: 6458)\n  --http HTTP_BIND      bind http server (default: ) example: 127.0.0.1:80\n  --demon [DEMON]       run demon mode (default: True)\n  --nodemon [NODEMON]   run no demon mode (default: False)\n  --log LOG_FILE        log file\n  --log-level LOG_LEVEL\n                        log level (defaul: INFO)\n  --driver DRIVER       store driver mem or redis (defaul: mem)\n  --driver-mem-store-file STORE_MEM_STORE_FILE\n                        store mem driver store file (defaul: ~/.forsun.dump)\n  --driver-redis-host DRIVER_REDIS_HOST\n                        store reids driver host (defaul: 127.0.0.1)\n  --driver-redis-port DRIVER_REDIS_PORT\n                        store reids driver port (defaul: 6379)\n  --driver-redis-db DRIVER_REDIS_DB\n                        store reids driver db (defaul: 0)\n  --driver-redis-password DRIVER_REDIS_PASSWORD\n                        store reids driver password (defaul: )\n  --driver-redis-prefix DRIVER_REDIS_PREFIX\n                        store reids driver key prefix (defaul: forsun)\n  --driver-redis-server-id DRIVER_REDIS_SERVER_ID\n                        store reids driver server id (defaul: 0)\n  --extension-path EXTENSION_PATH\n                        extension path\n  --extension EXTENSIONS\n                        extension name\n```\n\n### 使用内存持久化存储启动：\n\n```\nforsund --bind=0.0.0.0 --port=6458 --log=/var/log/forsun.log --log-level=INFO --driver=mem --driver-mem-store-file=/var/lib/fousun/forsun.session\n```\n\n### 使用redis持久化存储启动：\n\n```\nforsund --bind=0.0.0.0 --port=6458 --log=/var/log/forsun.log --log-level=INFO --driver=redis --driver-redis-host=127.0.0.1 --driver-redis-db=1\n```\n\n### 提供http接口：\n\n```\nforsund --bind=0.0.0.0 --port=6458 --http=0.0.0.0:9001 --log=/var/log/forsun.log --log-level=INFO --driver=redis --driver-redis-host=127.0.0.1 --driver-redis-db=1\n```\n\n### 使用配置文件前台进程方式启动：\n\n```\nforsund --conf=forsun.conf --nodemon\n```\n\n# Bash接口\n\n```\nforsun -h\nusage: forsun [-h] [--host HOST] [--port PORT] [--exe EXECUTE] [cmd]\n\nHigh-performance timing scheduling service\n\npositional arguments:\n  cmd            execute cmd (default: )\n\noptional arguments:\n  -h, --help     show this help message and exit\n  --host HOST    host (default: 127.0.0.1)\n  --port PORT    port (default: 6458)\n  --exe EXECUTE  execute cmd (default: )\n  \n#timeout模式（每5秒运行，共运行1次）\nforsun \"set redis */5/1 * * * * * redis 'host=172.16.0.2;command=\\'SET b 1 EX 300\\'\"\nforsun \"set shell */5/1 * * * * * shell 'cmd=ls\"\nforsun \"set beanstalk */5/1 * * * * * beanstalk 'host=10.4.14.14;name=etask;body={}'\"\nforsun \"set thrift */5/1 * * * * * thrift 'host=10.4.14.14;port=4220\"\nforsun \"set http */5/1 * * * * * http 'url=\\'http://www.baidu.com\\''\"\nforsun \"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\\'\"\n\n#time模式（定点时间，每天16:32:00运行）\nforsun \"set redis 0 32 16 * * * redis 'host=172.16.0.2;command=\\'SET b 1 EX 300\\'\"\nforsun \"set shell 0 32 16 * * * shell 'cmd=ls\"\nforsun \"set beanstalk 0 32 16 * * * beanstalk 'host=10.4.14.14;name=etask;body={}'\"\nforsun \"set thrift 0 32 16 * * * thrift 'host=10.4.14.14;port=4220\"\nforsun \"set http 0 32 16 * * * http 'url=\\'http://www.baidu.com\\''\"\nforsun \"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\\'\"\n```\n\n# Thrift接口\n\n```\nexception ForsunPlanError{\n    1:i16 code,\n    2:string message\n}\n\nstruct ForsunPlan {\n    1: required bool is_time_out,\n    2: required string key,\n    3: required i16 second,\n    4: i16 minute = -1,\n    5: i16 hour = -1,\n    6: i16 day = -1,\n    7: i16 month = -1,\n    8: i16 week = -1,\n    9: required i32 next_time,\n    10: i16 status = 0,\n    11: i16 count = 0,\n    12: i16 current_count = 0,\n    13: i32 last_timeout = 0,\n    14:string action = \"shell\",\n    15:map\u003cstring, string\u003e params = {}\n}\n\nservice Forsun{\n    i16 ping(),\n    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\u003cstring, string\u003e params={}) throws (1:ForsunPlanError err),\n    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\u003cstring, string\u003e params={}) throws (1:ForsunPlanError err),\n    ForsunPlan remove(1:string key) throws (1:ForsunPlanError err),\n    ForsunPlan get(1:string key) throws (1:ForsunPlanError err),\n    list\u003cForsunPlan\u003e getCurrent(),\n    list\u003cForsunPlan\u003e getTime(1:i32 timestamp),\n    list\u003cstring\u003e getKeys(1:string prefix),\n    void forsun_call(1:string key, 2:i32 ts, 3:map\u003cstring, string\u003e params)\n}\n```\n\n# HTTP接口\n\n启用http接口需添加--http参数，如--http=0.0.0.0:8001\n\n### 创建定时执行任务\n\nPOST /v1/plan\n\n```\n# 在03-23 16:35:01执行http get请求http://www.baidu.com/\ncurl -X POST -H 'Content-Type: application/json' -d '{\"key\": \"test\", \"seconds\": 1, \"minute\": 35, \"hour\": 16, \"day\": 23, \"month\": 3, \"action\": \"http\", \"params\": {\"url\": \"http://www.baidu.com/\"}}' http://127.0.0.1:8001/v1/plan\n\n{\"data\": {\"week\": -1, \"status\": 0, \"is_time_out\": false, \"hour\": 16, \"current_count\": 0, \"count\": 0, \"month\": 3, \"action\": \"http\", \"second\": -1, \"params\": {\"url\": \"http://www.baidu.com/\"}, \"key\": \"test\", \"created_time\": 1521764975.0, \"next_time\": 1521794100, \"last_timeout\": 0, \"day\": 23, \"minute\": 35}, \"errcode\": 0, \"errmsg\": \"\"}\n```\n\naction及params参数信息请查看下Action参数信息\n\n### 创建延时任务\n\nPUT /v1/plan\n\n```\n# 5秒后执行1次http get请求http://www.baidu.com/\ncurl -X PUT -H 'Content-Type: application/json' -d '{\"key\": \"test\", \"seconds\": 5, \"minute\": 0, \"hour\": 0, \"day\": 0, \"month\": 0, \"count\": 0, \"action\": \"http\", \"params\": {\"url\": \"http://www.baidu.com/\"}}' http://127.0.0.1:8001/v1/plan\n\n{\"data\": {\"week\": -1, \"status\": 0, \"is_time_out\": true, \"hour\": 0, \"current_count\": 0, \"count\": 0, \"month\": 0, \"action\": \"http\", \"second\": -1, \"params\": {\"url\": \"http://www.baidu.com/\"}, \"key\": \"test\", \"created_time\": 1521765952.0, \"next_time\": 1521765952, \"last_timeout\": 0, \"day\": 0, \"minute\": 0}, \"errcode\": 0, \"errmsg\": \"\"}\n```\naction及params参数信息请查看下Action参数信息\n\n### 查询任务\n\nGET /v1/plan\n\n```\n# 查询test任务信息\ncurl -X GET -H 'Content-Type: application/json' http://127.0.0.1:8001/v1/plan?key=test\n\n{\"data\": {\"week\": -1, \"status\": 0, \"is_time_out\": true, \"hour\": 0, \"current_count\": 1, \"count\": 0, \"month\": 0, \"action\": \"http\", \"second\": -1, \"params\": {\"url\": \"http://www.baidu.com/\"}, \"key\": \"test\", \"created_time\": 1521766188.0, \"next_time\": 1521766213, \"last_timeout\": 1521766188, \"day\": 0, \"minute\": 0}, \"errcode\": 0, \"errmsg\": \"\"}\n```\n\n### 删除任务\n\nDELETE /v1/plan\n\n```\n# 删除test任务信息\n\ncurl -X DELETE -H 'Content-Type: application/json' http://127.0.0.1:8001/v1/plan?key=test\n\n{\"data\": {\"week\": -1, \"status\": 0, \"is_time_out\": true, \"hour\": 0, \"current_count\": 1, \"count\": 0, \"month\": 0, \"action\": \"http\", \"second\": -1, \"params\": {\"url\": \"http://www.baidu.com/\"}, \"key\": \"test\", \"created_time\": 1521766188.0, \"next_time\": 1521766378, \"last_timeout\": 1521766188, \"day\": 0, \"minute\": 0}, \"errcode\": 0, \"errmsg\": \"\"}\n```\n\n### 获取某时刻执行任务信息\n\nGET /v1/time\n\n```\n# 查询1521795279这一刻要执行的任务信息\n\ncurl -X GET -H 'Content-Type: application/json' http://127.0.0.1:8001/v1/time?timestamp=1521795279\n\n{\"data\": {\"current_timestamp\": 1521159718, \"plans\": []}, \"errcode\": 0, \"errmsg\": \"\"}\n```\n\ntimestamp参数不传递或为0查询下一秒执行任务信息\n\n### 查询任务KEY\n\nGET /v1/keys\n\n```\n# 过滤t开头的任务\ncurl -X GET -H 'Content-Type: application/json' http://127.0.0.1:8001/v1/keys?prefix=t\n\n{\"data\": [], \"errcode\": 0, \"errmsg\": \"\"}\n```\n\n# Action参数详解\n\n回调器参数为create和createTimeout最后一个参数params key和value的map。\n\n## shell参数\n\n* cmd shell命令\n* cwd 工作目录\n* env 环境变量，以;分割＝号连接的字符串，如：a=1;b=c\n\n## http参数\n\n* url 请求接口URL字符串\n* method 请求方法，只支持get,post,put,delete,head五种方法\n* body 请求体字符串\n* header_ 以header_为前缀的key都会放到请求header中\n* auth_username 校验用户名\n* auth_password 校验密码\n* auth_mode 校验方法\n* user_agent 请求User－Agent\n* connect_timeout 连接超时时间，默认5秒\n* request_timeout 请求超时时间，默认60秒\n\n## redis参数\n\n* host redis服务器地址，默认127.0.0.1\n* port redis服务器端口，默认6379\n* selected_db redis运行命令db\n* max_connections 连接redis服务器最大连接数，第一次连接时的命令中的值有效\n* command 需要执行的命令，多条命令以;分割\n\n## mysql参数\n\n* host mysql服务器地址，默认127.0.0.1\n* port mysql服务器端口，默认3306\n* db mysql运行命令db，默认mysql\n* user mysql登陆用户名，默认root\n* passwd mysql登陆密码，默认空字符串\n* max_connections 连接redis服务器最大连接数，第一次连接时的命令中的值有效\n* sql 需要执行的sql\n\n## beanstalk参数\n\n* host beanstalk服务器地址，默认127.0.0.1\n* port beanstalk服务器端口，默认11300\n* name 队列名称，默认default\n* body 推送的消息体\n\n## thrift参数\n\n回调thrift接口时，固定请求void forsun_call(1:string key, 2:i32 ts, 3:map\u003cstring, string\u003e params)该函数，第三个params参数即为任务定义时的params值。\n\n* host thrift服务器地址，默认127.0.0.1\n* port thrift服务器端口，默认5643\n* max_connections 连接thrift服务器最大连接数，第一次连接时的命令中的值有效\n\n\n# License\n\nforsun uses the MIT license, see LICENSE file for the details.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsnower%2Fforsun","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsnower%2Fforsun","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsnower%2Fforsun/lists"}