平台SEMQ静态路由实现

来源:互联网 发布:药物靶点数据库 编辑:程序博客网 时间:2024/05/15 22:06
1.引入
供应宝支持各种类型的实体之间通信,实体类型称为端点类型。
目前定义的端点类型有:
///< 列: ID 宏 说明
.1     PT_ORG    机构
.2     PT_ORG_USER    机构用户(客户端)
.3     PT_CENTRAL    平台
.4    PT_SERVER    (本地)服务器
.5    PT_PSERVER    平台服务器ID
.6    PT_DATA_NODE    数据节点
.7        保留(原作为平台登录用户)
.8    PT_PAPP    平台应用(如AS网关)
.9    PT_PUSER    平台登录用户(如平台管理员)
.11    PT_LSS    本地分离服务器

标记有目标端点信息的消息,如何选择传输路径,需要在目标端点和通信节点进行映射(称为端点地址映射)。
平台与通信节点完成具体的传输过程。

动态路由在传输开始前确定通信节点。能自动适应端点迁移。
缺点主要在效率方面:
(1).需要查表,有开销
(2).端点的实例数越大,批处理效率越差,开销越大:
  如某个服务器注册后,平台要把属于该服务器的消息推送出去,端点实例包括该服务器,该服务器上的每个机构,每个机构的每个用户。
  基于端点实例进行查询无疑效率非常差。
  select * from tb_0031 where 端点实例 in (符合条件的端点实例表);
  列表的长度没有限制,可以见到数千规模。更大规模的情况还只能分段处理。

  这个过程会非常耗数据库资源,也非常缓慢。尤其是应用规模和数据到达一定数量级时。(这要求系统及时清理)
 
采用静态路由后,在写入SEMQ表时,已经确定传输(服务器)地址。
  上述查询可以改变为:
  select * from tb_0031 where 传输地址 in (符合条件的传输地址列表);
  传输节点的数量要远小于应用的端点实例数,其规模也相对稳定。
  现有应用最坏的情况是一个RSP服务器向该RSP所有注册的本地服务器发送消息。
 
没有显式的独立部署的传输节点,传输节点重叠在本地服务器内部的,传输地址就是服务器编号。

2.采用静态路由对系统的影响

优点是解决动态路由2种情形下的效率问题:
(1)服务器注册成功后,平台推送该服务器上机构和用户的消息。
(2)在确认过程中,每个平台RSP(Real Server)需要对注册到其上的本地服务器待确认的消息执行问询,这些消息包括PT_ORG,PT_ORG_USER,PT_SERVER类型的消息.(未来可能扩展到PT_DATA_NODE,PT_LSS类型)
2种操作需要执行类似下面的查询:
select * from tb_0031 where (dest_type=1 and dest_id in (该服务器上的机构列表)) or (dest_type=2 and ...) ...
对于(2),列表项可能达到几千个机构。
采用静态路由可以避免这种情况。

缺点是当端点迁移时,需要对SEMQ记录进行传输地址的重置。(如托管机构迁移)
出现此情况时手工执行脚本。(待程序实现)


3.实现
实现重点:
.外部指定地址映射方法:避免SEMQ与映射需要的资源耦合.
.实现地址映射函数:
对于机构和机构用户,确定分配给该机构的服务器,作为传输地址。
.在写入SEMQ时,根据应用端点地址信息确定传输地址。

(1)SEMQ表增加传输地址
消息队列表增加svr_id字段表示消息的传输地址:(以下为MySQL脚本)
alter table tb_0031 add svr_id int default 0 COMMENT '服务器ID';

(2)初始化消息传输地址信息
 升级时对SEMQ表的未完成的记录进行处理,初始化传输地址信息。
 需要对每个SEMQ实例执行初始化(目前配置了4个实例)
 初始化过程在rto中完成,为此提供一个专用rto版本(rto_0),此版本是一次性工具。

(3)代码修改:
 (3.1)rto插件:
    ///< 地址映射函数:根据目标端点信息确定传输节点地址
    typedef int (*RouteFunc)(int dest_type,unsigned long dest_id,unsigned long &comm_id);   
 
  CSEMQ增加静态成员,记录端点地址映射函数指针
      static RouteFunc route_func_;
  rto初始化时设置.
  CSEMQ::route_func_ = ::RouteFuncProc;
  RouteFuncProc实现在rto中,需要访问mdb(机构,服务器信息)。
 
  修改CSEMQ::Save
  执行地址映射函数,获取传输地址
    if ((*route_func_)(qe->dest_type_,qe->dest_id_,qe->svr_id_)) {
        return -1;
    th->BindField("svr_id",(char**)&qe->svr_id_,sizeof(qe->svr_id_));
        
    IDAP增加接口方法并实现:
        virtual int GetSvrByRSP(CQQ_RSPID rsp_id,vector<CQQ_SERVERID> svr_list) = 0; ///< 取指定RSP上的所有服务器ID        
    该函数以最小的开销获取必要的信息.
    重量级的操作对应下面的方法:
        virtual int GetSvrByRSP(CQQ_RSPID rsp_id,CAutoVector2<ISERVERINFO*> &svr_list) = 0; ///< 取指定RSP上的所有服务器
    
  (3.2)AS2GW修改
    AS2GW是独立部署的,程序直接面向SEMQ表操作。(这种实现影响了SEMQ的封装性,也是额外有此步骤的原因)
  对AS2消息队列进行类似处理.
  区别是:
  .地址映射未采用回调,直接在AS2GW中实现
  .访问平台数据库(非mdb),获取机构的服务器编号信息
      

4.升级注意事项
(1)修改4个SEMQ实例的表结构:
ALTER TABLE tb_0031 ADD svr_id INT DEFAULT 0 COMMENT '服务器ID';
ALTER TABLE tb_0031_1 ADD svr_id INT DEFAULT 0 COMMENT '服务器ID';

ALTER TABLE tb_0031 ADD svr_id INT DEFAULT 0;
ALTER TABLE tb_as2_0031 ADD svr_id INT DEFAULT 0;

(2)rto有2个版本:rto_0.dll,rto.dll。
   rto_0.dll是执行传输地址初始化的版本.rto.dll是正式版本.
   
   初始化传输地址在文件更新后立即执行.
   .把rto_0.dll更名为rto.dll
   .修改hotfox.conf只加载rto
   .启动服务器
   .等待初始化完成.(注意控制台没有"初始化失败"的错误提示)
   .执行成功后,换回正式的rto.dll
   .修改hotfox.conf,恢复其它插件的加载。

(3)AS2GW.conf
    增加配置:<dbc>为平台数据库连接名
    <dbc>laton</dbc>




原创粉丝点击