使用自动修复功能构建高可用性应用


本互动教程介绍了如何使用自动修复功能在 Compute Engine 上构建高可用性应用。

高可用性应用旨在以最低的延迟和最少的停机时间向客户端提供服务。应用崩溃或冻结时,可用性会受到影响。受损应用的客户端可能会遭遇高延迟或服务中断。

借助自动修复功能,您可以自动重启受损的应用。该功能会即刻检测到故障实例并自动重新创建这些实例,以便恢复正常向客户端提供服务。得益于此,您不再需要在发生故障后手动将应用恢复到正常服务状态。

目标

  • 配置健康检查和自动修复政策。
  • 在托管实例组上设置演示 Web 服务。
  • 模拟健康检查失败并见证自动修复过程。

费用

本教程使用 Google Cloud 的计费组件,包括:

  • Compute Engine

准备工作

    登录您的 Google Cloud 账号。如果您是 Google Cloud 新手,请创建一个账号来评估我们的产品在实际场景中的表现。新客户还可获享 $300 赠金,用于运行、测试和部署工作负载。

    在 Google Cloud Console 中的项目选择器页面上,选择或创建一个 Google Cloud 项目

    转到“项目选择器”

    确保您的 Google Cloud 项目已启用结算功能

    启用 Compute Engine API。

    启用 API

    在 Google Cloud Console 中的项目选择器页面上,选择或创建一个 Google Cloud 项目

    转到“项目选择器”

    确保您的 Google Cloud 项目已启用结算功能

    启用 Compute Engine API。

    启用 API

如果您希望通过命令行进行操作,请安装 Google Cloud CLI。

  • 安装 Google Cloud CLI。
  • 如需初始化 gcloud CLI,请运行以下命令:

    gcloud init

应用架构

该应用包括以下 Compute Engine 组件:

  • 健康检查:自动修复程序用于检测故障虚拟机实例的 HTTP 健康检查政策。
  • 防火墙规则:借助 Google Cloud 防火墙规则,您可以允许或拒绝流向您的实例的流量。
  • 托管实例组:运行相同的演示 Web 服务的一组实例。
  • 实例模板:用于创建实例组中各个实例的模板。

健康检查和实例组的系统架构。

健康检查如何探测演示 Web 服务的健康状况

健康检查使用指定的协议(如 HTTP(S)、SSL 或 TCP)向实例发送探测请求。如需了解详情,请参阅健康检查原理以及健康检查类别、协议和端口

本教程中的健康检查是一个 HTTP 健康检查,它会探测端口 80 的 HTTP 路径 /health。对于 HTTP 健康检查,仅当路径返回 HTTP 200 (OK) 响应时,才算通过探测请求的检查。在本教程中,演示 Web 服务器会定义路径 /health,以便在运行状况良好时返回 HTTP 200 (OK) 响应,运行状况不佳时返回 HTTP 500 (Internal Server Error) 响应。如需了解详情,请参阅 HTTP、HTTPS、HTTP/2 成功标准

创建健康检查

要设置自动修复功能,请先创建自定义健康检查并将网络防火墙配置为允许其进行探测。 您可以使用区域级健康检查或全球健康检查。区域级健康检查可减少跨区域依赖项并帮助实现数据驻留。如果要对多个区域中的 MIG 使用相同的健康检查,则全球健康检查会很方便。在本教程中,您将创建全球健康检查。

控制台

  1. 创建一项健康检查。

    1. 在 Google Cloud 控制台中,转到健康检查页面。

      转到“健康检查”

    2. 点击创建健康检查

    3. 名称字段中,输入 autohealer-check

    4. 范围设置为 Global。对于自动修复,您可以使用区域级健康检查或全球健康检查。

    5. 对于协议,请选择 HTTP

    6. 请求路径设置为 /health。这表示健康检查使用的 HTTP 路径。在本教程中,演示 Web 服务器会定义路径 /health,以便在运行状况良好时返回 HTTP 200 (OK) 响应,运行状况不佳时返回 HTTP 500 (Internal Server Error) 响应。

    7. 设置运行状况判断标准

      1. 检查间隔设置为 10。这定义了从一次探测开始到下一次探测开始之间的时间量。
      2. 超时设置为 5。这定义了 Google Cloud 等待探测响应的时间量。这个值必须小于或等于检查间隔时间。
      3. 状况良好判断阈值设置为 2。这定义了要将实例视为运行状况良好必须成功的连续探测次数。
      4. 状况不佳判断阈值设置为 3。这定义了要将实例视为运行状况不佳所必须失败的连续探测次数。
    8. 点击底部的创建

  2. 创建防火墙规则以允许健康检查发出 HTTP 探测请求。

    1. 在 Google Cloud 控制台中,转到创建防火墙规则页面。

      转到“创建防火墙规则”

    2. 对于名称,输入 default-allow-http-health-check

    3. 对于网络,请选择 default

    4. 对于目标,请选择 All instances in the network

    5. 对于来源过滤条件,请选择 IP ranges

    6. 对于来源 IP 地址范围,请输入 130.211.0.0/2235.191.0.0/16

    7. 协议和端口中,选择 tcp 并输入 80

    8. 点击创建

