为了实现高可用性,微服务一般部署在多机房,只要部署到多机房就万无一失了?考虑如下问题:
1 多机房负载均衡
当服务部署在多个机房时,最简单的就是遵循用户就近访问原则,比如北方用户访问联通机房,南方用户访问电信机房。
为了实现负载均衡,还会在每个机房分别部署四层负载均衡器VIP以及七层负载均衡器Nginx。
比如来自北方用户的请求:
- 通过DNS解析到联通机房下任一VIP
- 然后通过VIP,把请求转发给联通机房下任一Nginx
- Nginx再把请求转发给联通机房下任一Tomcat容器
以实现各个机房内高并发访问下的负载均衡。
这是最理想情况,实际部署时经常会遇到:
- 某机房流量较大,但该机房服务器不足以支撑线上流量
- 某机房服务有问题,需切一部分流量到另外一个机房
因此实际部署时,有时并不能完全遵循就近访问原则,而是要根据需要调配流量,达到各个机房流量均衡。
可以通过两种方法来切换流量:
- 在DNS解析时,把一部分北方用户请求解析到电信机房的VIP反之亦然
- 在Nginx转发请求时,把一部分电信机房的Tomcat容器配置到联通机房的Nginx的upstream里或把一部分联通机房的Tomcat容器配置到电信机房的Nginx的upstream里
2 多机房数据同步
想要实现服务部署到多机房,供用户访问是有前提的,即每个机房的数据都一样,这就要求多机房间数据必须保持同步。
高并发访问的服务,数据通常都会有两层存储即缓存层和数据库层
要保证多机房的数据一致,不仅要保证数据库层的数据一致,还需要保证缓存层的数据一致,应该如何实现呢?
1.主从机房架构
以一个机房为主机房,所有写请求都只发给主机房:
- 主机房的处理机更新本机房的缓存和DB
- 其他机房的缓存也通过主机房的处理机更新
- DB通过MySQL的binlog实现数据同步
- 主从机房数据同步方案
这样做有一个很大的风险,若主机房出现问题,就没法更新缓存和DB,所以有了下个方案。
2.独立机房架构
联通和电信机房都有写请求,通过消息同步组件把各自机房的写请求同步一份给对方机房,相当于每个机房都有全量写请求。
- 每个机房的处理机接收到写请求后更新各自的缓存
- 只有一个机房会更新DB,其他机房DB通过MySQL的binlog同步
该架构的优势是任一机房异常,都不影响其它机房数据更新,因为每个机房都是全量写消息,所以每个机房可以更新自己缓存,并从DB主库同步数据。
消息同步组件是如何实现的呢?
消息同步组件是把一个机房写请求发给其它机房,实现原理如下:
- reship
把本机房的写请求分发一份给其它机房 - collector
从其它机房读取写请求,再把请求转发给本机房处理机