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

1. 简介

您可以通过多种方式在 Google Cloud 上部署网站,其中每种解决方案都提供不同的特性、功能和控制级别。Compute Engine 可让您对用于运行网站的基础架构进行深度控制,但与 Google Kubernetes Engine、App Engine 或其他解决方案相比,它还需要更多的运营管理。使用 Compute Engine,您可以对基础架构的各个方面(包括虚拟机、负载平衡器等)进行精细控制。今天,您将部署一个示例应用(即 Fancy Store 的电子商务网站),以展示如何使用 Compute Engine 轻松部署网站并扩大规模。

学习内容

完成此 Codelab 后,您将在托管式实例组中有一些实例,用于为您的网站提供自动修复、负载均衡、自动扩缩和滚动更新功能。

前提条件

2. 环境设置

自定进度的环境设置

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

96a9c957bc475304

b9a10ebdf5b5a448.png

a1e3c01a38fa61c2.png

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

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

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

启用 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

默认情况下,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. 克隆源代码库

您将使用 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 命令提示符下,运行代码的初始构建,以允许应用在本地运行。脚本可能需要几分钟时间才能运行完毕。

./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

这将打开一个新窗口,您可以在其中查看 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”文件夹。点击文件 >新建文件,然后创建一个名为 launch-script.sh 的文件。

439553c934139b82

在新文件中,粘贴以下代码(其中部分代码将在粘贴后进行修改):

#!/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 代理进行收集

现在,将创建的 launch-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。从“代码编辑器”菜单中,选择视图 >切换隐藏文件以查看 .env 文件。.env

e7314ceda643e16.png

修改 .env 文件,使其指向后端的外部 IP 地址。下面的 [BACKEND_ADDRESS] 表示通过 gcloud 工具中的上一条命令确定的后端实例的外部 IP 地址。

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

保存文件。

使用以下命令重新构建 response-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/

部署前端实例

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

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)可取消监视命令。

80dc8721dc08d7e4.png

使用新的网络浏览器标签页访问 http://[FRONTEND_ADDRESS]:8080 以访问该网站,其中 [FRONTEND_ADDRESS] 为上面确定的 EXTERNAL_IP。

尝试导航至“产品”和“订单”页面,应该也能成功。

a11460a1fffb07d8.png

5. 创建代管式实例组

为了允许您的应用扩缩,系统将创建托管式实例组,并将前端后端实例用作实例模板。

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

基于源实例创建实例模板

在创建代管式实例组之前,您需要创建一个实例模板作为该实例组的基础。借助实例模板,您可以定义在创建新的虚拟机 (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

对于您的应用,前端微服务在端口 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

配置自动修复功能

如需提高应用本身的可用性并验证其是否能够响应,可以为代管式实例组配置自动修复政策。

自动修复政策依赖于基于应用的健康检查来验证应用是否按预期响应。与仅验证实例是否处于 RUNNING 状态(这是默认行为)相比,检查应用是否响应可以获得更加精准的结果。

创建一个健康检查,以便在实例在前端和后端连续三次返回健康状况不佳时对其进行修复:

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 地址,您需要更新前端的代码,使其指向新地址,而不是之前使用的指向 backend 实例的临时地址。

在 Cloud Shell 中,切换到 response-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

重新构建 response-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 中,运行以下命令以修改 frontend 实例的机器类型:

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

如果您有多个实例处于 RUNNING 状态,ACTION 设置为 None,并且 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%

发出滚动操作重启命令后,请等待大约 30 秒,以便系统有时间来处理实例,然后检查代管式实例组的状态,直到实例出现在列表中。

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

当列表项出现在列表中后,按 Control+S(在 Macintosh 上按 Command+S)退出 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+S(在 Macintosh 上按 Command+S)退出 Watch 命令。

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

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

通过 http://[LB_IP] 浏览网站,其中 [LB_IP] 是为负载平衡器指定的 IP_ADDRESS,您可以使用以下命令找到:

gcloud compute forwarding-rules list --global

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

b081b8e885bf0723.png

模拟故障

如需确认健康检查是否有效,请登录实例并停止服务。如需确定实例名称,请执行以下命令:

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

然后,通过安全 shell 进入其中一个实例,其中 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)退出 watch 命令。此时,托管式实例组会重新创建实例以进行修复。

9. 清理

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

gcloud projects delete [PROJECT_ID]

输入“Y”以确认删除。

10. 恭喜!

您已在 Compute Engine 上部署、扩缩并更新了您的网站。现在,您已获得使用 Compute Engine、代管式实例组、负载均衡和健康检查的经验!