部署云数据库以扩展 LAMP 应用程序

提高应用程序容量的一大关键是重新构建单体应用程序并实现横向扩展。托管云服务简化了将单体分解为组件服务的过程。本教程将演示如何将单体应用程序迁移并扩展至分布式云架构。
发布时间:2023 年 8 月 11 日
LightSail
LAMP
MySQL
扩展
教程
亚马逊云科技
Olawale Olaleye
亚马逊云科技使用经验
200 - 中级
完成所需时间
45 分钟
所需费用

可通过亚马逊云科技免费套餐免费试用,或 1.01 美元

前提条件
示例代码

本教程中使用的示例代码来自 GitHub

上次更新时间
2023 年 8 月 11 日

模块 1:部署单体应用程序

在单体应用程序中,所有组件都位于一个 VPS 中。在教程示例中,组件包括 MySQL 数据库、PHP 应用程序框架和应用程序,全部托管在一个 Lightsail 实例中。

我们将使用 Lightsail 命令行 (CLI) 客户端在 Amazon Lightsail 虚拟专用服务器 (VPS) 上部署应用程序。CLI 提供了一种在启动时使用命令或 Shell 脚本配置服务器的方法。脚本可以安装软件、更改文件权限以及设置服务器部署应用程序所需的配置参数。

本教程使用的脚本可执行以下操作:

  • Bitnami 镜像中包含一个默认网页,需要删除。该脚本首先更改为 Web 服务器的根目录 (/opt/bitnami/apache2/htdocs) 并删除现有文件
  • 接着,该脚本将从实验室的 Github 仓库中克隆应用程序代码,用于呈现 Web 前端界面
  • 为了确保 PHP 应用程序可以写入设置文件 (connectvalues.php),该脚本会更改文件的所有权 (chown) 以匹配 Apache Web 服务器运行所用的账户,并确保该账户可以写入文件(通过 chmod)
  • 每个基于 Bitnami 的实例都会为本地安装的 MySQL 数据库生成一个唯一的密码,而脚本中的下一个命令将打开设置文件并使用此密码将其更新(可以在 /home/bitnami/bitnami_application_password 中找到)
  • 最后,脚本向 MySQL 发出一组 SQL 命令(通过 MySQL 命令行工具)来将本地数据库初始化

复制脚本并将其保存至名为 launch.sh 的文件。

#!/bin/bash

echo "removing default website"
cd /opt/bitnami/apache2/htdocs
rm -rf *

echo "cloning github repo"
git clone https://github.com/build-on-aws/sample-php-app .

echo "setting ownership on settings file"
sudo chown bitnami:daemon connectvalues.php
sudo chmod 666 connectvalues.php

echo "adding db password to settings file"
sed -i.bak "s/<password>/$(cat /home/bitnami/bitnami_application_password)/;" /opt/bitnami/apache2/htdocs/connectvalues.php

echo "creating tasks database"
cat /opt/bitnami/apache2/htdocs/data/init.sql | /opt/bitnami/mariadb/bin/mysql -u root -p$(cat /home/bitnami/bitnami_application_password)

为了简化部署,Amazon Lightsail VPS 预配置有名为 blueprints 的常用软件。我们的应用程序部署在 LAMP 堆栈上,并且可以使用 Lightsail CLI 找到 LAMP 堆栈蓝图。使用 get-blueprints 命令,并使用 Linux Utility grep 来过滤结果。

aws lightsail get-blueprints | grep lamp
"group": "lamp_8_bitnami",
"blueprintId": "lamp_8_bitnami",

我们需要指定 VPS 的大小,并且就像蓝图一样,我们可以使用 CLI 找到大小合适的 VPS。VPS 的规格(例如 CPU 数量、内存大小和磁盘大小)称为捆绑包。我们将通过添加额外的服务器或横向扩展来扩展应用程序。我们可以使用可复制的小型 VPS 捆绑包,或者 cloned 来横向扩展应用程序。

aws lightsail get-bundles
...
{
 "supportedPlatforms": [
 "LINUX_UNIX"
 ], 
 "name": "Small", 
 "power": 1000, 
 "price": 10.0, 
 "ramSizeInGb": 2.0, 
 "diskSizeInGb": 60, 
 "transferPerMonthInGb": 3072, 
 "cpuCount": 1, 
 "instanceType": "small", 
 "isActive": true, 
 "bundleId": "small_2_0"
 }

