UMX-T时序控制

1.目的:
以添加合作机构,解除合作机构操作为例说明需要进行时序控制的情形:

用户执行了以下2个顺序操作:
(1).A添加B
(2).A删除B
在分布式的并行系统中,在传输和调度处理过程中如果没有时序控制则其结果不可预料。
其结果可能是A-B的合作关系被记录或者没有记录。系统和用户都没有得到预期的结果。
处理时序性是目标结果,要得到正确的结果,传输的时序需要同时得到保证。
---不排除存在传输无序,但处理能保证有序的向传输效率倾斜的可选方案。

 

2.应用
还是以上面的示例说明,在采用时序控制后,以下操作序列:
(1).A添加B
(2).A删除B
(3).A添加C
则(1,2)需要保证顺序,而不需要包含(3).即(1,2)可以由任务T1处理,而(3)可以由其它任务处理。
这样即保证了时序性,也没有降低并行效率。

 

 

3.定义

在UMX-T中增加时序控制属性。
.SEQ_CONTROL: 时序控制标志 1/0 1-需要时序控制 0-不需要时序控制 参数@SeqCtrl 默认:0
.SEQ_CONTROL_KEY:时序控制键,当SEQ_CONTROL=1时有效.参数@SeqCtrlKey.
.时序控制键:域,数据类型,子类型,控制子键
域为扩展保留,支持客户化开发和第三方开发。默认为0,表示供应宝标准域。
数据类型,子类型和UMX-T的应用关联键中的定义类似,可参考但独立定义。
两者不能完全相同是因为各自的目的不同,应用关联键是作为传输层和应用层的连接对象。
而时序控制是在传输层内部使用,在并行系统中保证消息的时序。

控制子键根据不同的数据类型分别定义。
以用户上下线为例,假设100081001用户上线,时序控制键为:0,30,10,100081001。

对于单据传输,可以顺序跟踪一张单据的多次操作,保证应用语义的正确。其时序控制键为:0,200,1050,SP0001。分别表示供应宝标准域,单据数据,订单,单据编号为SP0001.

具体编码见<<SES全局资源分配规则>>中的“时序控制键编码”。


4.时序控制的实现策略
(1)数据接收方:根据消息的时序控制键把消息分发给特定的任务。

(2)数据发送方:如当存在多个SEMQ发送任务时
从SEMQ DB读取消息时,根据时序控制键分派给特定的任务。

.对于不需要时序控制的消息由专门的任务处理,线程个数为原来hotfox.conf的<scheduler><thread>指定。
.处理时序消息的任务数:同上(以后考虑单独配置)

 

分发算法可以采用:
.基于键值的分发:把键值转换为一个数值,按任务个数取模
.其它算法:如把任务消息队列的元素数量和权值考虑进来


5.实现

5.1 hotfox
  增加HTX_Dispatcher类,由该类管理插件/消息调度器,包括:
  .HTX_Scheduler *schedulers_; ///< 多个处理有时序控制消息的调度器,数量可配置
 .HTX_Scheduler def_scheduler_; ///< 默认消息处理任务(处理无时序要求的消息)
 .HTX_Scheduler control_scheduler_; ///< 控制消息调度器
 

 
5.2UMX-T:

增加时序控制属性并实现.

 bool seq_ctrl_flag_; ///< 时序控制标志
 string seq_ctrl_key_; ///< 时序控制键
public:
 void SetSeqControl(bool seq_ctrl_flag);
 void SetSeqControlKey(const char *seq_ctrl_key);
 const char* GetSeqControlKey();
 unsigned long HashSeqControlKey(); ///< 把时序控制键映射为一个数值

 

5.3 SEMQ

  修改CSEMQ基类,使本地服务器和平台支持消息的时序控制。

  CSEMQ的send_task_,由多线程单任务变为多个动态单线程任务.
  SEMQ DB增加2个字段:是否做时序控制,时序控制键.
  CSEMQ在GetData后,根据时序控制属性,选择一个任务处理.
 
5.4调度算法
 if (msg->GetMsgAttr()&CONTROL_MASK) { ///< 如果是控制消息,则进入控制消息任务队列
  return control_scheduler_.enqueue(wm);
 }
 else {
  ///< 选择一个处理任务(调度插件处理)
  HTX_Scheduler *scheduler = 0;
  if (!msg->IsSeqCtrl()) {
   scheduler = &def_scheduler_;
  }
  else {
   unsigned long seq_key = msg->HashSeqControlKey();
   scheduler = &schedulers_[seq_key%this->seq_task_num_];
  }
  scheduler->enqueue(wm);
 }

 

6.使用示例:

以平台检测到连接实体断开采用时序控制为例,说明如何修改。

下面代码的兰色标记的部分为修改部分:

int CBRSP::handle_input(HTX_HANDLE fd, HTX_Reactor_Mask masks,void *arg,Sock_Peer_Base *entity) {
   CMsg *msg = new CMsg;
   CUMXT *tmsg = CUMXT::New(msg);
   string sc_key;
   if (client_type==CLIENT_TYPE_USER) {
    sc_key = LogMsg("%d,%d,%d,%d",this->GetDomain(),30,10,ulUserId);
   }
   else { /// client_type==CLIENT_TYPE_SERVER
    sc_key = LogMsg("%d,%d,%d,%d",this->GetDomain(),30,15,server->GetServerID());
   }
   tmsg->SetSeqControlKey(sc_key.c_str());

   CWrappedMsg<> *pwm = new CWrappedMsg<>;
   pwm->msg = tmsg;
   pwm->SetFlag(CWrappedMsg<>::ML_FAKE);
   ...
}

 

对于客户端,对于登录消息,以UMX-T传输,参考上述形式指定时序控制键。

这同样适用于单据传输,IM,多人会话等功能。不再需要应用层来处理时序问题。

 

7.备忘

7.1其它方案
服务端集中配置,使用和应用关联键相同的数据分类方法,服务端配置时序控制规则。

时序控制规则用来规定哪些类型的数据是需要在一个时序上控制的。

如服务端可以把(30,505),(30,506)配置为需要进行时序控制的组,如果控制子键相同,则进行时序控制。
7.2暂时未实现SEMQ的部分

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值