使用Redis来处理负载均衡场景下异步转同步的一种方法
背景
对一个由Java编写的提供HTTP接口服务的程序进行改造以支持负载均衡,特别是提高整个系统的可用性。该服务有一个HTTP接口,收到请求后,内部会去异步请求第三方,第三方通过HTTP回调把结果返回,而该接口需要同步返回结果,即内部做了一个异步转同步的过程。对如何实现异步转同步,可以自行搜索 Java异步转同步。
我们有一个Key来标记同一个请求和返回。该Key可以从第三方回调的参数中生成,但是却不能从该服务接口的参数中生成,需要该服务再去做一些数据库查询操作。所以如果用nginx等来做负载均衡,并不能比较简单把第三方回调的请求和该服务的接口请求分发到同一个后台服务接口上,是本次改造要解决的难点。
方法
- 用Redis做消息队列和缓存,每个服务程序监听不同的Topic;
- 服务收到请求时,把Key缓存到Redis中,该Key对应的value即为自己的Topic;
- 服务收到回调时,可先检查Key是不是自己处理的,
– 如果是,清除Redis缓存,并自行处理后续流程,同步响应原始请求;
– 如果不是,通过Key在Redis中查到的Topic,并把回调消息发到该Topic。如果查不到,可打印日志丢弃;
– 服务收到Redis消息,清除Redis缓存,并处理消息响应原始请求;
缓存需要配置超时时间,防止程序异常导致添加的Key不会被清除。
总结
可以看到该方案可以满足负载均衡分布式部署的需求,但是对于性能的提升是1+1<2的,不过能够极大的提升了系统的可用性,个人觉得还是可取的。