使用 Compute Engine 在 Google Cloud 中托管和扩缩 Web 应用

1. 简介

您可以通过多种方式在 Google Cloud 中部署网站,每种解决方案的特性、功能和掌控程度各不相同。Compute Engine 可用于对运行网站所用的基础设施进行深层控制,但与 Google Kubernetes Engine、App Engine 等其他解决方案相比,采用 Compute Engine 还需要略微多完成一些运维管理工作。利用 Compute Engine,您可以精细控制基础设施的各个方面,包括虚拟机、负载平衡器等。今天,您将部署一个示例应用,即 Fancy Store 的电子商务网站,以展示如何使用 Compute Engine 轻松部署和扩缩网站。

学习内容

本 Codelab 结束时,您的托管式实例组中将会有多个实例,可为网站提供自动修复、负载均衡、自动扩缩和滚动更新功能。

前提条件

2. 环境设置

自定进度的环境设置

  1. 登录 Cloud 控制台,然后创建一个新项目或重复使用现有项目。 如果您还没有 Gmail 或 Google Workspace 账号,则必须创建一个

96a9c957bc475304.png

b9a10ebdf5b5a448.png

a1e3c01a38fa61c2.png

请记住项目 ID,它在所有 Google Cloud 项目中都是唯一的名称(上述名称已被占用,您无法使用,抱歉!)。它稍后将在此 Codelab 中被称为 PROJECT_ID

  1. 接下来,您需要在 Cloud 控制台中启用结算功能,才能使用 Google Cloud 资源。

运行此 Codelab 应该不会产生太多的费用(如果有费用的话)。请务必按照“清理”部分中的所有说明操作,该部分介绍了如何关停资源,以免产生超出本教程范围的结算费用。Google Cloud 的新用户符合参与 $300 USD 免费试用计划的条件。

启用 Compute Engine API

接下来,您需要启用 Compute Engine API。启用 API 需要您接受 API 的服务条款和结算责任。

在 Cloud Shell 中,执行以下命令以启用 Compute Engine API:

gcloud services enable compute.googleapis.com

Cloud Shell

虽然可以通过笔记本电脑对 Google Cloud 进行远程操作,但在此 Codelab 中,您将使用 Cloud Shell,这是一个在云端运行的命令行环境。

基于 Debian 的这个虚拟机已加载了您需要的所有开发工具。它提供了一个持久的 5GB 主目录,并且在 Google Cloud 中运行,大大增强了网络性能和身份验证。这意味着在本 Codelab 中,您只需要一个浏览器(没错,它适用于 Chromebook)。

  1. 如需从 Cloud Console 激活 Cloud Shell,只需点击激活 Cloud Shella8460e837e9f5fda.png(预配和连接到环境仅需花费一些时间)。

b532b2f19ab85dda.png

Screen Shot 2017-06-14 at 10.13.43 PM.png

在连接到 Cloud Shell 后,您应该会看到自己已通过身份验证,并且相关项目已设置为您的 PROJECT_ID

gcloud auth list

命令输出

Credentialed accounts:
 - <myaccount>@<mydomain>.com (active)
gcloud config list project

命令输出

[core]
project = <PROJECT_ID>

如果出于某种原因未设置项目,只需发出以下命令即可:

gcloud config set project <PROJECT_ID>

正在查找您的 PROJECT_ID?检查您在设置步骤中使用的 ID,或在 Cloud Console 信息中心查找该 ID:

2485e00c1223af09.png

默认情况下,Cloud Shell 还会设置一些环境变量,这对您日后运行命令可能会很有用。

echo $GOOGLE_CLOUD_PROJECT

命令输出

<PROJECT_ID>
  1. 最后,设置默认可用区和项目配置。
gcloud config set compute/zone us-central1-f

您可以选择各种不同的可用区。如需了解详情,请参阅区域和可用区

创建 Cloud Storage 存储桶

我们将使用 Cloud Storage 存储分区来存储构建的代码以及启动脚本。在 Cloud Shell 中,执行以下命令以创建新的 Cloud Storage 存储分区:

gsutil mb gs://fancy-store-$DEVSHELL_PROJECT_ID

3. 克隆源代码库

您将使用基于 monolith-to-microservices 代码库的 Fancy Store 现有电子商务网站作为您网站的基础。您将从代码库中克隆源代码,以便专注于将网站部署到 Compute Engine。稍后,您将对代码进行细微更新,从而验证在 Compute Engine 上进行更新是多么简单。

