【原创】消息中间件主备方案选型实践
背景介绍
该消息中间件由三个子系统组成:客户端SDK、Server和控制管理中心(Admin)。我们所说的主备主要是针对Server,而Server的节点是局部有状态的,具体而言就是发布无状态,但是拉取有状态。因此,对于发布而言,由于分布式部署所以本身具备高可用性;但是对于拉取,就存在单点的可用性问题。
主备切换的关键问题
实现主备切换,需要解决两个核心问题:
- 解决主备之间状态检测、通信和决策问题。
通过心跳检测来得知互相之间的状态,一旦得知对方状态异常需要接管对方的资源继续提供服务。- 解决资源转移的问题。
通过资源共享机制或者资源同步冗余方式来解决资源转移的问题。任何一套主备切换方案都需要解决这两个基本问题。
主备切换思路
- 故障检测
- 状态和决策
- 资源切换
方案比较
- Zookeeper
如果使用Zookeeper,每组主备Server需要部署Zookeeper,作为Zookeeper Server;SDK作为Zookeeper Client,建立和主备Server的连接,并且监控Zookeeper Server的事件。如果发生不可用,则可以通过监听到的事件,来触发主备切换。那么其实,我们使用Zookeeper只解决了第一个问题。至于第二个问题,如果是Single模式,资源转移可以通过DB中间件来共享资源解决;如果是Master-Slave模式,则需要Server自身的开发来解决。
- 负载均衡软件(LVS、HAProxy、Nginx)+ 高可用软件(Keepalived、Heartbeat)
这种方案是用于负载均衡Server的高可用,Keepalived和Heartbeat也只是解决了第一个问题;第二个问题是负载均衡软件来解决。
自研
自研方案一- Admin作为观察者,建立和每一个主备server的的连接,并通过心跳检测监控连接状态。Admin管理每组主备的关系和其激活状态。需要考虑Admin本身的高可用性。
- Server的备机启动项区别于主机,并且只提供拉取服务,其他服务拒绝。另外,备机在恢复时,需要先停止服务,然后同步消费状态;Server的主机在恢复时,首先要从Admin拉取消费状态信息,并更新到DB。
- SDK定时从飞鸽Admin拉取飞鸽Server的信息,如果发现Slave被激活,则建立同Slave的连接,剔除Master连接;如果发现Master被激活,则建立同Master的连接,待连接建立成功后,再剔除Slave连接。
主备切换序列图:
主备切换序列图:
自研方案二
- 在SDK和Server之间加一个飞鸽Proxy,其负责主备切换,并且负责路由,这样可以轻量化SDK。因为目前server的连接是带了鉴权状态的,因此就需要将鉴权功能上移到proxy。或者考虑是否可以去除连接的状态?连接是否有状态会影响proxy本身的高可用方案,如果连接无状态,直接采用F5即可;如果有状态,则proxy本身的高可用方案又是个难题了。
- Proxy保持这和Master和Slave的长连接,并且做心跳检测,检测达到切换条件,则触发切换动作。
- Proxy方案对现有飞鸽方案的冲击比较大,改动面比较多。