微服务多机房部署

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
应用型负载均衡 ALB,每月750个小时 15LCU
网络型负载均衡 NLB,每月750个小时 15LCU
简介: 【2月更文挑战第13天】微服务一般要部署在多个机房,保证有一个机房因为各种不可抗力因素导致不可用时,可以把流量切换到其他可用机房来避免故障。

为了实现高可用性,微服务一般要部署在多个机房,保证有一个机房因为各种不可抗力因素导致不可用时,可以把流量切换到其他可用机房来避免故障。


多机房负载均衡

当服务部署在多个机房时,最简单的就是遵循用户就近访问的原则,比如北方用户访问联通机房,南方用户访问电信机房。服务也是同时部署在联通和电信机房,访问时根据用户访问的 IP,通过 DNS 解析到不同的机房,如果是北方用户就访问联通机房,南方用户就访问电信机房。并且为了实现负载均衡,还会在每个机房分别部署四层负载均衡器 VIP 以及七层负载均衡器 Nginx。比如来自北方用户的请求通过 DNS 解析到联通机房下任意一个 VIP,然后通过 VIP 把请求转发给联通机房下任意一个 Nginx,Nginx 再把请求转发给联通机房下任意一个 Tomcat 容器,通过这种方式来实现各个机房内高并发访问下的负载均衡。

image.png

当然这是最理想的情况,在实际部署时经常会遇到下面的情况:

  • 某个机房的流量比较大,但是该机房的服务器规模有限并不足以支撑线上流量。
  • 某个机房服务有问题,需要切一部分流量到另外一个机房。


因此在实际部署时,有时候并不能完全遵循就近访问的原则,而是要根据需要调配流量,达到各个机房流量均衡的目的。在实践中可以通过两种方法来切换流量:一种是在 DNS 解析时,把一部分北方用户的请求解析到电信机房的 VIP 或者把一部分南方用户的请求解析到联通机房的 VIP;另一种是在 Nginx 转发请求时,把一部分电信机房的 Tomcat 容器配置到联通机房的 Nginx 的 upstream 里或者把一部分联通机房的 Tomcat 容器配置到电信机房的 Nginx 的 upstream 里。这两种方法的示意你可以看下面这张图。

image.png

多机房数据同步

想要实现服务部署到多机房供用户访问是有前提的,这个前提是每个机房的数据都是一样的,用户访问哪个机房都可以获取到一样的数据,这就要求多个机房之间的数据必须保持同步。数据通常都会有两层存储即缓存层和数据库层。缓存层是为了存储用户经常访问的数据,尤其是在高并发访问下可以用缓存 cache 住绝大多数用户请求,减少对数据库层的压力,这是因为数据库层要直接访问磁盘,相比缓存层直接访问内存来说,响应要慢得多。

image.png

要保证多个机房的数据一致,不仅要保证数据库层的数据一致,还需要保证缓存层的数据一致,应该如何实现呢?

1)主从机房架构

主从机房架构是以一个机房为主机房,所有的写请求都只发给主机房的处理机,由主机房的处理机来更新本机房的缓存和数据库,其他机房的缓存也通过主机房的处理机来更新,而数据库则通过 MySQL 的 binlog 同步机制的方式实现数据同步。

image.png

2)独立机房架构

这种架构的数据同步方案联通和电信机房都有写请求,并通过一个叫 WMB 的消息同步组件把各自机房的写请求同步一份给对方机房,这样的话相当于每个机房都有全量的写请求。每个机房的处理机接收到写请求后更新各自机房的缓存,只有一个机房会更新数据库,其他机房的数据库通过 MySQL 的 binlog 同步机制实现数据同步。

image.png

独立机房架构相比于主从机房架构的优势在于任意一个机房出现问题,都不影响别的机房的数据更新,因为每个机房的写消息都是全量的,所以每个机房可以更新自己的缓存,并从数据库主库同步数据。其实独立机房架构的关键点在于 WMB 消息同步组件,它可以把各个机房之间的写请求进行同步。


WMB 消息同步组件的功能就是把一个机房的写请求发给另外一个机房,它的实现原理可以用下面这张图来描述,分为两个部分:

  • reship,负责把本机房的写请求分发一份给别的机房。
  • collector,负责从别的机房读取写请求,然后再把请求转发给本机房的处理机。


那么该如何实现 WMB 的消息同步功能呢?主要有两种方案,一种是通过 MCQ 消息队列,一种是通过 RPC 调用。

  • MCQ 消息队列实现

下面这张图是采用 MCQ 消息队列的实现方案,可以看到联通机房的写请求写入到联通机房的 MCQ 里,然后联通机房的 reship 就从联通机房的 MCQ 里读取,再写入到电信机房的 MCQ 里,电信机房的 collector 就可以从电信机房的 MCQ 里读取到写请求,再写入到电信机房的另外一个 MCQ 里,电信机房的队列机就会从这个 MCQ 里读取写请求,然后更新缓存。可见采用这种方案的一个缺点是流程比较长,需要多次与 MCQ 消息队列打交道,当有大量写请求到来时,不仅要扩容 reship 和 collector 确保有足够的处理能力,还需要扩容 MCQ 消息队列以确保能够承受大量读取和写入,一种更加简单的方案是采用 RPC 调用来实现。

image.png

  • RPC 调用实现

下面这张图是采用 RPC 调用的实现方案,从图中你可以看到联通机房的写请求会调用联通机房的 reship RPC,然后联通机房的 reship RPC 就会调用电信机房的 collector RPC,这样电信机房的 collector RPC 就会调用电信机房的处理机 RPC,从而实现把联通机房的写请求同步给电信机房的处理机进行处理。

image.png

多机房数据一致性

