服务器主备切换
主备环境总览
主备环境相对于单机模式,旨在主机服务停止后,备机能自动地继续提供服务
主备机数据通过UFTDB内存表进行实时同步,而会话信息没有进行同步,客户端为实现在主机宕机时,能够自动连接备机,实现无感切换(技术层面并不能实现真的无感), 无需重新登录,因此需要将主机的会话信息也加入到UFTDB内存表,实时同步到备机。
主备环境的搭建
- 首先,准备两个机器,然后修改配置文件,
- 将主备机的核心业务节点mt注册到zk的指定目录,谁先注册成功,谁成为主机。
- 注意这里容易出现
双主的情况- 目录的路径要一样的
- zk为非集群模式,如果填了多个zk服务器地址,会导致节点信息不在一个集群,也就不会在同一级zk目录了
- 目前不支持docker主备环境,设置nfs挂载以同步主备机器的UFT数据。
- 如果主机或备机搭建在Nat内网,需要进行端口映射。参考链接:nfs穿透NAT挂载
- 注意区分udp和tcp端口
主备机启动与工作流程
讲解主备机器的工作流程前,需要说明以下几点:
- 环境的运行模式是总线模式,通过
OSPF协议进行路由 - 主备模式采用热备模式,也就是主机和备机的所有进程都是正常启动的,只是请求都会路由到主机;
- 主机会加载外部投资的数据,这部分的数据是十分庞大的,而备机只会在成为主机的时候才加载,这导致在主备切换时,客户端会有较大的切换时延
- 之所以备机不加载外部投资系统数据,是因为数据更新时,备机需要接收外部主推就行数据处理,而这并不是必要的
- 服务启动:
两台服务器互为主备,先启动的机器在zk上注册成功后,当备机在注册时,发现目录已注册,将按备机模式启动,寻找同名节点,发送消息通知主机,主机回包确认
-
数据同步(以会话信息为例):
- 客户端在登录时,将内存中的数据存一份存入UFTDB内存表,UFTDB插件将会话信息通过redo文件落到Oracle数据库
- NFS由于挂载了主机和备机的redo目录,会将主机的redo文件实时同步到备机
- 主机和备机连接同一个oracle数据库,防止出现不同的数据
-
主备切换:
- zk会在mt节点的注册设置watcher,当主机宕机后,会通知备机,备机向主机发送三次ping消息,如果没有回应,就启动为主机
- 备机切主会做两件事:一是路由节点会将请求分发到新主机,二是会加载外部投资系统数据
-
心跳机制:
- 客户端通过后台的session向宽途发送心跳,后台通过session或user_token向投资系统发送心跳.
- 前端调用
心跳接口:- 为实现主备机的无感切换,后台向客户端屏蔽主备机的差异,会将客户端的心跳包路由到主机的mt节点,正常情况下主机返回
错误号为0的应答包。 - 当主机的mt服务停止后,客户端收到心跳
应答包为空,将停止发送心跳. - 在备机尝试切换成主机的过程中,客户端的心跳应答包的错误号为
308000000,当备机成功切换为主机后,心跳应答包中的错误号为0.
- 为实现主备机的无感切换,后台向客户端屏蔽主备机的差异,会将客户端的心跳包路由到主机的mt节点,正常情况下主机返回
- 定时任务
心跳检查接口:- 后台每隔10s检查一次,清理掉120s没有心跳的session
客户端登陆流程
宽途为支持主备模式的session信息同步,新建了UFT内存表tstp_session,服务器内存中的session信息会同步保存到内存表。据此,宽途的登录流程做出如下修改:
- 单机模式:
- 服务器清流启动(该模式会清空UFT内存表数据),客户端需重新登录
- 服务器带流启动,会将内存表中的session信息写到内存,客户端重新连接即可
- 主备模式:
根据主备模式的心跳机制,客户端若未收到心跳应答,将弹窗并停止心跳;
然后点击重连,可能返回308000000的错误号,此时正在进行主备切换;
稍等后再次点击重连,若返回的错误号为0,则重连成功。
常见的问题
- 在主机mt节点停止后,备机启动时状态报错:
这是由于备机同步主机数据发生错误,`df -h`检查挂载目录是否正确
2. 主备机突然连接不上本地数据库:
可能是电脑的防火墙或者服务器节点的防火墙被打开了(公司的电脑会自动开启防火墙)
3. 服务单机模式下,启动后提示ALGO Standby load successfully
一般都是由于UFT数据加载出错,比如hstodb插件涉及的so加载出错、workspace目录下UFT的配置文件有问题
4. 双主现场
- zk为非集群模式,且填了多个zk服务器地址
5. 在主切备的前2秒,备机还未标识成主机,所以一开始点击重新连接,会无任何反应
扩展
-
核心管理功能号(GetMSFuncList)提供注册的 功能号列表给微服务插件注册,只有主机会向微服务注册这些功能号,备机不会注册。发生 主备切换,备机切成主机后,就会向微服务插件注册功能号列表。
-
目前微服务调用支持同步调用和异步调用。
- 同步调用的宏为开发工具上的[同步调用]宏; lpIUFTContext->nErrorNo = lpIUFTContext->ParalSyncCallService(lpESBMsg, NULL, lpIUFTContext->GetSyncTimeOut());
- 指定微服务的被调用节点的GSV:Group、Service、Version
- 异步调用的宏为开发工具上的[消息主推]宏。
- 如果主备机在docker内,可以不通过nfs挂载,而通过docker数据卷进行挂载。(本地测试下,单说utddata同步是没问题的)