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>
供应宝支持各种类型的实体之间通信,实体类型称为端点类型。
目前定义的端点类型有:
///< 列: 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>