增强的单据通esb插件任务调度策略及配置
来源:互联网 发布:php中空对象的if 判断 编辑:程序博客网 时间:2024/05/19 02:03
1.缘起
基于hotfox的程序,到v3.2止只支持2种后台任务调度方式:(1)每间隔:适用于指定一段时间重复执行的任务,如每小时执行一次
(2)每天执行一次:需要指定执行的时间,精确到分钟,如02:30.
近期的2个项目分别提出了超出上述能力的需求,这些需求的含义描述如下:
- 要求每N周执行一次,可指定一周的哪天的什么时间,如每2周的周三19:00执行一次
- 要求每月执行一次,可指定哪天和时间点,如每月1号的20:00执行一次.
增强后实现了对以下调度策略的支持:
ID
名称
参数
参数说明
上次活动标记
示例及说明
1
每间隔
间隔时间
间隔时间单位:秒
1,0,60
表示间隔60秒
2
每天执行
执行时间(HHMM),到期检查间隔
YYYYMMDD
2,0,200,60
每天2:00执行,到期检测间隔60秒
3
按周调度
周数,星期几,执行时间(HHMM),到期检查间隔
星期几,执行时间可选
YY YYMMDD
3,0,2,1,200,60
每2周的周一的2:00执行,到期检查间隔60秒
4
按月调度
每月N号,执行时间(HHMM),到期检查间隔
执行时间可选
YYYYMM
4,0,(1),(2200),60
每月1号22:00执行,到期检查间隔60秒
策略定义格式:策略ID,属性,参数
策略属性:保留,如可用于指定一次性任务。
记录上次活动的时间标记可以在服务重起启动时能正确地接续,避免任务重做或漏做。
标记的时间是任务开始执行的时间(而非任务结束的时间,这对每天执行运行时间跨天的情况存在语义上的差异).
2.配置说明
以下以esb插件为例说明如何配置后台任务的调度策略:<ScheduleStrategy> <strategy>4,0,(1),(2200),60</strategy> <last_time_tag>201308</last_time_tag> </ScheduleStrategy> <Schedule Type="0"> <Interval>6</Interval> </Schedule>
<ScheduleStrategy>是新的策略定义节点,<Schedule>是原有的策略定义.
优先采用<ScheduleStrategy>定义,只有在没有<ScheduleStrategy>时才检查<Schedule>.
上述<ScheduleStrategy>配置中,<strategy>为策略定义,<last_time_tag>为任务上次执行的时间标记.
<strategy>4,0,(1),(2200),60</strategy>表示:
该任务采用每月1号22:00执行一次.到期检查间隔为60秒.
其中,"(1)"和"(2200)"参数中使用括号是考虑对每月某几天或某天的几个时间点执行.
3.实现说明
实现方法考虑以下特性:(1)必须兼容现有部署运行的系统
(2)既然无法一劳永逸适应所有的可能,模块应该方便应需求驱动进行扩展.
3.1hotfox
增强依赖对hotfox关于后台任务(DeamonTask,DeamonTaskManager)接口的改变,新的IDeamonTask接口增加了以下方法:typedef int (*OnTaskDoneFunc)(void *arg,const char *tag); ///< 任务结束回调struct IDeamonTask {public: ///< 取任务的调度策略 virtual IScheduleStrategy* get_strategy() = 0; ///< 指定任务的调度策略 virtual void set_strategy(IScheduleStrategy *strategy) = 0; ///< 设置按周调度策略 virtual int set_week_strategy(unsigned short week_num,unsigned short week_day,unsigned short start_time,unsigned short interval=60,unsigned long last_day=0) = 0; ///< 获取任务ID virtual unsigned long get_id() const = 0; ///< 设置回调函数 virtual void set_done_cb(OnTaskDoneFunc func,void *arg=0) = 0; ///< 获取回调函数 virtual OnTaskDoneFunc get_done_cb() = 0; ///< 获取回调参数 virtual void* get_done_cb_arg() = 0;};OnTaskDoneFunc回调函数的用途是在任务执行成功后修改上次任务时间标记.
该标记可能保存在本地配置文件中,也可以集中保存在数据库中.这由具体的应用体系来决定。
set_week_strategy提供内置的按周调度的策略设置方法.
get_id返回任务ID,该ID没有全局意义.仅用于执行回调修改上次任务时间标记时能正确匹配。
按周调度作为内置功能提供,按月调度采用框架外实现.目的一是作为以后扩展的示例,二是避免每增加新的调度策略需要框架修改.
主要实现修改内容:
3.2 esb_task.h
class c_esb_scan_rule_week : public i_esb_scan_rule {public: short week_num_; short wday_; long l_time_; short n_interval_; unsigned long last_day_;public: c_esb_scan_rule_week():n_interval_(60),last_day_(0) { } virtual int ReadConfig(INode* parentNode) { return 0;} virtual void settaskinfo(IDeamonTask* task); bool tg_flag() const { return true;}};class c_esb_scan_rule_month : public i_esb_scan_rule {public: short n_day_; long l_time_; short n_interval_; unsigned long last_month_;public: c_esb_scan_rule_month():n_interval_(60),last_month_(0) { } virtual int ReadConfig(INode* parentNode) { return 0;} virtual void settaskinfo(IDeamonTask* task); bool tg_flag() const { return true;}};
3.3 esb_task.cpp
i_esb_scan_rule* c_esb_scan_rule_factory::new_rule(INode* parentNode) { INode* subnode = parentNode->GetChildNodes()->GetChildNode("strategy"); ///< 策略描述串 if (subnode==NULL) return NULL; string ss = (string)*subnode; i_esb_scan_rule* rule = 0; CStrategyStringParser ssp; ssp.set_ss(ss.c_str()); int type = ssp.get_type(); subnode = parentNode->GetChildNodes()->GetChildNode("last_time_tag"); ///< 最近一次任务时间标记 if (type!=1&&subnode==NULL) ///< 每间隔调度策略目前不记录上次执行时间标记(影响性能,并且不必要) return NULL; string tg = (string)*subnode; ssp.get_prop(); char *buffer = 0; switch(type) { case 1: { c_esb_scan_rule_time *c_rule = new c_esb_scan_rule_time; ssp.get_next_item(&buffer); c_rule->l_interval_ = atol(buffer); delete []buffer; rule = c_rule; break; } case 2: { c_esb_scan_rule_date *c_rule = new c_esb_scan_rule_date; ssp.get_next_item(&buffer); c_rule->l_time_ = atoi(buffer); delete []buffer; if (ssp.get_next_item(&buffer)) { c_rule->n_interval_ = atoi(buffer); delete []buffer; } c_rule->last_day_ = atol(tg.c_str()); rule = c_rule; break; } case 3: { c_esb_scan_rule_week *c_rule = new c_esb_scan_rule_week; c_rule->week_num_ = atoi(buffer); delete []buffer; if (ssp.get_next_item(&buffer)) { c_rule->wday_ = atoi(buffer); delete []buffer; } if (ssp.get_next_item(&buffer)) { c_rule->l_time_ = atol(buffer); delete []buffer; } if (ssp.get_next_item(&buffer)) { c_rule->n_interval_ = atoi(buffer); delete []buffer; } c_rule->last_day_ = atol(tg.c_str()); rule = c_rule; break; } case 4: { c_esb_scan_rule_month *c_rule = new c_esb_scan_rule_month; char *buffer = 0; ssp.get_next_item(&buffer); c_rule->n_day_ = atol(buffer); delete []buffer; if (ssp.get_next_item(&buffer)!=-1) { c_rule->l_time_ = atoi(buffer); delete []buffer; } if (ssp.get_next_item(&buffer)) { c_rule->n_interval_ = atoi(buffer); delete []buffer; } c_rule->last_month_ = atol(tg.c_str()); rule = c_rule; break; } default: return 0; } return rule;}void c_esb_scan_rule_week::settaskinfo(IDeamonTask* task) { task->set_week_strategy(week_num_,wday_,l_time_,n_interval_,last_day_);}void c_esb_scan_rule_month::settaskinfo(IDeamonTask* task) { CMonthStrategy *stg = new CMonthStrategy; stg->last_month_ = last_month_; stg->active_day_ = n_day_; stg->start_time_ = l_time_; stg->interval_ = n_interval_; task->set_strategy(stg);}
3.4 esb.cpp
int esbPlugin::ReadPrivateConfig() nodelist_sheet = parentNode->GetChildNodes()->GetChildNodes("ScanTask"); count = nodelist_sheet->Count(); for(i=0;i<count;i++){ INode *subnode = nodelist_sheet->GetChildNode(i); c_esb_task* task = new c_esb_task(); task->set_id(i+1); ///< 设置任务ID vec_tasklist.push_back(task); ret = task->ReadConfig(subnode); if(ret){ config_->Close(); ACE_ERROR_RETURN((LM_ERROR,"esb:open config::Tasks::SheetFileScanTask[%s] 返回值=[%d].\n",cf_.c_str(),ret),-1); } } int esbPlugin::RegisterTask() { vector<c_esb_task*>::iterator iter = vec_tasklist.begin(); for(; iter != vec_tasklist.end(); iter++) { c_esb_task* esbtask = *iter; IDeamonTask *task = deamon_mgr_->add(OnTaskTranslate1,"esbPlugin::OnTaskTranslate1",esbtask); esbtask->settaskinfo(task); if (esbtask->c_rule_->tg_flag()) { task->set_done_cb(::OnTaskDoneProc,(void*)esbtask->id_); ///< 设置任务结束回调函数 } } return 0;}////////////////////////////////////////////////////////////////////////////////int OnTaskDoneProc(void *arg,const char *tag) { return esbPlugin_Singleton::instance()->OnTaskDoneProc(arg,tag);}////////////////////////////////////////////////////////////////////////////////int esbPlugin::OnTaskDoneProc(void *arg,const char *tag) { AUTO_CLOSE_CONFIG(config_); int t_id = (int)arg; if (config_->Open(cf_.c_str())) { return -1; } INode *root = config_->GetChildNodes()->GetChildNode("config"); INode *node,*attr; INode *task_list_node = root->GetChildNodes()->GetChildNode("Tasks"); if (task_list_node==0) return -1; INodeList *nl = task_list_node->GetChildNodes()->GetChildNodes("ScanTask"); int task_num = nl->Count(); for (int i=0;i<task_num;i++) { INode *subnode = nl->GetChildNode(i); if (t_id==(i+1)) { INode *stg_node = subnode->GetChildNodes()->GetChildNode("ScheduleStrategy"); if (stg_node==0) return 0; INode *last_time_tag_node = stg_node->GetChildNodes()->GetChildNode("last_time_tag"); last_time_tag_node->operator=((char*)tag); config_->Save(); break; } } nl->Release(); config_->Close(); return 0;}
3.5 工程
.增加:quartz_month_strategy,quartz_strategy_parser(.cpp,.h文件)4.HOWTOD
4.1如何使用已实现的调度策略
4.2如何增加新的调度策略
5.TODO
- 增强的单据通esb插件任务调度策略及配置
- Spark任务调度流程及调度策略分析
- 任务调度策略
- Linux 任务调度策略
- Spring 任务调度配置及使用
- 进程调度及调度策略
- 嵌入式系统设计过程中任务优先级调度的策略
- Spring中Quartz任务调度的配置
- Spring--Quartz 任务调度的配置详解
- spring任务调度quarzt的配置
- Linux下io磁盘调度策略及配置
- Spring任务调度配置
- quartz任务调度配置
- spring任务调度配置
- Storm中Topology任务调度策略
- Hadoop yarn任务调度策略介绍
- Hadoop yarn任务调度策略介绍
- Elasticsearch 免费认证插件Search-guard的部署安装及策略配置
- 问题集锦索引
- storm-0.8.2源码分析之topology启动
- Nearest Neighbor Image Scaling
- 最近的一些思路,有精力了展开
- Oracle/PLSQL中的一个函数--NVL函数
- 增强的单据通esb插件任务调度策略及配置
- 分布式拒绝服务攻击(DDoS)原理及防范
- Oracle 中的JOIN
- 如何优化网页转化率?(上篇)
- codeforces 339C
- JS精华入门之【一】
- JScript实现将指定目录下的vc工程加到解决方案
- IT求职经验总结——面试和准备策略
- Oracle natural join(自然连接)