团队中前些天遇到这样一个问题,比较有意思也比较典型,我给出方案后团队成员实施出来,最终问题得以解决。 > 一个智能终端连接到Netty服务保持会话,在异步完成某项操作后回调回来需要通过会话通知终端,终端再根据通知做相应业务处理, > 在部署单节点的情况下是OK的,但是系统整体由于要做HA,部署多节点后就会出现问题: 并不能保证该回调请求一定负载到终端保持会话的节点。
如何解决这个问题?这里跟大家分享一种类似场景的通用解决方案,以下是流程图:
< Async Callback Model in Cluster Architecture >
(D) Broadcast to all nodes
+-----------------------------------------------------------------------+
v |
+ - - - - - - - - - +
' Cluster: '
' '
+--------+ (A) Connect ' +---------------+ ' (B) Async call +---------------+ (C) Callback +----+
| | -------------> ' | Server Node A | ' ----------------> | | --------------> | |
| | ' +---------------+ ' | | | |
| | ' ' | | | |
| | + - - - - - - - - - + | | | |
| | (E) Notify : | | | |
| | <................... | | | |
| | | | | |
| Client | + - - - - - - - - - + | Remote Server | | MQ |
| | ' ' | | | |
| | ' +---------------+ ' | | | |
| | ' | Server Node B | ' | | | |
| | ' +---------------+ ' | | | |
| | ' +---------------+ ' | | | |
| | ' | Server Node C | ' | | | |
| | ' +---------------+ ' | | | |
| | ' ' | | | |
+--------+ + - - - - - - - - - + +---------------+ +----+
- (A) 客户端向
Server Node A
发起请求并保持会话。 - (B) 异步向
Remote Server
发起请求处理业务。 - ©
Remote Server
处理完成后回调将消息放入消息队列。 - (D) MQ将回调消息以广播形式广播到集群各个节点。
- (E) 各节点收到广播消息后,能取到对应客户端会话则处理,否则丢弃消息。
注:本案例中的客户端是以TCP连接至服务端,在HTTP服务中如果处理类似场景可以使用Java8中的CompletableFuture
来实现。
- EOF -