亚马逊AWS官方博客
如何使用 Amazon CloudFront 加速您的 WordPress 站点 | AWS 初创公司博客
博客发文和内容制作已然成为许多初创公司的首选营销工具,有相当多的创业者都选择了 WordPress 作为自己的企业宣传工具。WordPress 已成为 28% 网络用户选择的内容管理系统 (CMS),是世界上最大的自托管博客工具,或许也是哈佛大学法学院、Walt Disney 公司、瑞典官方网站和 Rackspace 唯一使用的开源项目。
WordPress 开箱即用即可具备良好性能,但仍有改进的空间 – 解决性能问题的 WordPress 插件数量就是这方面的一个证据。 但是,改善用户体验最简单的方法就是使用 CloudFront 加速整个 WordPress 网站。这样做不仅可以提高网站的响应速度,还可以降低运行 WordPress 基础设施的总体成本,因为降低 Web 服务器的负载有助于缩小所需基础设施的规模。事实上,如果您的网站很受欢迎,CloudFront 可以很好地帮助您的网站应对意外负载。
现在,如果您之前在互联网上搜索过有关加速 WordPress 网站的建议,那么您可能已经找到了一些 CloudFront 配置指南,其中包含各种不同、有时甚至矛盾的建议。今天的这篇博文将明确解释如何让采用合理标准配置的 WordPress 网站或博客实现性能提升。(本解决方案还将包括 AWS Shield 标准的优势,例如针对最常见的 DDoS 攻击的保护措施,而且不影响启动速度,也无需额外费用。) 但是,如果您的网站安装了其他插件,则可能需要运行一些额外的测试,以防插件导致 WordPress 以我并未测试到的方式运行。
CloudFront 能提供哪些帮助?
许多 AWS 客户都有遍布世界各地的用户,而他们希望能触及这些客户。但是,以往需要大量工程工作的任务现在可以使用 AWS 区域和边缘站点轻松构建,这使您可以从最接近这些用户的位置提供内容。
互联网上的数据传输在很大程度上取决于全球光纤网络的情况,从而实现超高带宽的数据传输(观看 James Hamilton 在 re:Invent 大会上有关 AWS 全球网络的精彩演讲)。这些光纤网络已经可以做到以光速发送数据,但是当人们从世界的另一端访问内容时,仍然会出现一定的延迟,导致用户不耐其烦。事实已经证明,光速是一个难以克服的挑战,Amazon CloudFront 另辟蹊径,为访问您网站的用户改善了体验,这些方法包括:
- Anycast DNS 确保您的客户被路由到最近的边缘站点。
- 缓存的内容(如果可用)将从边缘站点传送给您的用户。
- 需要从您的站点获取数据时,CloudFront 会通过管理边缘站点与您网站之间的传输来优化网络吞吐量。 此流量在 Amazon Global Backbone 上运行,其中经过优化的 TCP 配置可确保在网络上传输更多字节,从而提高吞吐量,而 TCP 连接的重用可消除与建立连接相关的大部分延迟。 通过这种方式,无论内容是否已缓存,都可以通过优化的网络路径交付内容来实现加速。
- 最后,在 CloudFront Edge 上协商和分载传输层安全性 (TLS) 可进一步提高性能、降低连接设置延迟,并进一步支持后端连接重用。
解决方案概览
上面的简化架构描述了 WordPress 的通用架构,其中静态内容存储在 AWS S3 中,WordPress 运行在 EC2、Lightsail 或其他托管设施上。WordPress 默认将所有内容存储在 Web 服务器本地。但是,有几个插件可以很容易地将静态内容移动到 S3,一个示例就是 W3 Total Cache。这里的建议与您的网站是否在 S3 中存储静态内容相关,无论如何,您的网站都能得到加速。
分发点、源站和行为
首先,我将简要回顾一些术语,确保我们对内容的理解一致。具有 DNS 终端节点的 CloudFront 配置称为分发点。一个网站的所有配置设置均可配置为使用一个分发点,但有些内容可能具有不同的可缓存属性,例如图片等,以及为查看器定制且动态生成的内容(这类内容不应缓存)。 WordPress 将内容拆分成下表所述的文件夹结构。 我们可以使用适当的设置来配置 CloudFront,以通过缓存行为提供每类内容,允许请求 URL(通常按文件扩展名或路径前缀分组)应用适当的缓存配置。
即使是相对简单的网站也可以从不同的位置提供内容。CloudFront 将这些单独的位置称为源站。源站可以是 Amazon S3 存储桶,也可以是 HTTP 终端节点。您的 HTTP 服务器可以托管在 AWS 或任何面向互联网的 HTTP 系统上。在上图中,S3 和 WordPress 服务器将在您的分发点设置中配置为单独的源站。
接下来,我要介绍配置 CloudFront 的三个主要步骤:
- 创建分发点
- 定义源站
- 配置缓存行为
源站
创建 CloudFront 分发点
我假设您的 WordPress 网站已启动且正在运行。如果没有,请参阅 WS WordPress 参考架构页面,以获取帮助您在几分钟内开始投入运行的带脚本的解决方案。 您应该已经注册了域名,可能是指向您的 WordPress 网站或服务器的“www”条目。在本例中,“www”记录指向我的 Application Load Balancer 的 CNAME。但是,您的 DNS 记录将通过 DNS 名称或 IP 地址引用您的 WordPress 站点。
www.example.com ⇒ wordpress-abxdef-111222333.eu-west1.elb.amazonaws.com
或者更广泛地来说:
<DNS.friendly.name> ⇒ <WordPress DNS 名称或 IP>
现在,您应该通过 CloudFront 控制台创建一个 CloudFront Web 分发点。如果我没有提到配置,那么您就可以假设我采用的是默认选项。
填写所需的分发点详细信息。
“源站域名”是您当前 DNS 记录的目标,在本例中是我的 Application Load Balancer,但您选择的可能是 Amazon Lightsail、EC2或托管的 WordPress 服务。CloudFront 控制台会提供一个下拉列表,列出您的 AWS 账户中配置的 S3 存储桶和任何负载均衡器,以帮助避免错误,但如果其中未列出所需内容,您只需输入 DNS 名称或 IP 地址即可。
注意:CloudFront 可以配置为加速您的网站,无论该网站是否托管在 AWS 上。
TLS/SSL
Amazon Certificate Manager 可免费提供 TLS/SSL 证书,以便与 CloudFront 和 AWS Elastic 或 Application Load Balancer 一起使用。 因为加密传输中的数据有助于与用户建立信任关系,所以我假设您会使用 TLS 加密。
选择 CloudFront 与 WordPress 网站通信时可能会使用的 SSL 协议。如果您已将网站配置为接受 HTTPS 流量,那么这种假设确有意义。除非您的后端不支持传输层安全性 (TLS),否则 AWS 不建议配置 SSLv3。
源站协议策略确定 CloudFront 如何与您的源站(WordPress 服务器)通信。您可以选择始终让 CloudFront 使用 HTTP,无论源站 Web 查看器(客户端或浏览器)请求如何,CloudFront 都使用 HTTPS 进行源站连接,或者匹配查看器的请求。 我已使用 Amazon Certificate Manager 在我的网站上配置了证书,因此我将选择“HTTPS Only”,以确保在 CloudFront 和我的源站之间进行加密通信。
超时和端口
CloudFront 允许用户配置源站响应和“保持连接”超时。您的 WordPress 网站不太可能需要更长时间的请求超时。但是,如果您的网站会接收少许流量,则增大保持连接超时会很有用,最长或许可以增加到 60 秒。这会使得 CloudFront 在多次请求之间保持与源站的 TCP 连接,从而避免为后续用户或页面获取重新建立连接,避免因此而产生的延迟。默认行为是关闭空闲达到 5 秒的连接。
注意:如果您配置了较长的“保持连接”超时,而且您的网站流量较大,那么您可能会需要对源站进行扩展,以维护与 CloudFront 之间的众多开放连接。
自定义报头
CloudFront 能够为发送到源站的各请求添加用户指定的报头,这种自定义报头可能会覆盖查看器设置的报头。例如,这可以用于添加密钥,以表明该请求是通过 CloudFront 提供的。您的 Web 应用程序或者 Application Load Balancer 上的 AWS WAF 规则可以验证此报头,确保仅接受来自 CloudFront 分发点的流量。
默认缓存行为设置
这些默认设置属于“全能”行为,必须适用于我们将根据上文中的行为表定义的更为具体的规则未能处理的任何请求。
在我的查看器协议策略中,我会将 CloudFront 配置为将任何 HTTP 请求重定向到 HTTPS。请注意,如果您选择了“HTTPS Only”,则您的用户在访问您的网站时可能需要输入完整的 https://url,除非他们始终通过另一个网页上的链接导航到您的网站。
对于“允许的方法”,由于 WordPress 使用需要 POST 的表单,因此我选择了启用所有 HTTP 方法。此外,我还启用了缓存 Options 请求,这可以加速 CORS 请求。
报头
当您的 Web 服务器配置为托管多个网站(通过虚拟主机等)时,Host 报头将确定将要提供的内容。我建议根据列入白名单的报头进行缓存,同时至少配置 Host 和 Origin 报头。您应该转发通过 Web 应用程序处理的报头,或者更改返回给查看器的内容的报头。如果您跟踪将用户引导到网站的推荐者,您可能还希望转发推荐者报头。
注意:如果选择“None”,则 CloudFront 可能会在某些情况下提供错误的内容,例如在同一服务器上托管多个网站的内容时。另一方面,如果选择“All”,CloudFront 将不会缓存对象,而是将所有请求发送到您的源站进行处理,这会降低缓存命中率,也会给您的源站增加额外的负载。要实现恰当的平衡,就需要切实了解您自己的环境,而您的环境可能与我的环境有所不同,举例来说,如果您托管多个网站,则可能需要在本文的基础之上进一步作出调整。
对象缓存
默认情况下,WordPress 不会设置 Expires 或 max-age 等缓存控制报头。您可以安装插件(参见关于缓存的 WordPress 文档),或者配置“.htaccess”文件来设置这些报头。 如果您选择不以这种方式配置 WordPress,则可以选择在“Object Caching”下进行自定义,这样仍然可以保证获得 CloudFront 缓存内容。(如果您已将 WordPress 配置为添加缓存控制报头,那么就应该选择“User Origin Cache Headers”)。下面的“Default TTL”设置将指示 CloudFront 在 WordPress 服务器未配置缓存报头时,将对象缓存 300 秒。
这会缓存您网站上的动态页面,并且还可能阻止未登录的用户看到在页面上发布的评论,直至缓存在 1 分钟/300 秒内到期为止。如果您希望用户在评论发布后立即查看评论,请选择较低的默认 TTL。这样的缓存可以降低服务器的负载(特别是在您的网站流量突然激增的情况下),因为大多数访问者都会看到缓存的页面。
Cookie
WordPress 广泛使用 Cookie,我建议根据白名单转发 Cookie。您的具体情况可能会有所不同,具体取决于您的网站或插件的配置,但对于大多数情况,以下 Cookie 应该足以满足需求。您可以单击此处查看官方文档,详细了解如何使用 WordPress Cookie。
查询字符串
WordPress 使用查询字符串来确定要返回的内容,例如,搜索结果或单个文章请求。因此,这些内容应该发送到源站 (WordPress),但我们还应该根据实际的查询字符串在短时间内缓存内容,以避免返回来自先前用户的查询的缓存结果等。
媒体流(顺畅流式处理)和限制内容(例如网站设置了付费门槛的内容)不在本文讨论之列,因此我们将相应的设置保留默认值。
我建议开启“自动压缩对象”。启用这个选项时,如果请求查看器或浏览器包含报头“Accept-Encoding: gzip”,CloudFront 就会压缩某些文件。提供压缩对象可以提高用户端性能。
分发点设置
CloudFront 允许许多配置选项,但我会集中讨论可能与 WordPress 网站相关的选项。您也会看到,我并未配置 AWS WAF,这是因为相关内容不在本文讨论之列,但是这项配置也值得考虑,因为它能为您的网站提供额外的保护。
TLS/SSL
如上所述,我使用 Amazon Certificate Manager 创建了免费的 TLS/SSL 证书。此证书在我的 Application Load Balancer 上配置,除了保护 CloudFront 与我的网站之间的后端流量之外,我还可以使用 CloudFront 证书来保护我的用户与 CloudFront 边缘站点之间的通信。
定制 TLS/SSL 客户端支持
CloudFront 提供两种托管 TLS/SSL 证书的选项。默认选项是仅为支持服务器名称指示 (SNI) 的客户端提供服务。使用此默认选项,CloudFront 会将您的证书与并非分发点专用的 IP 地址相关联。SNI 是大多数现代浏览器支持的 TLS 协议的扩展,包括请求报头中的域名。这允许 CloudFront 确定在协商加密通道时使用的证书。如果客户端浏览器不支持 SNI,则无法保护连接,该连接将被丢弃。
另一种方法是让 CloudFront 在托管您的分发点的每个边缘站点提供专用 IP 地址。在这种情况下,不支持 SNI 的浏览器将能够协商与您网站之间的安全连接。注意:此选项会产生额外的月度费用。
Wikipedia 的此页面列出了支持 SNI 的浏览器。
我建议使用服务器名称指示的默认选项。
安全策略
CloudFront 支持各种安全策略,例如,通过强制实施 TLS v1.2、杜绝使用 RC4 等弱密码来提高 Web 应用程序的安全性。但是,我们建议您使用 TLSv1.2_2016 安全策略,以获得最广泛的浏览器兼容性。使用更新的安全策略时,需要浏览器支持更高版本的 TLS 版本,此外还会停止对弱密码(如 3DES)的支持。请参见 CloudFront 文档,了解密码和协议详情。
默认根对象
这与 WordPress 无关,因为您的网站会自动配置为提供 index.php。如果您托管的是来自 S3 源站的静态网站,则可以选择默认提供 index.html。
日志记录
根据您自己的要求,您可以选择在日志中记录由 CloudFront、Elastic、Application Load Balancer、WordPress 服务器或上述所有服务处理的 HTTP 请求。默认情况下不会记录所有查看器请求,目前我保留这一默认设置。
最后,您可以添加注释,选择“enabled as the distribution state“,然后单击“create distribution”。
状态:进行中
创建分发点后,您将被重定向回 CloudFront Web 控制台,然后便可查看状态为“进行中”的分发点。 此状态可能需要在几分钟后才能更改为“已部署”,但我们可以继续为 WordPress 内容指定源站和行为。
添加源站和行为
选择您的分发点,然后单击“Distributions Settings”按钮以编辑设置。
在“Origins”选项卡上,您应该会看到一个在初始设置中创建的源站,如下所示:
选择“Create Origin”以添加 CloudFront 将从中请求内容的源。
由于我已将 WordPress 配置为在 S3 中存储静态内容(如图像、CSS 和 JavaScript 文件),因此我将 S3 存储桶添加为源站,并配置相应的缓存行为。
接下来,在“Behaviors”选项卡中,我们将创建上表中提到的配置。
目前,您只会看到 Default(*) 行为:
我已经在上文中介绍了设置,因此此处不再赘述,但您应该使用这些设置另外创建 4 个行为。
由于内容是静态的,因此它应该具有十分便于缓存的特点。
不要忘记 DNS
此时,系统会应用您对分发点做出的更改(状态:进行中)。但是,我们尚未对您的 WordPress 网站做出任何更改。该网站仍然像以前一样在 www.example.com 上提供。
要为您的域激活 CloudFront 配置,您只需更新 DNS 记录,创建指向您的 CloudFront 分发点 DNS 名称的 CNAME 或 ALIAS 即可。如果您在 Route 53 中托管 DNS,那么可以快速轻松地完成这项更改,但我要将此作为练习留给读者去完成。但是,在为所有用户进行此更改之前,您可以测试设置,通过编辑主机文件来覆盖自己计算机的 DNS:
1.通过命令行在您的 CloudFront 分发点上执行 DNS 查找;
dig dywhc8e9dt67j.cloudfront.net
dywhc8e9dt67j.cloudfront.net.54 IN A 54.192.31.130
dywhc8e9dt67j.cloudfront.net.54 IN A 54.192.31.131
…
…
2. 选择返回的 IP 地址,将其添加到您的主机文件中(在 Windows 上的路径是 C:\Windows\System32\drivers\etc\hosts,
在 Mac 或 Linux 系统上的路径是 /etc/hosts)
在文件底部附加一行,内容应如下所示:
www.example.com 54.192.31.130
3. 现在,当您使用浏览器访问您的网站时,主机文件将覆盖 DNS,您将被定向到用于测试的 CloudFront 分发点。 确保全面测试网站的所有区域,包括管理界面和插件行为。
4. 最后,对改进感到满意后,从主机文件中删除相关条目,并在 DNS 中创建一个 CNAME,指向您的 CloudFront 分发点 DNS 终端节点(在本例中是 dywhc8e9dt67j.cloudfront.net,但您的终端节点地址可能有所不同)。
小结
这一分步指南应该能帮助您改进 WordPress 网站,并准备好应对任何突发的流量高峰。有关本文中所介绍的各种选项的更多详情,请参阅 Amazon CloudFront – 入门网站。此外,请访问 GitHub 上的 WordPress 参考架构,其中提供了 CloudFormation 脚本,可以帮助您在短短几分钟内启动并运行可扩展的 WordPress 架构,包括 CloudFront 加速。