您可以通过以下链接自动将代码库克隆到项目中,并打开 Cloud Shell 和内置的代码编辑器:在 Cloud Shell 中打开

或者,您也可以在 Cloud Shell 中使用以下命令手动克隆代码库:

cd ~
git clone https://github.com/googlecodelabs/monolith-to-microservices.git
cd ~/monolith-to-microservices

在 Cloud Shell 命令提示符处,运行代码的初始 build,让应用在本地运行。脚本可能需要几分钟才能运行完毕。

./setup.sh

请尽职尽责地测试您的应用。运行以下命令以启动您的 Web 服务器:

cd microservices
npm start

输出:

Products microservice listening on port 8082!
Frontend microservice listening on port 8080!
Orders microservice listening on port 8081!

点击“网页预览”图标,然后选择“在端口 8080 上预览”,即可预览应用。

6634c06dd0b9172c.png

系统应该会打开一个新窗口,您可以在其中看到 Fancy Store 前端的实际效果!

abf2ca314bf80d03.png

查看完网站后,您可以关闭此窗口。如需停止 Web 服务器进程,请在终端窗口中按 Control+C(Macintosh 上为 Command+C)。

4. 创建 Compute Engine 实例

现在您已经有了可用的开发者环境,接下来可以部署一些 Compute Engine 实例了!在以下步骤中,您将:

  1. 创建启动脚本以配置实例。
  2. 克隆源代码并将其上传到 Cloud Storage。
  3. 部署 Compute Engine 实例,用于托管后端微服务。
  4. 重新配置前端代码,以利用后端微服务实例。
  5. 部署 Compute Engine 实例,用于托管前端微服务。
  6. 配置网络以允许通信。

创建启动脚本

使用启动脚本可以告知实例每次启动时要执行哪些操作。这样便可以自动配置实例。

点击 Cloud Shell 功能区中的铅笔图标,打开代码编辑器。

找到 monolith-to-microservices 文件夹。依次点击文件 > 新建文件,然后创建一个名为 startup-script.sh 的文件。

439553c934139b82.png

在新文件中,粘贴以下代码,粘贴后您需要修改其中的部分代码:

#!/bin/bash

# Install logging monitor. The monitor will automatically pick up logs sent to
# syslog.
curl -s "https://storage.googleapis.com/signals-agents/logging/google-fluentd-install.sh" | bash
service google-fluentd restart &

# Install dependencies from apt
apt-get update
apt-get install -yq ca-certificates git build-essential supervisor psmisc

# Install nodejs
mkdir /opt/nodejs
curl https://nodejs.org/dist/v8.12.0/node-v8.12.0-linux-x64.tar.gz | tar xvzf - -C /opt/nodejs --strip-components=1
ln -s /opt/nodejs/bin/node /usr/bin/node
ln -s /opt/nodejs/bin/npm /usr/bin/npm

# Get the application source code from the Google Cloud Storage bucket.
mkdir /fancy-store
gsutil -m cp -r gs://fancy-store-[DEVSHELL_PROJECT_ID]/monolith-to-microservices/microservices/* /fancy-store/

# Install app dependencies.
cd /fancy-store/
npm install

# Create a nodeapp user. The application will run as this user.
useradd -m -d /home/nodeapp nodeapp
chown -R nodeapp:nodeapp /opt/app

# Configure supervisor to run the node app.
cat >/etc/supervisor/conf.d/node-app.conf << EOF
[program:nodeapp]
directory=/fancy-store
command=npm start
autostart=true
autorestart=true
user=nodeapp
environment=HOME="/home/nodeapp",USER="nodeapp",NODE_ENV="production"
stdout_logfile=syslog
stderr_logfile=syslog
EOF

supervisorctl reread
supervisorctl update

现在,在代码编辑器中,找到文本 [DEVSHELL_PROJECT_ID],并将其替换为以下命令的输出:

echo $DEVSHELL_PROJECT_ID

输出示例:

my-gce-codelab-253520

现在,startup-script.sh 文件中的这行代码应类似于以下内容:

gs://fancy-store-my-gce-codelab-253520/monolith-to-microservices/microservices/* /fancy-store/

