将Web服务从单体架构演进为弹性高可用架构

更新时间:
一键部署
我的部署

随着业务增长,单体架构的Web服务的业务负载也逐渐增加,导致系统稳定性降低。此时,您可以将单体架构演进为弹性高可用架构,通过伸缩组水平扩展服务器来分摊负载,从而增强系统稳定性和响应速度。

为什么使用弹性高可用架构?

单体架构的问题

一种常见的单体架构如图所示,所有的资源部署在一台ECS实例中,用户通过域名(或IP)直接访问到单一服务器中的服务。该架构存在两方面的问题:

  • 单点故障:使用单体架构部署,一旦服务出现故障后,整个业务将发生中断,严重影响用户体验,造成用户流失。

  • 性能瓶颈:随着业务访问量的增长,单体架构可能会遇到性能瓶颈,进而阻碍业务的扩展。特别是在遭遇突发性大量访问时,容易导致服务响应变慢。

image

弹性高可用架构特点

弹性高可用架构如图所示。用户通过域名访问业务服务集群时,请求会通过负载均衡器,分摊到集群的各个业务服务实例上的业务服务进行处理。该架构特点如下:

  • 避免单点故障(高可用):使用多台服务器来分摊业务负载,从而提高服务承载能力,避免出现单一服务故障造成的业务中断。

  • 弹性伸缩:使用伸缩组管理服务集群可以一键修改集群服务器数量,快速横向扩展。同时还可以设置自动伸缩的机制,实现根据业务负载按需扩展。

image

如何将单体架构演进为弹性高可用架构?

image

如图所示,将左侧单体架构演进为弹性高可用架构需要经历两个阶段。

  • 阶段一:分离数据存储与业务逻辑

    由于弹性高可用架构是以ECS实例为单元进行复制,因此在实施弹性高可用架构时,需要确保ECS实例(包含其中的业务服务)的数据存储业务逻辑分离,即无状态化,避免因横向扩展实例而导致的数据一致性问题。

    例如,在复制ECS实例时,应确保不会复制数据库,从而防止集群使用多个不同的数据源。通过将数据存储从ECS中抽离出来,确保所有实例共享同一数据源,保持数据的一致性。

    如果在您的实际业务中,出现了以下几种常见的情况时,您需要评估该情况是否会对您的业务造成影响,从而改进业务架构。

    常见的需要注意的情况

    情况1:在实例中部署了MySQL、Redis等服务。

    如果您的ECS实例中包含数据库等有状态服务,在复制该ECS横向扩展时,会造成您的集群存在多个数据源,造成数据不一致等问题。遇到此情况时,您可以考虑抽离MySQL或者Redis等有状态的服务单独部署。

    此外,您还可以直接将自建MySQL或Redis迁移到云数据库RDS,相比自建数据库,RDS更加安全可靠、运维更加方便,自建数据库迁移上云,请参见自建数据库迁移到云数据库

    情况2:在业务服务中用到了Session技术。

    如过您在业务服务中使用到了Session技术用于保存用户登录状态,扩展服务后,会导致服务副本之间的登录信息(Session信息)不共享,从而造成用户频繁被弹出。此情况,您可以考虑单独部署Redis做共享Session,来解决此问题。

    情况3:某些不能同时执行的定时任务。

    比如您的业务中存在每天只能执行一次的定时任务,在横向扩展后,在这定时任务执行的时间点多台服务器会同时执行该定时任务,此情况您可能需要调整任务处理逻辑。

  • 阶段二:将架构演进为弹性高可用架构

    在将ECS实例中的数据存储业务逻辑分离之后,可以通过创建副本的方式进行横向扩展ECS实例(包含其中业务服务)。

    此时将服务集群迁移至伸缩组,利用其弹性能力快速创建服务的副本,使用负载均衡器作为服务集群的访问入口,分摊业务负载,确保系统的稳定和高效。

快速迁移以实现弹性高可用

方案介绍

如果您已经完成数据存储业务逻辑的分离(无状态化),您可以通过以下步骤快速将单体架构服务迁移到伸缩组实现弹性高可用架构。

  1. 部署示例网站(准备实例)。本方案会模拟一个已经完成无状态化的示例Web服务实例,以该实例为例,演示迁移过程。您也可以使用现有实例进行操作。

  2. 构建包含业务服务的实例镜像。该镜像之后会作为您集群实例的启动镜像,实例启动时自动启动业务服务。

  3. 创建管理服务集群的伸缩组。之后会通过该伸缩组快速复制实例(横向扩展)。

  4. 为集群设置统一访问入口。关联负载均衡器实现统一访问的入口。

  5. 扩展实例(验证)。快速复制实例(横向扩展),访问负载均衡器以验证集群正常工作。

