亚马逊AWS官方博客

基于亚马逊云科技无服务器服务快速搭建电商平台——性能篇

上一篇我们介绍了WordPress的电商插件WooCommerce和如何快速在亚马逊云快速搭建基于无服务器服务Lambda的方案,这篇我们来介绍本方案的优势,并进行负载测试。

使用Serverless构建独立站的优势

在传统架构模式下,如果需要进行电商大促需要提前预置计算资源以支撑高并发访问,会造成计算资源浪费并且增加运维工作量。本文介绍一种新的部署方式,将WordPress和WooCommerce部署在AWS Lambda中。Lambda是无服务器的计算方式,无需预置资源就可以运行代码,自动响应任何规模的代码执行请求,从每天十几个事件到每秒数十万个事件,按计算时间付费(以毫秒为单位),真正做到按使用量计费,从而达到节省预置资源和运维成本。Lambda的这种特性,让Lambda越来越受欢迎,越来越多的客户选择Lambda来部署应用,其中也包含web应用。了解Lambda的客户可能清楚,Lambda是基于事件触发的方式,对于web应用,需要使用API Gateway,接收HTTP请求,把HTTP请求转化为Lambda事件触发Lambda运行。

在以前,对于已有的Web应用,需对应用代码进行轻量级的改造以处理Lambda事件。对于很多使用像WordPress和WooCommerce这样的成熟组件的电商客户来讲,进行代码改造不太可能,是不是就不能利用Lambda的优势了呢?答案是否定的。利用Lambda的新功能Lambda container images和开源组件AWS Lambda adapter可以让WordPress在Lambda中运行且无需进行任何代码的修改。本解决方案通过将Lambda Adapter,WordPress,WooCommerce以及其他必要插件打包成容器,部署到Lambda。同时本解决方案也利用了Lambda的新功能,Function URL,来代替API Gateway,可以直接通过Function URL来通过HTTP(s)访问Lambda,从而节省API Gateway带来的成本。用户的动态请求,通过CloudFront回源到Lambda URL触发Lambda运行,在Lambda内部,Lambda Adapter接收到Lambda事件并将其转换成WordPress能处理的HTTP请求。这样就实现了无需修改代码就能在Lambda中运行WordPress。

本文着重介绍Lambda container image和Lambda Function URL,关于Lambda Adapter的实现细节请参考这篇博客。

Lambda container image

要将容器运行在Lamabda,容器映像需包含运行时API的runtime interface clients,用于管理 Lambda 和函数代码之间的交互。客户可以自行将runtime interface client包含在自己的映像以支持在Lambda运行。AWS 提供了一组可用于创建容器映像的开源基础映像。这些基本映像包括runtime interface clients 。Lambda映像是只读的,但函数代码可以访问具有 512 MB 存储空间的可写 /tmp 目录。本方案使用Docker来创建映像。Dockerfile里使用AWS提供的基础映像Amazon Linux 2,并使用bedrock来管理WordPress和插件的安装。本方案中预配置了一些必要插件,客户可以修改bedrock的配置添加所需要的插件。

Lambda Function URL

现在可以通过创建Function URL,支持使用HTTP(s)来访问这个URL来触发Lambda运行。在Function URL这个功能没有发布的时候,基于Lambda构建Web应用需要结合API Gateway来接收HTTP(s)请求。但是在Lambda上部署WooCommerce的场景下,因为是把WordPress等打包成一个容器,因此只需要单个Lambda Function,API gateway的作用只是把HTTP请求转化为Lambda事件,而API Gateway提供的高级功能,例如API管理,请求验证等,并不需要。因此有了Function URL的功能,就能够取代API Gateway在此场景下的作用,并且不会增加Lambda的费用,同时也节省了API Gateway的费用。

负载测试

在上一篇博客的基础上,我们使用WordPress的插件Blocksy快速构建一个Starter Site,并使用这个Site来作为测试对象。

本方案已经开源在Github,访问此Repo可获得完整代码。

在test/k6文件夹内,本方案也提供了进行性能测试的k6脚本。模拟了用户进入主页,选择商品,并加入购物车,更新地址,到提交订单的完整流程。具体说明参考test/readme.md文件。

main.js作为测试的入口文件,模拟了前5分钟100个用户在线,中间10分钟1000个用户在线,后5分钟100个用户在线的场景。读者可根据测试需要修改main.js文件。

因为默认CDK模版预置的RDS Aurora mysql实例和Elasticahe Redis cluster规模过小,不适合用来做测试。这里修改CDK代码cdk/lib/woocommerce-stack.ts,将RDS Aurora mysql 的r5.4xlarge。Elasticahe Redis cluster修改为r5.xlarge。客户也可以自行改大规模进行更大范围的测试。

通过以下命令更新资源。

make diff
make deploy

在这里我们使用一台c5.xlarge的Amazon Linux 2 EC2来进行测试。并安装CloudWatch Agent,将k6生成的指标上传到CloudWatch进行可视化。注意EC2需要有权写入CloudWatch Metrics,这里我们使用EC2 Role来赋予权限。通过创建Role,选择下图的托管策略CloudWatchAgentAdminPolicy,并且把这个Role绑定给EC2。

通过以下命令安装、配置k6和CloudWatch Agent,并运行k6进行测试。

sudo yum -y install https://dl.k6.io/rpm/repo.rpm
sudo yum -y install --nogpgcheck k6
sudo yum -y install git 
git clone https://github.com/aws-samples/serverless-woocommerce-workshop.git
cd ~/serverless-woocommerce-workshop/test/k6
sudo yum install -y amazon-cloudwatch-agent
cat << EOF > cw-statsd.json
{
    "metrics": {
        "namespace": "k6",
        "metrics_collected": {
            "statsd": {
                "service_address": ":8125",
                "metrics_collection_interval": 1,
                "metrics_aggregation_interval": 0
            }
        }
    }
}
EOF
sudo amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -s -c file:./cw-statsd.json
K6_STATSD_ENABLE_TAGS=true k6 run --out statsd -e HOSTNAME=<your WooCommerce website domain name> main.js

下图是k6测试运行完的统计结果。

在CloudWatch的k6 metrics中能看到每秒完成的订单数和Lambda的并发量。可以看出,随着随着请求/订单量的增加,Lambda会自动进行扩展。可以看出,Lambda能够应对对于流量的高低峰,无需任何运行操作。

总结

本篇博客在上一篇的基础上,介绍了Serverless建站方案的优势,并对基于Serverless服务的WordPress进行负载测试,能够看出Lambda能够自动应对流量高低峰而无需任何运维操作,大大节省运维成本。读者也可以根据自身需求,修改测试脚本,进行更大规模的性能测试。

附录

本篇作者

汪其香

AWS解决方案架构师,负责基于AWS云计算方案的架构咨询和设计实现,具有丰富的解决客户实际问题的经验,同时热衷于深度学习的研究与应用。

许昌月

AWS解决方案架构师,负责基于AWS的云计算方案架构咨询和设计,实施和推广,擅长软件开发,具有丰富的解决客户实际问题的经验。