gcloud

  1. 使用 health-checks create http 命令创建全球健康检查。

    gcloud compute health-checks create http autohealer-check \
        --global \
        --check-interval 10 \
        --timeout 5 \
        --healthy-threshold 2 \
        --unhealthy-threshold 3 \
        --request-path "/health"
    
    • check-interval 定义了从一次探测开始到下一次探测开始之间的时间量。
    • timeout 定义了 Google Cloud 等待探测响应的时间量。这个值必须小于或等于检查间隔时间。
    • healthy-threshold 定义了要将实例视为运行状况良好必须成功的连续探测次数。
    • unhealthy-threshold 定义了要将实例视为运行状况不佳所必须失败的连续探测次数。
    • request-path 表示健康检查使用的 HTTP 路径。在本教程中,演示 Web 服务器会定义路径 /health,以便在运行状况良好时返回 HTTP 200 (OK) 响应,运行状况不佳时返回 HTTP 500 (Internal Server Error) 响应。
  2. 创建防火墙规则以允许健康检查发出 HTTP 探测请求。

    gcloud compute firewall-rules create default-allow-http-health-check \
        --network default \
        --allow tcp:80 \
        --source-ranges 130.211.0.0/22,35.191.0.0/16
    

良好的自动修复健康检查需要具备哪些特点

自动修复健康检查应该比较保守,以免在不必要时删除并重新创建实例。如果为自动修复功能设置的健康检查过于严格,则自动修复程序可能会将繁忙的实例误认为故障实例,并且不必要地重启它们,从而降低可用性。

  • unhealthy-threshold。此值应大于 1。最好将此值设置为 3 或更大。这样可以防止在发生网络数据包丢失等罕见故障时误判。
  • healthy-threshold。对于大多数应用来说,将此值设置为 2 就足够了。
  • timeout。请将此时间值设置为一个较大的值(预期响应时间的五倍或更长时间)。这样可以防止在出现意外延迟(例如实例繁忙或网络拥堵造成的延迟)时误判。
  • check-interval。此值应介于 1 秒到超时的两倍之间(不要太长,也不要太短)。如果设置的时间太长,就不能及时发现故障实例。如果设置的时间太短,实例和网络可能会因健康检查每秒发送大量探测而变得非常繁忙。

设置网络服务

本教程使用一个存储在 GitHub 上的 Web 应用。如果您想详细了解该应用的实现方式,请参阅 GoogleCloudPlatform/python-docs-samples GitHub 代码库。

要设置演示 Web 服务,请先创建一个在启动时会自动启动演示 Web 服务器的实例模板。然后,使用此实例模板部署托管实例组并启用自动修复功能。

控制台

  1. 创建实例模板。其中包含用于启动演示 Web 服务器的启动脚本。

    1. 在 Google Cloud 控制台中,转到实例模板页面。

      转到“实例模板”

    2. 点击创建实例模板

    3. 名称设置为 webserver-template

    4. 对于机器配置,请选择 micro (e2-micro)。

    5. 防火墙下,选中允许 HTTP 流量复选框。

    6. 点击管理、安全、磁盘、网络、单独租用以显示高级设置。系统会显示几个标签页。

    7. 管理标签页下,找到自动化并输入以下启动脚本

      sudo apt update && sudo apt -y install git gunicorn3 python3-pip
      git clone https://github.com/GoogleCloudPlatform/python-docs-samples.git
      cd python-docs-samples/compute/managed-instances/demo
      sudo pip3 install -r requirements.txt
      sudo gunicorn3 --bind 0.0.0.0:80 app:app --daemon
      

    8. 点击创建

  2. 将 Web 服务器部署为托管实例组。

    1. 在 Google Cloud 控制台中,转到实例组页面。

      进入“实例组”

    2. 点击创建实例组

    3. 名称设置为 webserver-group

    4. 对于区域,请选择 europe-west1

    5. 对于可用区,请选择 europe-west1-b

    6. 对于实例模板,请选择 webserver-template

    7. 对于自动扩缩,选择不自动调节

    8. 实例数设置为 3

    9. 对于健康检查,请选择 autohealer-check

    10. 初始延迟时间设置为 90

    11. 点击创建

  3. 创建一条允许向 Web 服务器发出 HTTP 请求的防火墙规则。

    1. 在 Google Cloud 控制台中,转到创建防火墙规则页面。

      转到“创建防火墙规则”

    2. 对于名称,输入 default-allow-http

    3. 对于网络,请选择 default

    4. 对于目标,请选择 Specified target tags

    5. 对于目标标记,请输入 http-server

    6. 对于来源过滤条件,请选择 IP ranges

    7. 对于来源 IP 地址范围,请输入 0.0.0.0/0

    8. 协议和端口中,选择 tcp 并输入 80

    9. 点击创建