1. 部署示例网站

首先您需要准备能够代表生产环境的应用实例,用于后续的复制和自动化部署。

本教程为您提供一个示例网站服务,您可以使用该服务体验迁移过程。单击一键部署示例服务完成示例服务的搭建。

该示例网站服务包含一个Web服务软件包及其运行环境自启动脚本,且该实例已经完成数据存储与业务逻辑的分离即无状态化。
如果您的业务服务实例已经无状态化,且具备以上条件(软件包、环境、自启动脚本),您也可以使用您的实际业务服务代替该实例进行后续的迁移操作。

示例服务部署说明

如右图所示,在本示例架构的ECS实例中,包含一个连接数据库的Web服务,访问该服务的地址,可以查看当前服务器的IP以及从数据库中查询到的一个字符串。同时,会为该服务设置开机自启动命令,在ECS启动时会自动运行该服务。

一键部署示例服务功能基于资源编排 ROS(Resource Orchestration Service)实现,使用该功能会在您的阿里云账户下创建一个专有网络(VPC)以及交换机(vSwitch)、一个包含示例服务的ECS实例、云数据库 RDS MySQL版。
image

部署该实例服务的具体操作步骤如下:

  1. 单击一键部署示例服务按钮,进入一键部署页。

  2. 根据界面提示,选择地域可用区

  3. 在实例配置中,选择实例规格并设置实例密码

    选择最低配置即可,您可以选择共享型实例节省体验成本。不同地域及可用区所支持的实例规格不同,请以界面显示为准。
  4. 选择RDS实例规格并设置RDS数据库密码

  5. 确认费用后,单击立即部署按钮,等待创建完成。

    您可以在具体资源页签下查看进度。您需要关注的资源如图所示,从1到5依次为安全组、专有网络VPC、交换机、ECS实例、RDS数据库。

    image

  6. 查看输出页签下,找到输出的WebUrl的链接。

    您可以在浏览器多次访问该链接,每次看到的都是相同的IP,证明访问到同一台ECS实例。

    image

2. 构建包含业务服务的实例镜像

为确保后续您新扩展的实例中部署有业务服务和设置好的自启动脚本,您需要先以该实例为基础创建自定义镜像,后续创建的实例会以该镜像作为基础镜像,在实例启动时,您的业务服务也随之启动。

  1. 进入ECS管理控制台,将地域切换到您在步骤1中准备的实例的地域。

  2. 找到步骤1中准备好的ECS实例,在右侧操作列,选择image > 云盘与镜像 > 创建自定义镜像

    image

  3. 在弹出的创建自定义镜像对话框中,记录镜像名称,方便后续查找,单击确认按钮,等待镜像创建完成。您可以在ECS控制台左侧导航栏单击实例与镜像 > 镜像查看镜像创建进度。

3. 创建管理服务集群的伸缩组