解决了多机房数据同步的问题之后,还要确保同步后的数据是一致的,因为在同步过程中,会因为各种原因导致各机房之间的数据不一致,这就需要有机制能确保数据的一致性。而且考虑到不同业务的特征对数据一致性的要求也不相同,类似金融类的业务要求多机房之间的数据必须是强一致的,也就是一个机房的数据必须时刻同另外一个机房的数据完全一致;而社交媒体类的业务则要求没那么高,只需要能达到最终一致即可。微博的服务主要是通过消息对账机制来保证最终一致性,下面我们来看下如何通过消息对账机制来保证最终一致性。


系统会给每一次写请求生成一个全局唯一的 requestId,联通机房的写请求一方面会调用联通机房的处理机 RPC 来修改缓存和数据库,另一方面还会调用联通机房的 reship RPC,reship RPC 再调用电信机房的 collector RPC 来同步写请求,电信机房的 collector RPC 最后会调用电信机房的处理 RPC 来更新缓存。在这整个过程的每一个环节,requestId 始终保持向下传递,无论是处理成功或者失败都记录一条包含 requestId 和机房标记的处理日志,并写到 Elasticsearch 集群上去。然后通过一个定时线程,每隔 1 分钟去扫描 Elasticsearch 集群上的日志,找出包含同一个 requestId 的不同机房的处理日志,然后验证是否在各个机房请求都处理成功了,如果有的机房某一阶段处理失败,则可以根据日志信息重试该阶段直到成功,从而保证数据的最终一致性。

image.png

可以说多机房部署是非常有必要的,尤其是对可用性要求很高的业务来说,通过多机房部署能够实现异地多活,尤其可以避免因为施工把光缆挖断导致整个服务不可用的情况发生,也是业务上云实现混合云部署的前提。


相关文章
|
2月前
|
Kubernetes 持续交付 Docker
利用 Docker 和 Kubernetes 实现微服务部署
【10月更文挑战第2天】利用 Docker 和 Kubernetes 实现微服务部署
|
3月前
|
运维 Kubernetes Cloud Native
云原生时代下,如何高效构建与部署微服务
【9月更文挑战第8天】随着云计算技术的飞速发展,云原生已成为现代软件架构的重要趋势。本文将深入浅出地介绍云原生概念、微服务架构的优势以及如何在云平台上高效构建和部署微服务。我们将通过实际的代码示例,展示在Kubernetes集群上部署一个简单的微服务应用的过程,帮助读者理解云原生环境下的微服务开发和运维实践。
|
4月前
|
负载均衡 应用服务中间件 持续交付
微服务架构下的Web服务器部署
【8月更文第28天】随着互联网应用的不断发展,传统的单体应用架构逐渐显露出其局限性,特别是在可扩展性和维护性方面。为了解决这些问题,微服务架构应运而生。微服务架构通过将应用程序分解成一系列小型、独立的服务来提高系统的灵活性和可维护性。本文将探讨如何在微服务架构中有效部署和管理Web服务器实例,并提供一些实际的代码示例。
129 0
|
28天前
|
Docker 微服务 容器
使用Docker Compose实现微服务架构的快速部署
使用Docker Compose实现微服务架构的快速部署
55 1
|
3月前
|
Dubbo Java 应用服务中间件
微服务框架Dubbo环境部署实战
微服务框架Dubbo环境部署的实战指南,涵盖了Dubbo的概述、服务部署、以及Dubbo web管理页面的部署,旨在指导读者如何搭建和使用Dubbo框架。
261 17
微服务框架Dubbo环境部署实战
|
2月前
|
Kubernetes Docker 微服务
微服务实践k8s&dapr开发部署实验(1)服务调用(一)
微服务实践k8s&dapr开发部署实验(1)服务调用(一)
49 2
|
2月前
|
Kubernetes Docker 微服务
微服务实践k8s&dapr开发部署实验(1)服务调用(二)
微服务实践k8s&dapr开发部署实验(1)服务调用(二)
56 0
|
3月前
|
运维 Cloud Native Devops
云原生架构的崛起与实践云原生架构是一种通过容器化、微服务和DevOps等技术手段,帮助应用系统实现敏捷部署、弹性扩展和高效运维的技术理念。本文将探讨云原生的概念、核心技术以及其在企业中的应用实践,揭示云原生如何成为现代软件开发和运营的主流方式。##
云原生架构是现代IT领域的一场革命,它依托于容器化、微服务和DevOps等核心技术,旨在解决传统架构在应对复杂业务需求时的不足。通过采用云原生方法,企业可以实现敏捷部署、弹性扩展和高效运维,从而大幅提升开发效率和系统可靠性。本文详细阐述了云原生的核心概念、主要技术和实际应用案例,并探讨了企业在实施云原生过程中的挑战与解决方案。无论是正在转型的传统企业,还是寻求创新的互联网企业,云原生都提供了一条实现高效能、高灵活性和高可靠性的技术路径。 ##
222 3
|
3月前
|
缓存 Java 应用服务中间件
随着微服务架构的兴起,Spring Boot凭借其快速开发和易部署的特点,成为构建RESTful API的首选框架
【9月更文挑战第6天】随着微服务架构的兴起,Spring Boot凭借其快速开发和易部署的特点,成为构建RESTful API的首选框架。Nginx作为高性能的HTTP反向代理服务器,常用于前端负载均衡,提升应用的可用性和响应速度。本文详细介绍如何通过合理配置实现Spring Boot与Nginx的高效协同工作,包括负载均衡策略、静态资源缓存、数据压缩传输及Spring Boot内部优化(如线程池配置、缓存策略等)。通过这些方法,开发者可以显著提升系统的整体性能,打造高性能、高可用的Web应用。
77 2
|
4月前
|
Kubernetes 中间件 API
微服务开发到部署视频教程全集
微服务开发到部署视频教程全集