启动脚本会执行以下任务:

  • 安装 Logging 代理,该代理会自动从 syslog 收集日志
  • 安装 Node.js 和 Supervisor,后者将应用作为守护程序运行
  • 从 Cloud Storage 存储分区克隆应用的源代码并安装依赖项
  • 运行应用的 Supervisor 的配置,确保应用在意外退出或被管理员或进程停止时重新启动,并将应用的 stdout 和 stderr 发送到 syslog,供 Logging 代理收集

现在,将创建的 startup-script.sh 文件复制到您之前创建的 Cloud Storage 存储分区中:

gsutil cp ~/monolith-to-microservices/startup-script.sh gs://fancy-store-$DEVSHELL_PROJECT_ID

现在可通过以下网址访问此文件:https://storage.googleapis.com/[BUCKET_NAME]/startup-script.sh[BUCKET_NAME] 代表 Cloud Storage 存储分区的名称。默认情况下,只有获得授权的用户和服务账号才能查看此文件,因此无法通过网络浏览器访问它。Compute Engine 实例能够自动通过其服务账号访问此文件。

将代码复制到 Cloud Storage 存储分区

实例启动后,会从 Cloud Storage 存储分区中拉取代码,因此您可以在代码的“.env”文件中存储一些配置变量。

将克隆的代码复制到 Cloud Storage 存储分区:

cd ~
rm -rf monolith-to-microservices/*/node_modules
gsutil -m cp -r monolith-to-microservices gs://fancy-store-$DEVSHELL_PROJECT_ID/

部署后端实例

您要部署的第一个实例是后端实例,用于存储订单和产品微服务。

在 Cloud Shell 中执行以下命令,以创建配置为使用您之前创建的启动脚本的 f1-micro 实例,并将其标记为后端实例,以便您稍后可以对其应用特定防火墙规则:

gcloud compute instances create backend \
    --machine-type=f1-micro \
    --image=debian-9-stretch-v20190905 \
    --image-project=debian-cloud \
    --tags=backend \
    --metadata=startup-script-url=https://storage.googleapis.com/fancy-store-$DEVSHELL_PROJECT_ID/startup-script.sh

配置与后端的连接

在部署应用的前端之前,您需要先更新配置,使其指向您部署的后端。

检索后端的外部 IP 地址,该地址可通过以下命令在后端实例的 EXTERNAL_IP 标签页下查看:

gcloud compute instances list

输出示例:

NAME     ZONE           MACHINE_TYPE  PREEMPTIBLE  INTERNAL_IP  EXTERNAL_IP   STATUS
backend  us-central1-a  f1-micro                   10.128.0.2   34.68.223.88  RUNNING

在 Cloud Shell 的代码编辑器中,依次找到文件夹 monolith-to-microservices > react-app。在代码编辑器菜单中,依次选择 View > Toggle Hidden Files(查看 > 显示/不显示隐藏文件),以查看 .env 文件。

e7314ceda643e16.png

修改 .env 文件,以指向后端的外部 IP 地址。下方的 [BACKEND_ADDRESS] 代表后端实例的外部 IP 地址,该地址是通过 gcloud 工具中的上一个命令确定的。

REACT_APP_ORDERS_URL=http://[BACKEND_ADDRESS]:8081/api/orders
REACT_APP_PRODUCTS_URL=http://[BACKEND_ADDRESS]:8082/api/products

保存文件。

使用以下命令重新构建 react-app,以更新前端代码:

cd ~/monolith-to-microservices/react-app
npm install && npm run-script build

将应用代码复制到 Cloud Storage 存储分区:

cd ~
rm -rf monolith-to-microservices/*/node_modules
gsutil -m cp -r monolith-to-microservices gs://fancy-store-$DEVSHELL_PROJECT_ID/

部署前端实例

代码已配置完毕,现在可以部署前端实例了。执行下面的命令来部署前端实例,此命令与前面的命令类似,但此实例已标记为“前端”,可用于防火墙用途。

gcloud compute instances create frontend \
    --machine-type=f1-micro \
    --image=debian-9-stretch-v20190905 \
    --image-project=debian-cloud \
    --tags=frontend \
    --metadata=startup-script-url=https://storage.googleapis.com/fancy-store-$DEVSHELL_PROJECT_ID/startup-script.sh 

配置网络

创建防火墙规则,以允许前端访问端口 8080,后端访问端口 8081 和 8082。这些防火墙命令会使用在为应用创建实例时指定的标记。