弹性高可用架构的核心是通过伸缩组管理您的服务集群,您可以通过伸缩组快速复制实例,创建并启用伸缩组具体操作如下:

  1. 进入伸缩组管理页。

    1. 登录弹性伸缩控制台

      如果您是第一次使用弹性伸缩,请根据界面提示开通弹性伸缩的权限。具体操作,请参见服务关联角色

    2. 在左侧导航栏中,单击伸缩组管理
    3. 在顶部菜单栏处,选择地域。
  2. 创建伸缩组。

    1. 伸缩组管理页面,单击创建伸缩组按钮进入创建伸缩组页面。

    2. 在页面中完成如下配置。表中未涉及的配置项保持默认即可。

      配置项

      说明

      伸缩组名称

      根据界面提示输入。本示例伸缩组名称为ess-demo。

      伸缩组类型

      选中ECS

      组内实例配置信息来源

      选中选择已有实例

      选择已有实例

      选择在步骤1中准备的ECS实例。

      组内最小实例数

      伸缩组中实例数的最小值,当伸缩组实例数低于该值时,会自动触发扩展。本示例最小实例数为0。

      组内最大实例数

      伸缩组中实例数的最大值,当伸缩组实例数高于该值时,会自动触发收缩。本示例最大实例数为10。

      专有网络选择交换机

      这两个配置项会根据您选择的ECS实例,自动填充。

      重要

      建议您创建并选择多个可用区的交换机,避免出现单一可用区实例库存不足导致扩容失败,创建交换机,请参见创建交换机

      展开高级配置 > 开启期望实例数

      选择开启。开启该功能之后,可以通过设置期望实例数自动扩缩容。

      展开高级配置 > 组内期望实例数

      输入0即可,表示先创建一个空的伸缩组。

      展开高级配置 > 实例的健康检查

      选中实例状态检查负载均衡健康检查,启用该功能后,系统会根据健康检查的结果,确保伸缩组中的所有实例及其业务服务正常运行。一旦发现服务异常,将及时用新实例替换故障实例。

    3. 单击创建按钮,等待伸缩组创建完成。

  3. 修改伸缩配置中的实例镜像。

    在通过选择已有实例创建伸缩组后,会根据ECS的原始镜像创建一个伸缩配置,通过步骤1创建的实例中,原始镜像不包含后续部署好的业务服务软件包。因此需要将步骤2中新创建的镜像覆盖伸缩配置的基础镜像。
    1. 在伸缩组管理页,找到刚刚创建的伸缩组,在右侧操作列下,单击查看详情进入该伸缩组的详情页。

    2. 如图所示,在实例配置来源 > 伸缩配置页签下,单击唯一的伸缩配置操作列下的修改镜像

      image

    3. 在弹出的修改镜像的弹框中,选择自定义镜像,根据界面提示,选择步骤2中创建的镜像。单击确认按钮完成修改。

  4. 启用伸缩组。

    在伸缩组管理页,点击右上角的启用按钮,伸缩组开始工作。

4. 为集群设置统一访问入口

当您将实例从1台扩展到多台时,需要为多台实例组成的集群设置统一的访问入口。您需要为伸缩组创建并关联负载均衡器,使用户请求通过负载均衡器自动分摊到集群的各台ECS实例,从而平衡负载,最大化资源利用率。本示例使用应用型负载均衡(ALB)作为负载均衡器,具体操作如下:

4.1 创建负载均衡器

  1. 登录应用型负载均衡ALB控制台
  2. 实例页面,单击创建应用型负载均衡

  3. 应用型负载均衡(按量付费)购买页面。根据界面提示完成应用型负载均衡的创建。

    本示例以下配置,未提及配置项保持默认。

    配置项

    说明

    地域

    关联与步骤1中实例的地域保持一致。

    实例网络类型

    选择公网

    VPC

    选择步骤1中准备实例的VPC。

    可用区

    至少选择两个,如果选择的可用区没有交换机,需要根据界面提示创建对应可用区的交换机。创建交换机的操作说明,请参见创建交换机

4.2 为业务集群创建后端服务器组

此后端服务器组将会关联到伸缩组,伸缩组创建的实例会自动添加到该后端服务器组,通过负载均衡器对外提供服务。

  1. 在应用型负载均衡ALB控制台。选择地域。

  2. 单击左侧导航栏的服务器组进入服务器组页面,单击创建服务器组按钮,根据界面提示完成后端服务器组的创建。

    本示例使用以下配置,未提及配置项保持默认。

    配置项

    说明

    服务器组类型

    选择服务器类型

    服务器组名称

    根据界面提示输入,本示例以ess-test-server-group为例。

    VPC

    选择步骤1中准备的实例的VPC。

4.3 为负载均衡器配置监听

创建一个HTTP监听来转发来自HTTP协议的请求,负载均衡实例在监听到HTTP请求时,可以将请求转发到后端服务器组的ECS实例中。

  1. 在应用型负载均衡ALB控制台。选择地域。

  2. 单击左侧导航栏的实例,找到步骤4.1创建的负载均衡器,在右侧操作列下单击创建监听,根据界面提示完成监听的创建。

    本示例使用以下配置,未提及配置项保持默认。

    配置项

    说明

    选择监听协议

    选择HTTP

    监听端口

    负载均衡对外提供服务的端口,本示例服务的使用80,代表监听访问该负载均衡器80端口的请求。

    选择服务器组

    选择步骤4.2创建的服务器组。

4.4 为伸缩组关联负载均衡器

  1. 在伸缩组管理页,找到步骤3中创建的伸缩组,在右侧操作列下,单击查看详情进入该伸缩组的详情页。

  2. 基本信息页签下,找到关联负载均衡ALB、NLB服务器组,单击添加关联负载均衡ALB、NLB服务器组,在弹出的对话框中单击添加服务器组,根据界面提示,关联步骤4.2创建的后端服务器组。完成配置后,单击确认按钮完成关联负载均衡器的操作。

    重要

    该配置项中的端口设置为您的业务服务对外提供服务的端口,本示例的业务服务使用80端口。

    image

