SEMQ

  1.SEMQ:
    SEMQ是分布式的消息队列。作为供应宝系统的传输层,每个供应宝服务端节点都有一个或多个SEMQ单元,每个SEMQ单元由一个任务和一或多个存储组成,另外提供一组访问接口。
    平台支持多实例,多存储。
    私有本地服务器实现为单实例单存储,可以满足一家机构应用的需要.
    虚拟服务器将来也可能需要支持多实例多存储,以均衡负载提高性能。
    对单实例,单存储实例的服务器,semq_id=1,semq_db_id=1.
 
    这里不严格区分SEMQ和SEMQ单元。
 
  2.UMX分层
    数据传输分2个层次:应用层,传输层(包括传输属性,路由,会话属性).
    传输属性:是否要求有序,可靠,决定网络层采用的协议(TCP或者UDP)
    路由:是否支持存储转发,决定到目标不可达时的行为,是否持久化存储后待目标上线后再发送;消息是否需要节点间确认,确认所需要的定位键
    会话属性:是否需要端-端的确认,确认所需要的定位键;是否加密
    应用层只表现和应用有关的内容。签名归属于应用层功能,传输层的数据签名意义不大。
    UMX增加一个包层属性LAYER_MASK:区分应用包(0)还是传输层包(1)。
    传输层的引入是是对分布式应用的扩展。对于基于hotfox的简单的C/S应用,传输层不是必须的。
   
    2.1传输层协议(UMX-T)格式:
    .是否可靠:@Reliable=1|0 默认1
    .存储转发:@SaveFwd=1|2|3
    .是否送达确认:@Ack2=1|0
    .应用关联键: @AppKey(应用自定义:由域,数据类型,子类型,键4个项组成)
    .加密属性:@Encrypt=1|0 是否加密,@SessionKey 会话密钥。用会话密钥加密应用数据,会话密钥用接收方公钥加密,根据端点可确定证书
    .源定位键:@LK0(节点类型,节点ID,节点SEMQ ID,节点SEMQ存储ID,消息记录ID)
    .平台定位键:@LK1(节点SEMQ ID,节点SEMQ存储ID,消息记录ID)
    .应用层(@AppData):如果@Encrypt=1,则该包用@SessionKey已用加密
    源定位键,平台定位键相当于路由表,记录消息的传递路径.
   
    传输层UMX的源地址为发送时节点的地址,假设消息M从A发送给B,在平台保存后,由平台转发时,消息的源地址是平台而不是A,但应用层的消息还是A。

   2.2传输属性   
    (1)存储转发属性:
    .目标不在线时丢弃(1)
    .目标不在线时存储(2)
    .必须确保发送出去(3):对于必须送达的消息,要写入待发送消息队列,以便确认,询问和重发
      对于平台,如果目标方在线,为提高效率,直接转发。确认过程在源和目标方之间进行,平台不参与。
    存储转发属性代替了原来的可靠等级。
    确保发送出去要利用传输确认和询问机制来保证,原来的是否确认合并到此属性中了.
   
    (2)送达确认属性:
    通信端点之间消息送达的确认,和原来的是否确认含义不同。如果通信路径只有2个节点,则可合并传输确认和送达确认。
    相对于送达确认,必须确保送出的确认称为“传输确认”。
    或者把送达确认称为端-端确认,把传输过程其它节点之间的确认称为传输确认。
    如果端-端是直接通信的,则端-端确认和传输确认是等价的。

  3.SEMQ机制
    SEMQ需要实现包括消息存储,发送,询问,重发,确认,确认的确认,清理的若干机制。
   
    存储到SEMQ的消息有以下情况:
    .要求目标不在线时存储的消息,目标没在线时
    .必须确保发送出去的消息的发送源
    .需要送达确认的消息的发送源
     
    发送状态(SS_STATUS): SS_INIT(初始,未发送),SS_SENT(已发送),SS_ACK(已确认),SS_ACK2(送达确认)
    确认状态(AS_STATUS):SS_INIT(初始,未确认),SS_ACK(已确认)
    3.1应用示例:
    以单据传输为例,假设从A机构(机构ID:10008)通过平台发送给B机构(机构ID:56001)发送S0001号订单。
    。本地服务器A:
    --抽取单据后写入本地SEMQ存储的记录,消息用UMX-T协议表示(是否可靠(1),存储转发(3),是否送达确认(1),固定投递(1),加密)。源和目标分别为A和B。
    --如果本地服务器已连接平台,则读取发送状态(SS_STATUS)为SS_INIT的记录,准备发送
    --解析UMX-T消息,根据传输控制信息选择通道
    --发送前在UMX-T协议包中设置源定位键
    --执行发送,激发数据已发送事件(应用层可以对此事件进行响应),修改SS_STATUS=SS_SENT
   
    发送后,如果A:
    (1)接收到Ack-Fwd:
    修改发送状态为SS_ACK_FWD.设置询问时间为当前时间。
    对此状态的消息,以后直接向目标询问是否接收到。
    必须等待B返回的询问结果,A对结果进行处理。如果B接收到,则表示已经送达(SS_ACK2);否则,执行重发(修改发送状态为SS_INIT)
   
    (2)接收到Ack_Save:
    修改发送状态为SS_ACK。设置询问时间为当前时间。
    基于可靠的传输机制,消息已到达平台,平台必须保证B会接收到(除非B永远不上线)---如果数据长期未发送到B,这种情况需要通过工具发现,由人工干预。
    预期应该接收到来自B的Ack2消息,表示B已经接收。
    如果没有接收到来自B的Ack2的消息,启动询问机制
     
    (3)没有接收到任何确认:
    向目标询问。
  
    (4)接收到来自B的Inquiry-Resp(询问响应)   
    如果对方已接收,则修改SS_STATUS=SS_ACK2;否则,修改SS_STATUS=SS_INIT,使重发。
   
    。平台
    平台接收消息后,检查目标是否在线。
    如果目标在线,则转发,返回A一个已经转发的确认消息(Ack-Fwd)
    如果目标不在线,则保存,返回A一个已经存储的确认消息(Ack-Save)
    对于存储的消息,当目标上线后发送,发送前设置平台定位键。
   
    如果接收到B的Ack,表示B已经接收,修改SS_STATUS=SS_ACK,同时返回ReAck给B,表示已经收到B的确认。
   
    。本地服务器B
    保存到待确认消息表中,把UMX-T中的定位键分别写入,并分别返回确认,对平台返回Ack,对发送方返回Ack2。平台和发送方的确认状态为AS_INIT(初始)。
    如果接收到平台的ReAck,则修改待确认消息平台确认状态(P_ACK_STATUS)为“已确认”(AS_ACK);
    如果接收到A的ReAck2消息,则修改发送方确认状态(S_ACK_STATUS)为AS_ACK;
   
  3.2询问机制
    询问的时机:目标在线,离上次询问时间超过一定时间间隔(单位:秒),该时间可配置(如设置为15秒)
    询问的内容:询问的标的用(端点类型,端点ID,本地SEMQ ID,本地SEMQ DB ID,object_id)唯一确定。其中端点类型,端点ID可以省略(消息包头包含了此信息)
    询问请求处理成功时,询问的结果有2种:对方已收到或者对方未收到。
    如果对方已收到,则修改发送状态为SS_ACK2,同时返回ReAck2给询问发起方。
    否则,启动重发。
    有一种情况,超过了设置的询问间隔,但B才上线,源消息和A发出的询问消息到达B和处理的时序不能保证,导致可能做不必要的重发,但几率较低。
    而且,应用层要能够保证处理重发的消息不会产生错误的逻辑,如一张订单发送两次仍然是一张订单。
      
  3.3消息清理
    解决及时清理SEMQ中存储已经没有作用的数据,前提是确保消息到达目标。
    SEMQ存储的数据有(1)待发送消息队列 (2)待确认消息队列,只有本地服务器才有待确认消息队列.
    对于平台,可以删除待发送消息队列的状态为SS_ACK的记录,消息已成功送达。即使目标方没有接收到平台返回的ReAck,删除也是安全的。
    对于本地服务器,
    待发送消息队列:可以删除(SS_STATUS=SS_ACK&&送达确认=0)||(SS_STATUS=SS_ACK2&&送达确认=1)的记录
    待确认消息队列:可以删除(P_ACK_STATUS=AS_ACK&&S_ACK_STATUS=AS_ACK)的记录,如果对应的需要确认的标志为1的话。
    如果本地服务器没有接收到ReAck2/ReAck,通过询问机制确定。
    被询问一方有3种结果:以向平台询问为例
    (1)发送状态已经是SS_ACK
    (2)记录已经不存在:已经确认并删除
    (3)发送状态为SS_SENT:这表示平台发送,询问方接收后返回的确认没有被平台接收到,且平台还未发起询问
    对于前2种情况,询问方可以修改AS_STATUS为AS_ACK.
    对于后者,被询问方可以直接把发送状态修改为SS_ACK.询问方可以删除
   
    如果同时有对平台和发送方的确认需求,则要同时满足2个确认状态条件

  4.  实现
   待发送消息队列:tb_0031
   待确认消息队列: tb_0030
  4.1本地服务器实现:
    。询问机制:
    ---向平台发送Inquiry
      .如果SS_STATUS=SS_SENT且离上次询问时间(初始时询问时间等于发送时间)间隔超过指定时间
    ---向目标发送Inquiry
      .如果SS_STATUS=SS_ACK_FWD或者SS_ACK且离上次询问时间间隔超过指定时间
    。消息处理:
       ReAck2:接收到发送方对Ack2的确认
       Ack2:接收到目标方接收到消息的确认
       Inquiry-Resp:处理询问结果
       Inquiry:响应对方询问
       Ack-Fwd:平台已经转发
       Ack-Save:平台已经保存
    。清理:
  
 4.2 平台服务器实现:
    。消息处理:
      Ack: 接收方确认,返回ReAck
      Inquiry-Resp:询问结果处理
    。询问机制:向目标询问
   
   
  4.3 消息定义:
   4.3.1 Ack/ReAck/Ack2/ReAck2/Ack-Fwd/Ack-Save
    采用810描述。
    Ack/Ack2:对应810-Indication
    ReAck/ReAck2:对应810-Response.
    通过ack_flag区分Ack和Ack2,以及ReAck,ReAck2.
   
    Ack/ReAck/Ack-Fwd/Ack-Save传输控制:存储转发(3),不需要送达确认
    Ack2/ReAck2传输控制:存储转发(3),不需要送达确认
    通信对象
    。本地服务器-平台:
    。平台-本地服务器
    。本地服务器-本地服务器(Ack2/ReAck2)
    参数:
    src_semq_id: 源SEMQ实例ID,默认1
    src_semq_db_id:源SEMQ存储实例ID,默认1
    src_ref_id: 源SEMQ记录编号
    源是指发起确认的一方。
   
    ///< 本地服务器端待确认消息记录定位信息
    dest_semq_id:默认1
    dest_semq_db_id:默认1
    dest_ref_id:待确认消息表的object_id
   
    ack_flag: 1-与平台相关的确认 2-送达确认 (保留,可以从消息头确定来源)
    app_key:业务键,可以为空,在返回810-Response原样返回,本地服务器可以根据此键值定位业务记录,修改发送状态或者通知应用程序。
   flag: 1- 平台已转发 2-平台已存储 (只出现在平台返回的Ack-Fwd,Ack_Save消息中)
   
    返回:(810-Response)
    src_semq_id: 源SEMQ实例ID,默认1
    src_semq_db_id:源SEMQ存储实例ID,默认1
    src_ref_id: 源SEMQ记录编号
    源是指发起确认的一方。
   
    dest_semq_id:默认1
    dest_semq_db_id:默认1
    dest_ref_id:待确认消息表的object_id
  
     ack_flag: 1-与平台相关的确认 2-送达确认
     app_key:
   
    平台可以根据semq_id,semq_db_id,ref_id确定是哪个存储表的哪条记录,修改该记录的状态为SS_ACK。
    
    4.3.3 Inquiry/Inquiry-Resp:
    用809协议描述,取代原来的817.
    通信对象:
    .本地--平台
    .本地--目标本地:
    .平台--目标本地

  参数:
  .semq_id:默认1
  .semq_db_id:默认1
  .ref_id:
  .flag: 1-来自平台的询问 2-来自对方的询问 (也可以从消息头确定消息的来源)
  返回(809-Confirmation):
  .semq_id:
  .semq_db_id:
  .ref_id:
  .result: 1-已接收 0-未接收
   
 5.其它
  5.1兼容性:
    .存储在SEMQ中的未处理的数据
    .岁宝:与其他用户采用的机制不同,必须修改代码(历史原因造成)

  5.2已知缺陷:
    .目前不支持直接连接和P2P
    .部分待办事宜的消息应该属于SEMQ范围:实际上是转发给用户的消息
      同一机构内A用户向B用户发送离线消息时,应该保存在SEMQ中,而不是待办事宜(tb_0032)。待办事宜是应用层概念。
   .目前本地tb_0031存储的是发往机构外部(包括平台和其它机构和用户的消息,来自外部给本地用户或者本机构用户之间的消息没有保存在tb_0031中。逻辑不统一。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值