gcloud compute firewall-rules create fw-fe \
    --allow tcp:8080 \
    --target-tags=frontend
gcloud compute firewall-rules create fw-be \
    --allow tcp:8081-8082 \
    --target-tags=backend

网站现在应该可以正常运行了。确定前端的外部 IP 地址。您可以通过查找前端实例的 EXTERNAL_IP 来确定地址:

gcloud compute instances list

输出示例:

NAME      ZONE           MACHINE_TYPE  PREEMPTIBLE  INTERNAL_IP  EXTERNAL_IP      STATUS
backend   us-central1-a  f1-micro                   10.128.0.2   104.198.235.171  RUNNING
frontend  us-central1-a  f1-micro                   10.128.0.3   34.69.141.9      RUNNING

该实例可能需要几分钟才能启动并完成配置。执行以下命令以监控应用的就绪状态:

watch -n 5 curl http://[EXTERNAL_IP]:8080 

看到类似以下的输出之后,说明该网站应该已经就绪。在命令提示符下按 Control+C(在 Macintosh 上,按 Command+C)可取消 watch 命令。

80dc8721dc08d7e4.png

在新的浏览器标签页中,通过网址 http://[FRONTEND_ADDRESS]:8080 访问该网站,其中 [FRONTEND_ADDRESS] 是之前确定的外部 IP。

尝试前往“商品”和“订单”页面,这些页面也应该可以正常工作。

a11460a1fffb07d8.png

5. 创建托管式实例组

为了让应用能够扩缩,需要创建托管式实例组,并将 frontendbackend 实例用作实例模板。

托管式实例组包含多个相同实例,可将这些实例作为单个可用区内的单个实体进行管理。托管式实例组会主动让实例保持可用(即处于“正在运行”状态),以维持应用的高可用性。您将为前端和后端实例使用托管式实例组,以提供自动修复、负载均衡、自动扩缩和滚动更新功能。

基于源实例创建实例模板

在创建托管式实例组之前,您需要先创建一个实例模板,以用作实例组的基础。通过实例模板,您可以指定在创建新虚拟机 (VM) 实例时要使用的机器类型、启动磁盘映像或容器映像、网络和其他实例属性。您可以使用实例模板创建属于托管式实例组的实例,甚至是创建单独的实例。

若要创建实例模板,需使用您创建的现有实例。

首先,您必须停止这两个实例。

gcloud compute instances stop frontend
gcloud compute instances stop backend

现在,基于源实例创建实例模板。

gcloud compute instance-templates create fancy-fe \
    --source-instance=frontend
gcloud compute instance-templates create fancy-be \
    --source-instance=backend

确认实例模板已创建完成:

gcloud compute instance-templates list

输出示例:

NAME      MACHINE_TYPE  PREEMPTIBLE  CREATION_TIMESTAMP
fancy-be  f1-micro                   2019-09-12T07:52:57.544-07:00
fancy-fe  f1-micro                   2019-09-12T07:52:48.238-07:00

创建托管式实例组

您将创建两个托管式实例组,分别用于前端和后端。这些托管式实例组将使用之前创建的实例模板,并配置为每个实例组内各有两个实例要启动。系统会根据指定的“base-instance-name”(并附加随机字符)来自动为实例命名。

gcloud compute instance-groups managed create fancy-fe-mig \
    --base-instance-name fancy-fe \
    --size 2 \
    --template fancy-fe
gcloud compute instance-groups managed create fancy-be-mig \
    --base-instance-name fancy-be \
    --size 2 \
    --template fancy-be

对于 Fancy Store 应用,前端微服务在端口 8080 上运行,后端微服务在端口 8081(用于订单)和端口 8082(用于商品)上运行。由于这些是非标准端口,因此您需要指定已命名端口来标识它们。已命名端口是键值对元数据,代表服务名称以及运行服务的端口。可以将已命名端口分配给实例组,这表示该实例组中的所有实例都可以使用该服务。负载平衡器会使用这些信息,您将在后面进行配置。

gcloud compute instance-groups set-named-ports fancy-fe-mig \ 
    --named-ports frontend:8080
gcloud compute instance-groups set-named-ports fancy-be-mig \
    --named-ports orders:8081,products:8082

配置自动修复功能

若要提高应用本身的可用性,验证应用能否正常响应,可以为托管式实例组配置自动修复政策。