gcloud

  1. 创建实例模板。在其中添加用于启动演示 Web 服务器的启动脚本。

    gcloud compute instance-templates create webserver-template \
        --machine-type e2-micro \
        --tags http-server \
        --metadata startup-script='
      sudo apt update && sudo apt -y install git gunicorn3 python3-pip
      git clone https://github.com/GoogleCloudPlatform/python-docs-samples.git
      cd python-docs-samples/compute/managed-instances/demo
      sudo pip3 install -r requirements.txt
      sudo gunicorn3 --bind 0.0.0.0:80 app:app --daemon'
    
  2. 创建实例组。

    gcloud compute instance-groups managed create webserver-group \
        --zone europe-west1-b \
        --template webserver-template \
        --size 3 \
        --health-check autohealer-check \
        --initial-delay 90
    
  3. 创建一条允许向 Web 服务器发出 HTTP 请求的防火墙规则。

    gcloud compute firewall-rules create default-allow-http \
        --network default \
        --allow tcp:80 \
        --target-tags http-server
    

模拟健康检查失败

为了模拟健康检查失败的情况,演示 Web 服务器提供了几种强制使健康检查失败的方法。

控制台

  1. 导航到 Web 服务器实例。

    1. 在 Google Cloud 控制台中,前往虚拟机实例页面。

      转到虚拟机实例

    2. 外部 IP 列下,点击任意 webserver-group 实例的 IP 地址。网络浏览器中会打开一个新的标签页。如果请求超时或网页不可用,请等待服务器完成设置,然后重试。

    演示 Web 服务器会显示一个内容大致如下的网页:

    显示绿色状态按钮和蓝色操作按钮的简单演示网页

  2. 在演示网页上,点击模拟运行状况不佳 (Make unhealthy)。

    这会导致 Web 服务器使健康检查失败。具体而言,Web 服务器会使 /health 路径返回 HTTP 500 (Internal Server Error)。只需紧接着点击检查运行状况 (Check health) 按钮,您即可自行验证这一点(自动修复程序开始重新启动实例后,该方法即告失效)。

  3. 等待自动修复程序采取行动。

    1. 在 Google Cloud 控制台中,前往虚拟机实例页面。

      转到虚拟机实例

    2. 等待 Web 服务器实例的状态发生变化。实例名称旁边的绿色对勾标记应变为灰色方块,这表示自动修复程序已开始重新启动运行状况不佳的实例。

    3. 定期点击页面顶部的刷新以获取最新状态。

    4. 当灰色方块变回绿色对勾标记时,表示实例已恢复至正常运行状态,此时自动修复过程就完成了。