5. 开始扩展实例(验证)

在准备好伸缩组并已关联负载均衡器之后,此时可以开始扩展实例,验证集群是否可以正常工作。

  1. 触发伸缩组的扩容操作,伸缩组将自动创建实例。

    您可以通过修改伸缩组期望实例数触发扩容操作。具体操作步骤如下:

    1. 在伸缩组管理页,找到刚刚创建的伸缩组,在右侧操作列下,单击查看详情进入该伸缩组的详情页。

    2. 基本信息页签下,找到实例伸缩概览,单击image,在弹出的修改实例伸缩概览弹框中,修改组内期望实例数,从0修改为3(代表集群需要3台ECS实例对外提供服务),单击确认完成修改。

    3. 等待实例创建完成,完成后会在伸缩组下创建3个ECS实例,您可以在实例列表页签下查看实例的创建情况。

  2. 访问负载均衡器的地址,验证请求可以负载均衡到新创建的实例。

    1. 进入应用型负载均衡ALB控制台

    2. 找到步骤4.1中创建的负载均衡器,在DNS名称下,找到访问的网址。

      image

    3. 多次访问该网址,可以看到不同的IP地址,证明可以通过负载均衡器访问到不同的服务器。

6. (可选)资源清理

如果您不再需要该集群,您可以通过以下流程清理资源。

  1. 释放步骤4.1中创建的负载均衡器。具体操作,请参见释放ALB实例

  2. 删除步骤3中创建的伸缩组。具体操作,请参见删除伸缩组

  3. 删除步骤4.2中创建的后端服务器组。具体操作,请参见删除服务器组

  4. 删除步骤2中构建的自定义镜像。具体操作,请参见删除自定义镜像

  5. 删除您在步骤3步骤4.1中创建的交换机(vSwitch),具体操作,请参见删除专有网络删除交换机

  6. 清理步骤1中部署的示例服务。如果您部署了步骤1中的示例服务,您可以删除其创建的资源栈,在删除资源栈时,选择删除方式释放资源,即可完成示例服务的资源清理。具体操作,请参见删除资源栈

后续使用建议

用于生产环境之前

为了确保该弹性高可用方案在生产环境中稳定运行,建议您在用于生产环境前,完成以下操作:

  • 完善伸缩组配置

    • 实现多可用区容灾:您可以为伸缩组配置多个可用区的交换机,并设置均衡分布策略,这样伸缩组可以在多个可用区创建实例,并将业务服务实例均衡分布在各个可用区,提升集群的扩容成功率和容灾能力。具体操作,请参见扩缩容策略

    • 选择多个实例规格提高扩容成功率:单一实例规格在库存不足时也会出现扩容失败的现象,您可以选择多个实例规格创建实例,以提高扩容成功率。具体操作,请参见创建伸缩配置(ECS实例)

  • 充分测试

    如果将该弹性高可用方案应用于生产环境,建议您在集群搭建完成后,进行测试工作,确保您的服务复制为多个时不会出现问题,同时也可以对集群进行压测,来预估您的资源需求。

使用域名作为集群访问入口

修改域名解析

如果您原来使用域名访问您的ECS实例,您可以调整域名解析,将域名指向您的负载均衡器,这样,通过域名访问时,用户的请求可以经过负载均衡器访问到您的服务集群。具体操作,请参见设置CNAME域名解析

重要

在您修改域名解析之后,由于DNS传播需要时间,请暂时不要调整原服务的IP或者停止原实例,请先保持原ECS实例运行一段时间,您可以先在监控中观察流入该ECS实例的流量,待流量清零时再停止该实例。

这么做是为了避免用户所使用的DNS服务器没有更新DNS缓存,从而访问原ECS实例的IP。此时如果该ECS实例停止服务,会造成这部分用户无法访问。

HTTPS协议支持

本示例使用HTTP访问集群,如果您需要您的集群访问域名支持HTTPS,需要为负载均衡器设置HTTPS监听,具体操作,请参见添加HTTPS监听

使用伸缩组的弹性伸缩功能

  • 设计伸缩方案:本教程不涉及自动伸缩方案的设计,后续您可以为伸缩组设置自动伸缩方案优化成本,如何设计伸缩方案,请参见支持的伸缩方案

  • 进阶功能需求:如果您有更多伸缩组的进阶功能需求,比如提高扩容成功率、进一步降低成本等,请参见进阶需求