自动修复政策依靠基于应用的健康检查来验证应用能否按预期响应。默认行为是仅验证实例是否处于正在运行状态,相比之下,检查应用能否正常响应可以获得更加精准的结果。

创建如下健康检查:如果检查连续 3 次针对前端和后端返回“unhealthy”(健康状况不佳),则应修复实例:

gcloud compute health-checks create http fancy-fe-hc \
    --port 8080 \
    --check-interval 30s \
    --healthy-threshold 1 \
    --timeout 10s \
    --unhealthy-threshold 3
gcloud compute health-checks create http fancy-be-hc \
    --port 8081 \
    --request-path=/api/orders \
    --check-interval 30s \
    --healthy-threshold 1 \
    --timeout 10s \
    --unhealthy-threshold 3

创建防火墙规则,允许健康检查探测连接到端口 8080 和 8081 上的微服务:

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

将健康检查应用于对应的服务:

gcloud compute instance-groups managed update fancy-fe-mig \
    --health-check fancy-fe-hc \
    --initial-delay 300
gcloud compute instance-groups managed update fancy-be-mig \
    --health-check fancy-be-hc \
    --initial-delay 300

继续进行本 Codelab,为自动修复功能留出一些时间来监控实例组中的实例。稍后,您将模拟故障,测试自动修复能否正常运作。

6. 创建负载平衡器

为了完善托管式实例组,您可以使用 HTTP(S) 负载均衡将流量传送给前端和后端微服务,然后使用映射根据路径规则将流量传送给适当的后端服务。这将对所有服务公开单个负载均衡 IP 地址。

如需详细了解 Google Cloud 中提供的负载均衡选项,请参阅负载均衡概览

创建 HTTP(S) 负载均衡

Google Cloud 提供了许多不同类型的负载均衡,但您将使用 HTTP(S) 负载均衡来处理流量。HTTP(S) 负载均衡的结构如下:

  1. 转发规则将传入的请求定向到目标 HTTP 代理。
  2. 目标 HTTP 代理根据网址映射检查每个请求,为请求确定适当的后端服务。
  3. 后端服务根据关联后端的服务能力、可用区和实例健康状况,将每个请求定向到适当的后端。系统会通过 HTTP 健康检查来验证每个后端实例的健康状况。如果将后端服务配置为使用 HTTPS 或 HTTP/2 健康检查,系统会在将请求发送到后端实例的过程中对其进行加密。
  4. 负载均衡器与实例之间的会话可以使用 HTTP、HTTPS 或 HTTP/2 协议。如果您使用 HTTPS 或 HTTP/2,则后端服务中的每个实例都必须具有 SSL 证书。

创建健康检查,用于确定哪些实例能够为各项服务传送流量。

gcloud compute http-health-checks create fancy-fe-frontend-hc \
  --request-path / \
  --port 8080
gcloud compute http-health-checks create fancy-be-orders-hc \
  --request-path /api/orders \
  --port 8081
gcloud compute http-health-checks create fancy-be-products-hc \
  --request-path /api/products \
  --port 8082

创建后端服务,将其作为经过负载均衡的流量的目标。后端服务将使用您创建的健康检查和已命名端口。

gcloud compute backend-services create fancy-fe-frontend \
  --http-health-checks fancy-fe-frontend-hc \
  --port-name frontend \
  --global
gcloud compute backend-services create fancy-be-orders \
  --http-health-checks fancy-be-orders-hc \
  --port-name orders \
  --global
gcloud compute backend-services create fancy-be-products \
  --http-health-checks fancy-be-products-hc \
  --port-name products \
  --global

添加后端服务。

gcloud compute backend-services add-backend fancy-fe-frontend \
  --instance-group fancy-fe-mig \
  --instance-group-zone us-central1-f \
  --global
gcloud compute backend-services add-backend fancy-be-orders \
  --instance-group fancy-be-mig \
  --instance-group-zone us-central1-f \
  --global
gcloud compute backend-services add-backend fancy-be-products \
  --instance-group fancy-be-mig \
  --instance-group-zone us-central1-f \
  --global

创建网址映射。网址映射定义了将哪些网址引导至哪些后端服务。

gcloud compute url-maps create fancy-map \
  --default-service fancy-fe-frontend

创建路径匹配器,允许 /api/orders 和 /api/products 路径路由到它们各自的服务。