gcloud

  1. 监控实例组的状态。(完成后,请按 Ctrl+C 键停止。)

    while : ; do \
        gcloud compute instance-groups managed list-instances webserver-group \
        --zone europe-west1-b \
        ; done
    
    NAME                 ZONE            STATUS   ACTION  INSTANCE_TEMPLATE   VERSION_NAME  LAST_ERROR
    webserver-group-d5tz  europe-west1-b  RUNNING  NONE    webserver-template
    webserver-group-q6t9  europe-west1-b  RUNNING  NONE    webserver-template
    webserver-group-tbpj  europe-west1-b  RUNNING  NONE    webserver-template
    

    如有任何实例显示的状态不是 RUNNING,例如 STAGING,请等待实例完成设置,然后重试。

  2. 使用安装的 Google Cloud CLI 打开新的 Cloud Shell 会话。

  3. 获取 Web 服务器实例的地址。

    gcloud compute instances list --filter webserver-group
    

    EXTERNAL_IP 列下,复制任意 Web 服务器实例的 IP 地址并将其另存为本地 bash 变量。

    export IP_ADDRESS=EXTERNAL_IP_ADDRESS
    
  4. 验证 Web 服务器是否已完成设置。服务器返回 HTTP 200 OK 响应。

    curl --head $IP_ADDRESS/health
    
    HTTP/1.1 200 OK
    Server: gunicorn/19.6.0
    ...
    

    如果您收到 Connection refused 错误,请等待服务器完成设置,然后重试。

  5. 让 Web 服务器模拟运行状况不佳时的状况。

    curl $IP_ADDRESS/makeUnhealthy > /dev/null
    

    这会导致 Web 服务器使健康检查失败。具体而言,Web 服务器会使 /health 路径返回 HTTP 500 INTERNAL SERVER ERROR。只需紧接着向 /health 发出一个请求,您即可自行验证这一点(自动修复程序开始重新启动实例后,该方法即告失效)。

    curl --head $IP_ADDRESS/health
    
    HTTP/1.1 500 INTERNAL SERVER ERROR
    Server: gunicorn/19.6.0
    ...
    
  6. 返回到第一个 Shell 会话以监控实例组并等待自动修复程序执行操作。

    1. 自动修复过程开始后,STATUSACTION 列将会更新,这表示自动修复程序已开始重新启动运行状况不佳的实例。

      NAME                 ZONE            STATUS    ACTION      INSTANCE_TEMPLATE   VERSION_NAME  LAST_ERROR
      webserver-group-d5tz  europe-west1-b  RUNNING   NONE        webserver-template
      webserver-group-q6t9  europe-west1-b  RUNNING   NONE        webserver-template
      webserver-group-tbpj  europe-west1-b  STOPPING  RECREATING  webserver-template
      
    2. 当实例再次报告 STATUSRUNNINGACTIONNONE 时,表示实例已经成功重启,此时自动修复过程已完成。

      NAME                 ZONE            STATUS   ACTION  INSTANCE_TEMPLATE   VERSION_NAME  LAST_ERROR
      webserver-group-d5tz  europe-west1-b  RUNNING  NONE    webserver-template
      webserver-group-q6t9  europe-west1-b  RUNNING  NONE    webserver-template
      webserver-group-tbpj  europe-west1-b  RUNNING  NONE    webserver-template
      
    3. 完成对实例组的监控后,请按 Ctrl+C 键停止。

请随意重复这一练习。以下是一些建议:

  • 如果您一次使所有实例都进入运行状况不佳的状态,将会怎样?如需详细了解发生并发故障时的自动修复行为,请参阅自动修复行为

  • 能否更新健康检查配置,以尽快修复实例?(在实际使用中,您应该按照本教程中所述,将健康检查参数设置为保守值。否则,实例可能会在其实未发生问题的情况下被误删并重启。)

  • 实例组具有 initial delay 配置。您能确定此演示 Web 服务器所需的最小延迟吗?(在实际使用中,您应该将延迟设为稍微(10-20%)长于实例完成启动并可开始处理应用请求所需的时间。否则,实例可能会陷入自动修复启动循环中。)

查看自动修复程序的历史记录(可选)

如需查看自动修复程序的操作历史记录,请使用以下 gcloud 命令:

gcloud compute operations list --filter='operationType~compute.instances.repair.*'

如需了解详情,请参阅查看历史自动修复操作

清理

完成本教程后,您可以清理您创建的资源,让它们停止使用配额,以免产生费用。以下部分介绍如何删除或关闭这些资源。

如果您为本教程创建了单独的项目,请删除整个项目。 否则,如果项目中包含您要保留的资源,则只删除在本教程中创建的特定资源。

删除项目

  1. 在 Google Cloud 控制台中,进入管理资源页面。

    转到“管理资源”

  2. 在项目列表中,选择要删除的项目,然后点击删除
  3. 在对话框中输入项目 ID,然后点击关闭以删除项目。

删除特定资源

如果您无法删除本教程中使用的项目,请单独删除教程资源。

删除实例组

控制台

  1. 在 Google Cloud 控制台中,转到实例组页面。

    转到“实例组”

  2. 选取您的 webserver-group 实例组对应的复选框。
  3. 如需删除实例组,请点击删除

gcloud

gcloud compute instance-groups managed delete webserver-group --zone europe-west1-b -q

删除实例模板

控制台

  1. 在 Google Cloud 控制台中,转到实例模板页面。

    转到“实例模板”

  2. 点击实例模板旁边的复选框。

  3. 点击页面顶部的 删除。在新窗口中,点击删除以确认删除。

gcloud

gcloud compute instance-templates delete webserver-template -q

删除健康检查

控制台

  1. 在 Google Cloud 控制台中,转到健康检查页面。

    转到“健康检查”

  2. 点击健康检查旁边的复选框。

  3. 点击页面顶部的 删除。在新窗口中,点击删除以确认删除。

gcloud

gcloud compute health-checks delete autohealer-check -q

删除防火墙规则

控制台

  1. 在 Google Cloud 控制台中,转到防火墙规则页面。

    转到“防火墙规则”

  2. 点击名为 default-allow-httpdefault-allow-http-health-check 的防火墙规则旁边的复选框。

  3. 点击页面顶部的 删除。在新窗口中,点击删除以确认删除。

gcloud

gcloud compute firewall-rules delete default-allow-http default-allow-http-health-check -q

后续步骤