通过 lamp_8_bitnami 蓝图,使用 create-instances 命令部署一个名为 PHP-fe-1 的 small_2_0 VPS。请注意,您创建的 launch.sh 脚本会通过 --user-data 参数调用。这会在启动时部署应用程序。

aws lightsail create-instances \
--instance-names PHP-fe-1 \
--availability-zone us-west-2a \
--blueprint-id lamp_8_bitnami \
--user-data file://launch.sh \
--bundle-id small_2_0

将 VPS 实例化需要几分钟时间。您可以使用 get-instance-state 命令检查实例状态。

aws lightsail get-instance-state --instance-name PHP-fe-1

CLI 以 JSON 文档格式返回 VPS 的状态。

{
 "state": {
 "code": 16,
 "name": "running"
 }
}

当服务器准备就绪时,要验证 PHP 应用程序和本地运行的 MySQL 数据库之间的连接。要查找 Lightsail 实例的公共 IP,请在 Lightsail 控制台主页上检查您的实例窗格或使用 Lightsail CLI 命令 get-instance-access-details。

提示:要在 JSON 文件中查找特定值,请安装 jq,这是一个用于解析 JSON 的实用程序。 sudo yum install jq -y
aws lightsail get-instance-access-details --instance-name PHP-fe-1 | jq .accessDetails.ipAddress

通过打开浏览器访问 http://<ipAddress> 来验证 PHP 应用程序和本地运行的 MySQL 数据库之间的连接。

模块 2:创建高可用性关系数据库

在这部分,我们将部署 Lightsail 数据库,这是一种托管数据库服务,可降低部署和管理数据库软件的复杂性。在您创建并部署在服务内运行的数据库和表时,Lightsail 会管理底层基础设施和数据库引擎。

使用 Lightsail CLI 创建 MySQL 5.7 数据库 (--relational-database-blueprint-id mysql_5_7)。本实验的重点是部署一个容错且可扩展的 Web 应用程序实现,这就需要一个高可用性数据库计划,例如 --relational-database-bundle-id micro_ha_2_0。将数据库命名为 todo-db (--relational-database-name todo-db)。

默认情况下,Lightsail 会为您创建一个强密码。但是,对于本教程,使用密码简单即可 (--master-user-password taskstasks) 并分配用户名 (--master-username dbmasteruser)

aws lightsail create-relational-database \
--relational-database-name todo-db \
--relational-database-blueprint-id mysql_5_7 \
--relational-database-bundle-id micro_ha_2_0 \
--master-username dbmasteruser \
--master-user-password taskstasks \
--no-publicly-accessible

模块 3:替换数据库

下一步是将 VPS 中运行的本地 MySQL 实例替换为高可用性 Amazon Relational Database Service (RDS) 数据库。应用程序架构如下所示:

更新应用程序配置以指向具备高可用性的 Lightsail 数据库。首先,我们需要高可用性数据库的地址。使用 get-relational-databases 命令获取描述实例的 JSON 文档并使用 jq 对其进行过滤。

aws lightsail get-relational-databases | jq .relationalDatabases[].masterEndpoint.address

在 ToDo 应用程序中,点击顶部菜单中的 Settings(设置)。

将 Lightsail 数据库的端点值粘贴至 DB Hostname。在 DB Username 下键入 dbmasteruser,在 DB Password 下键入 taskstasks。选择 Save Settings(保存设置)。

通过点击顶部菜单中的 List Tasks(列出任务)来测试新数据库,此时应该不会显示任何任务。另请注意,屏幕底部应将您的 Lightsail 数据库终端节点列为数据库主机的值。

如果您的 Web 应用程序仍然显示之前部署的数据库(表示为 localhost 数据库主机),您可能就需要使用新的浏览器窗口或无痕窗口访问。

模块 4:克隆应用程序

快照是实例的时间点副本。Lightsail 简化了实例快照的创建过程,这些快照可用于备份和还原实例、扩大或缩小实例和/或部署新实例。使用 create-instance-snapshot 命令创建 VPS 快照。