gcloud compute url-maps add-path-matcher fancy-map \
   --default-service fancy-fe-frontend \
   --path-matcher-name orders \
   --path-rules "/api/orders=fancy-be-orders,/api/products=fancy-be-products"

创建要与所创建的网址映射关联的代理。

gcloud compute target-http-proxies create fancy-proxy \
  --url-map fancy-map

创建一条全局转发规则,将公共 IP 地址和端口与该代理关联起来。

gcloud compute forwarding-rules create fancy-http-rule \
  --global \
  --target-http-proxy fancy-proxy \
  --ports 80

更新配置

您已经有了新的静态 IP 地址,现在需要更新前端的代码,使其指向这个新地址,而不要使用先前指向 后端实例的临时地址。

在 Cloud Shell 中,切换到 react-app 文件夹,该文件夹中的 .env 文件内包含相关配置。

cd ~/monolith-to-microservices/react-app/

确定负载平衡器的 IP 地址:

gcloud compute forwarding-rules list --global

输出示例:

NAME                    REGION  IP_ADDRESS     IP_PROTOCOL  TARGET
fancy-http-rule          34.102.237.51  TCP          fancy-proxy

使用您偏好的文本编辑器(例如 GNU nano)修改 .env 文件,以指向负载平衡器的公共 IP 地址。[LB_IP] 代表后端实例的外部 IP 地址。

REACT_APP_ORDERS_URL=http://[LB_IP]/api/orders
REACT_APP_PRODUCTS_URL=http://[LB_IP]/api/products

重新构建 react-app,以更新前端代码。

cd ~/monolith-to-microservices/react-app
npm install && npm run-script build

将应用代码复制到 GCS 存储分区中。

cd ~
rm -rf monolith-to-microservices/*/node_modules
gsutil -m cp -r monolith-to-microservices gs://fancy-store-$DEVSHELL_PROJECT_ID/

更新前端实例

现在,您希望托管式实例组中的前端实例拉取新代码。实例会在启动时拉取代码,因此您可以发出滚动重启命令。

gcloud compute instance-groups managed rolling-action restart fancy-fe-mig \
    --max-unavailable 100%

测试网站

发出 rolling-action restart 命令后等待大约 30 秒,以便系统有充足的时间处理实例。然后,查看托管式实例组的状态,直到实例出现在列表中。

watch -n 5 gcloud compute instance-groups list-instances fancy-fe-mig

当实例显示在列表中后,按 Control+C(在 Macintosh 上按 Command+C)退出 watch 命令。

确认服务状态显示为“运行状况良好”。

watch -n 5 gcloud compute backend-services get-health fancy-fe-frontend --global

输出示例:

---
backend: https://www.googleapis.com/compute/v1/projects/my-gce-codelab/zones/us-central1-a/instanceGroups/fancy-fe-mig
status:
  healthStatus:
  - healthState: HEALTHY
    instance: https://www.googleapis.com/compute/v1/projects/my-gce-codelab/zones/us-central1-a/instances/fancy-fe-x151
    ipAddress: 10.128.0.7
    port: 8080
  - healthState: HEALTHY
    instance: https://www.googleapis.com/compute/v1/projects/my-gce-codelab/zones/us-central1-a/instances/fancy-fe-cgrt
    ipAddress: 10.128.0.11
    port: 8080
  kind: compute#backendServiceGroupHealth

当实例显示在列表中后,按 Control+C(在 Macintosh 上,按 Command+C)退出 watch 命令。

然后,您可以通过 http://[LB_IP] 访问该应用,其中 [LB_IP] 是为负载平衡器指定的 IP_ADDRESS,您可使用以下命令确定该地址:

gcloud compute forwarding-rules list --global

7. 扩缩 Compute Engine

到目前为止,您已经创建了两个托管式实例组,每个组中均包含两个实例。这项配置完全可以正常运作,但这是一项静态配置,不能根据负载情况进行调整。现在,您将需要创建基于利用率的自动扩缩政策,以便自动扩缩每个托管式实例组。

根据利用率自动进行调整

如需创建自动扩缩政策,请在 Cloud Shell 中执行以下命令。这些命令会针对托管式实例组创建自动扩缩器,在负载平衡器的利用率高于 60% 时自动添加实例,在利用率低于 60% 时自动移除实例。

gcloud compute instance-groups managed set-autoscaling \
  fancy-fe-mig \
  --max-num-replicas 5 \
  --target-load-balancing-utilization 0.60
gcloud compute instance-groups managed set-autoscaling \
  fancy-be-mig \
  --max-num-replicas 5 \
  --target-load-balancing-utilization 0.60

启用内容分发网络

内容分发网络服务 Cloud CDN 也有助于实现扩缩,启用后可为前端服务提供缓存。为此,您可以在前端服务上执行以下命令:

gcloud compute backend-services update fancy-fe-frontend \
    --enable-cdn --global

现在,当用户从负载平衡器请求内容时,该请求会发送到 Google 前端。Google 前端首先会在 Cloud CDN 缓存中查找对用户请求的响应。如果前端找到缓存的响应,则会将其发送给用户。这称为缓存命中。

否则,如果前端找不到针对该请求缓存的响应,便会向后端直接发出请求。如果对该请求的响应可缓存,则前端会将响应存储在 Cloud CDN 缓存中,以便后续请求可利用缓存找到响应。

8. 更新网站

更新实例模板

现有实例模板无法修改。不过,鉴于您的实例是无状态的,而且所有配置都是通过启动脚本完成的,因此,如果您想更改模板设置核心映像本身,只需要更改实例模板。现在,您需要进行简单的更改,以使用更大的机器类型,并部署此更改。

更新前端实例,该实例是实例模板的基础。在更新期间,您需要在更新版实例模板映像中添加一个文件,接着更新实例模板,发布新模板,然后确认托管式实例组的实例中是否存在该文件。

您将修改实例模板的机器类型,只需将 f1-micro 标准机器类型改为具有 4 个 vCPU 和 3840MiB RAM 的自定义机器类型。

在 Cloud Shell 中,运行以下命令以修改前端实例的机器类型:

gcloud compute instances set-machine-type frontend --machine-type custom-4-3840

创建新的实例模板:

gcloud compute instance-templates create fancy-fe-new \
    --source-instance=frontend \
    --source-instance-zone=us-central1-a

将更新后的实例模板发布到托管式实例组:

gcloud compute instance-groups managed rolling-action start-update fancy-fe-mig \
    --version template=fancy-fe-new

监控更新的状态:

watch -n 2 gcloud compute instance-groups managed list-instances fancy-fe-mig

当您有多个实例处于正在运行状态、ACTION 设置为且 INSTANCE_TEMPLATE 设置为新模板名称 (fancy-fe-new) 时,请复制其中列出的一个机器名称,以便在下一个命令中使用。

Control+S(在 Macintosh 上为 Command+S)退出监控流程。

运行以下命令,查看虚拟机使用的是否为新机器类型 (custom-4-3840),其中 [VM_NAME] 是新创建的实例:

gcloud compute instances describe [VM_NAME] | grep machineType

预期输出示例:

machineType: https://www.googleapis.com/compute/v1/projects/project-name/zones/us-central1-f/machineTypes/custom-4-3840

更改网站内容

营销团队要求您更改网站的首页,他们希望页面上显示更多关于公司简介和所售产品/服务的信息。在本部分中,您将根据营销团队的要求,在首页上添加一些文字。似乎某位开发者已经使用名为 index.js.new 的文件创建了更改。您可以将此文件复制到 index.js,首页上就会反映所做更改。按照以下说明进行适当更改。

运行以下命令,为更新后的文件设置正确的文件名,然后输出其内容以验证所做更改:

cd ~/monolith-to-microservices/react-app/src/pages/Home
mv index.js.new index.js
cat ~/monolith-to-microservices/react-app/src/pages/Home/index.js

最终代码应如下所示:

/*
Copyright 2019 Google LLC

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    https://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

import React from "react";
import { makeStyles } from "@material-ui/core/styles";
import Paper from "@material-ui/core/Paper";
import Typography from "@material-ui/core/Typography";
const useStyles = makeStyles(theme => ({
  root: {
    flexGrow: 1
  },
  paper: {
    width: "800px",
    margin: "0 auto",
    padding: theme.spacing(3, 2)
  }
}));
export default function Home() {
  const classes = useStyles();
  return (
    <div className={classes.root}>
      <Paper className={classes.paper}>
        <Typography variant="h5">
          Fancy Fashion &amp; Style Online
        </Typography>
        <br />
        <Typography variant="body1">
          Tired of mainstream fashion ideas, popular trends and societal norms?
          This line of lifestyle products will help you catch up with the Fancy trend and express your personal style.
          Start shopping Fancy items now!
        </Typography>
      </Paper>
    </div>
  );
}

您已经更新了 React 组件,但还需要构建 React 应用来生成静态文件。运行下面的命令,构建 React 应用并将其复制到单体式应用公共目录:

cd ~/monolith-to-microservices/react-app
npm install && npm run-script build

然后,再次将代码推送到 Cloud Storage 存储分区。

cd ~
rm -rf monolith-to-microservices/*/node_modules
gsutil -m cp -r monolith-to-microservices gs://fancy-store-$DEVSHELL_PROJECT_ID/