aws lightsail create-instance-snapshot \
--instance-snapshot-name PHP-fe-ls-db \
--instance-name PHP-fe-1

实例状态会变为 Snapshotting,我们需要等待该过程完成才能继续。这个过程最多可能需要 5 分钟。可以使用以下命令检查快照状态:

aws lightsail get-instance-snapshot --instance-snapshot-name PHP-fe-ls-db | jq .instanceSnapshot.state

快照完成后,使用 create-instances-from-snapshot 创建两个新实例。注意,您可以使用多个实例名称来创建多个实例。

aws lightsail create-instances-from-snapshot \
--instance-snapshot-name PHP-fe-ls-db \
--instance-names {PHP-fe-2,PHP-fe-3} \
--availability-zone us-west-2a \
--bundle-id small_2_0

使用以下命令获取两个新创建的前端实例的公共 IP。

aws lightsail get-instance --instance-name PHP-fe-2 | jq .instance.publicIpAddress

aws lightsail get-instance --instance-name PHP-fe-3 | jq .instance.publicIpAddress

打开浏览器窗口并键入其中一个新实例的 IP 地址,然后对另一个实例采取同样的操作。注意,特定 Web 前端实例的主机名会列在您的任务列表下,并且主机名会根据您在 Web 浏览器中访问的实例而变化。

模块 5:扩展应用程序

下一步是创建一个负载均衡器提供可扩展性和容错能力。将 —instance-port 设置为 80,并将负载均衡器命名为 todo-lb。

aws lightsail create-load-balancer \
--instance-port 80 \
--load-balancer-name todo-lb

您可以检查负载均衡器的状态。负载均衡器运行时,以下命令会返回 active。

aws lightsail get-load-balancer --load-balancer-name todo-lb | jq .loadBalancer.state

负载均衡器准备就绪后,添加这三个实例。

aws lightsail attach-instances-to-load-balancer \
--load-balancer-name todo-lb \
--instance-names {"PHP-fe-1","PHP-fe-2","PHP-fe-3"}

Lightsail 负载均衡器通过向每个实例上的 Web 应用程序的根发送请求来对每个实例进行运行状况检查。如果 Web 应用程序返回 HTTP Status 200,则实例通过了运行状况检查。每个实例通过运行状况检查都可能需要一些时间,您可以使用 get-load-balancer 命令验证来实例状态。

aws lightsail get-load-balancer --load-balancer-name todo-lb | jq .loadBalancer.instanceHealthSummary

若所有实例都为 healthy(运行正常),说明您就已经成功扩展了应用程序。恭喜您!新的应用程序架构如下所示。

您可以使用 get-load-balancer 查找负载均衡器的地址,并过滤对 dnsName 的响应。

aws lightsail get-load-balancer —-load-balancer-name todo-lb | jq .loadBalancer.dnsName

打开浏览器访问 http://< dnsName >,验证应用程序是否正常运行。刷新浏览器窗口就能看到前端主机 IP 的变化。

模块 6:清理资源

为了避免产生额外费用,请删除 VPS 实例、快照和 MySQL 实例。

aws lightsail delete-instance --instance-name PHP-fe-1
aws lightsail delete-instance --instance-name PHP-fe-2
aws lightsail delete-instance --instance-name PHP-fe-3
aws lightsail delete-relational-database --relational-database-name todo-db
aws lightsail delete-instance-snapshot --instance-snapshot-name PHP-fe-ls-db
aws lightsail delete-load-balancer --load-balancer-name todo-lb

成就

我们已经将一个应用程序部署在一个 VPS 上,并通过用高可用性数据库替换本地数据库、创建 VPS 副本并将它们添加到分配 VPS 中的请求的负载均衡器来扩展应用程序。本教程要点如下:

  • 使用启动脚本配置 VPS。
  • 将本地数据库替换为高可用性实例。
  • 创建快照以克隆 VPS。
  • 使用负载均衡器扩展应用程序。

您正在逐渐成长为一名云工程师。

后续步骤

下一节将从部署应用程序和数据库开始。您将了解如何创建账户以及管理用户角色和权限。现代企业通常拥有多种环境,如开发环境、测试环境和生产环境。管理企业的多个环境是对云工程师的核心要求。