利用滚动更新推送更改

您现在可以强制所有实例重启,以拉取更新内容。

gcloud compute instance-groups managed rolling-action restart fancy-fe-mig \
    --max-unavailable=100%

发出 rolling-action restart 命令后等待大约 30 秒,以便系统有充足的时间处理实例,然后再查看托管式实例组的状态,直到实例出现在列表中。

watch -n 5 gcloud compute instance-groups list-instances fancy-fe-mig

当实例显示在列表中后,按 Control+S(在 Macintosh 上按 Command+S)退出 watch 命令。

运行下面的命令,确认服务的状态显示为 healthy

watch -n 5 gcloud compute backend-services get-health fancy-fe-frontend --global

输出示例:

---
backend: https://www.googleapis.com/compute/v1/projects/my-gce-codelab/zones/us-central1-a/instanceGroups/fancy-fe-mig
status:
  healthStatus:
  - healthState: HEALTHY
    instance: https://www.googleapis.com/compute/v1/projects/my-gce-codelab/zones/us-central1-a/instances/fancy-fe-x151
    ipAddress: 10.128.0.7
    port: 8080
  - healthState: HEALTHY
    instance: https://www.googleapis.com/compute/v1/projects/my-gce-codelab/zones/us-central1-a/instances/fancy-fe-cgrt
    ipAddress: 10.128.0.11
    port: 8080
  kind: compute#backendServiceGroupHealth

当实例显示在列表中后,按 Control+S(在 Macintosh 上按 Command+S)退出 watch 命令。

如需使内容传送网络中的缓存内容失效,并确保显示最新内容,请运行以下命令:

gcloud compute url-maps invalidate-cdn-cache fancy-map \
    --path "/*"

通过 http://[LB_IP] 前往该网站,其中 [LB_IP] 是为负载平衡器指定的 IP 地址,您可使用下面的命令确定该地址:

gcloud compute forwarding-rules list --global

现在应该可以看到对网站进行的新更改。

b081b8e885bf0723.png

模拟故障

为了确认健康检查能否正常工作,请登录实例并停止服务。如需确定实例名称,请执行以下命令:

gcloud compute instance-groups list-instances fancy-fe-mig

然后,通过安全外壳 (SSH) 连接到其中一个实例,其中 INSTANCE_NAME 是列表中的一个实例:

gcloud compute ssh [INSTANCE_NAME]

在实例中,使用 supervisorctl 停止应用。

sudo supervisorctl stop nodeapp; sudo killall node

退出实例。

exit

监控修复操作。

watch -n 5 gcloud compute operations list \
--filter='operationType~compute.instances.repair.*'

查看以下输出示例:

NAME                                                  TYPE                                       TARGET                                 HTTP_STATUS  STATUS  TIMESTAMP
repair-1568314034627-5925f90ee238d-fe645bf0-7becce15  compute.instances.repair.recreateInstance  us-central1-a/instances/fancy-fe-1vqq  200          DONE    2019-09-12T11:47:14.627-07:00

发现修复后,按 Control+C(在 Macintosh 上,按 Command+S)退出监视命令。此时,托管式实例组会重新创建该实例以进行修复。

9. 清理

准备就绪后,清理所有已执行活动的最简单方法是删除项目。删除项目会删除 Codelab 期间创建的负载平衡器、实例、模板等,以确保不会产生意外的定期费用。在 Cloud Shell 中执行以下命令,其中 PROJECT_ID 是完整的项目 ID,而不仅仅是项目名称。

gcloud projects delete [PROJECT_ID]

出现提示时,输入“Y”以确认删除。

10. 恭喜!

您已在 Compute Engine 上部署、扩缩和更新了网站。您现在已经学会使用 Compute Engine、托管式实例组、负载均衡和健康检查了!