无服务器 PHP是一项令人兴奋的新技术,它有可能减轻托管 PHP 应用程序的大量负担。从无服务器 PHP 中获益最多的一种应用程序是WordPress。无服务器 PHP 减轻了扩展 WordPress 的负担,同时提供与顶级主机相同的性能优势。
要了解无服务器 PHP 如何与 WordPress 一起工作,我们将了解现代 WordPress 服务器架构的当前状态。在过去的十年中,这种架构已经发展了很多。 (您可以在此处阅读更多关于它的信息。)仅使用Apache 服务器托管 WordPress 站点的日子已经一去不复返了!现在托管 WordPress 网站还有很多事情要做。
好消息是托管无服务器 WordPress 网站看起来很像使用现代 WordPress 服务器堆栈。最大的变化是您将用来自云提供商的服务替换很多架构组件。
现在,您将使用的服务以及它们如何组合在一起将因云提供商而异。使用无服务器 PHP,最流行的云提供商是AWS。这就是为什么我们将专注于 AWS 上的无服务器 WordPress 架构。
还值得注意的是,这与您使用Ymir获得的架构相同。唯一的区别是 Ymir 会为您管理一切。 (这也是为什么它是DevOps平台的原因。)但是如果您不介意自己将所有部分放在一起或借助其他工具(例如无服务器框架,本文将帮助您实现这一点.
让我们从现代 WordPress 服务器架构开始。它喜欢什么?下图显示了浏览器向 WordPress 页面发出请求时发生的情况。
全尺寸
首先,您的浏览器发出的HTTP 请求将访问HTTP 缓存。此 HTTP 缓存可以是内容交付网络(也称为 CDN)(如Cloudflare)、专用服务器(如Varnish或页面缓存插件的组合。但无论你使用什么,目标都是一样的。
您想要缓存 WordPress 响应。
那是因为如果 PHP(以及扩展名 WordPress)比您的 HTTP 缓存慢很多。因此,您希望您的 HTTP 响应尽可能来自 HTTP 缓存。如果 HTTP 缓存无法响应您的请求,那么它会将请求转发给 WordPress。
一旦您使用 PHP,事情就会变得更加简单。 PHP 版本越高,WordPress 运行速度越快。这就是为什么您总是尝试使用 WordPress 支持的最高 PHP 版本。
最后一点优化出现在 WordPress 对MySQL 数据库进行查询时。这些查询通常是 WordPress 响应您的请求的大部分缓慢原因。为了使 WordPress 更快,您希望尽可能减少 WordPress 进行的查询次数。
您可以通过使用对象缓存插件来实现此目的。对象缓存插件将 MySQL 查询的结果存储在高性能持久缓存中。 (通常是Memcached或Redis。)然后在执行查询之前检查缓存并返回结果(如果存在)。 (就像 HTTP 缓存对我们的 HTTP 请求所做的那样。)
这大大减少了 WordPress 响应请求所需的时间。尤其是如果您的 WordPress 项目具有进行大量查询的插件,例如使用 WooCommerce。这就是为什么它是现代 WordPress 服务器架构的重要组成部分。
现在我们已经了解了现代 WordPress 服务器架构,让我们看看它是如何转换为无服务器的。我们讨论它的原因是基本组件保持不变。不同之处在于所有这些组件都将由特定的 AWS 服务处理。
全尺寸
让我们回到浏览器,您的 HTTP 请求首先要命中的是CloudFront。 CloudFront 是 AWS 内容交付网络。您可以使用它为您的无服务器 WordPress 网站做很多不同的事情。
WordPress 站点仅使用 CloudFront(或任何其他 CDN)来缓存 CSS/JS 文件和媒体文件等资产。但您也可以将其用作 HTTP 缓存。这是真正的性能提升发生的地方。
使用 CloudFront 作为 HTTP 缓存将显着减少 WordPress 站点的响应时间。但由于 CloudFront 也是一个内容交付网络,因此这种减少适用于所有访问者,无论他们身在何处。与大多数不是全球分布的 WordPress HTTP 缓存解决方案相比,这是一个很大的不同。
如果您不想使用 CloudFront 进行页面缓存,也可以将其配置为仅缓存 CSS/JS 文件和媒体文件。您也可以不使用 CloudFront 并使用其他内容交付网络或不使用。但请注意,如果没有内容交付网络,性能将不会那么好。
如果 CloudFront 无法响应请求,它会将请求转发到托管在 AWS Lambda 上的无服务器 PHP 应用程序。现在,就像普通的 PHP 应用程序一样,无服务器 PHP 应用程序不会暴露在互联网上。您需要使用其他服务作为两者之间的中介。
对于常规的 PHP 应用程序,这将是您的 Web 服务器的角色。但是对于无服务器 PHP,本身就没有 Web 服务器。相反,您需要使用两种服务之一与 AWS Lambda 进行通信。它们是API Gateway或Elastic Load Balancing。
通常,您需要使用 API 网关。 (这就是图中显示的原因。)您应该只在每月处理数亿个请求时使用负载均衡器。 (例如,与 API 网关相比,使用负载均衡器处理 10 亿个请求之间,您每月将节省数千美元。)但是大多数 WordPress 网站没有获得那么多流量,因此使用 API 网关是更便宜的选择。
AWS 也有两个不同的 API 网关:HTTP API 和 REST API。您可以使用其中任何一个。也就是说,两者之间存在一些重要差异。
首先是成本问题。 REST API 的成本高于 HTTP API。那是因为 REST API 比 HTTP API 有更多的功能。
这些额外的功能是什么?好吧,它提供了 http-to-https 重定向。但如果您使用 CloudFront 进行页面缓存,则不需要这样做。它将处理 http-to-https 重定向。
它还提供边缘优化缓存。但这也是 CloudFront 为我们处理的事情。事实上,您不能同时使用 REST API 边缘优化缓存和 CloudFront。
REST API 还支持通配符子域。这仅在您要托管子域多站点安装时才重要。否则,您也不需要它。 (您还可以使用CloudFront 函数来解决 HTTP API 对通配符子域的限制。)
这一切都是为了向您表明,大多数时候您不需要额外的 REST API 功能。所以你最好少付点钱,改用 HTTP API。
一旦请求到达 API 网关或负载均衡器,它就会被转换为事件。此事件触发 Lambda 函数运行。
此 Lambda 函数有两个组件。将事件转换为 PHPFastCGI请求的 PHP 运行时。另一个是您的 WordPress 项目,它将运行 FastCGI 请求。
现在,您可以创建一个 PHP 运行时,但使用现有的可能会更好。Bref是 AWS Lambda 的流行开源 PHP 运行时,因此它是一个不错的选择。否则,Ymir 的 PHP 运行时也是开源的。
如果您使用对象缓存,则需要 Memcached 或 Redis 缓存。ElastiCache是管理这些的 AWS 服务。因此,如果您想使用持久对象缓存,则需要创建一个。
如果您决定使用一个,请注意您需要将 Lambda 函数放在私有子网上才能访问它。反过来,这将需要一个NAT网关。您还可以将 NAT 网关替换为充当网关的特定 EC2 实例。 (您可以在此处阅读有关如何操作的信息。)
这是提出虚拟私有云也称为VPC的好时机。 AWS 要求某些资源,例如您的缓存和数据库(我们将在接下来看到!)连接到 VPC。有些必须在私有子网(无法访问互联网的网络)上,而另一些也可以在公共子网(可以访问互联网的网络)上。
如果您不使用 ElastiCache,那么您与 VPC 的交互就很少。您只需要一个用于 RDS 数据库的公共子网。这是一个更新的图表,显示了没有 ElastiCache 的 VPC。
全尺寸
如果您需要使用 ElastiCache 等私有资源,情况会更加复杂。这是您需要添加前面讨论的 NAT 网关的地方。但您还需要更改某些资源以使用私有子网,例如您的 Lambda 函数。 (默认情况下,Lambda 函数不需要子网。)
您还需要一个堡垒主机来连接到资源。堡垒主机是一个 EC2 实例,充当私有子网的桥接器。例如,如果要连接到位于私有子网上的数据库服务器,则需要一个堡垒主机。
全尺寸
上图显示了具有 ElastiCache、NAT 网关、堡垒主机和私有子网的相同架构。如您所见,有更多的活动部件。在 VPC 配置方面也更加复杂。
我们无服务器 WordPress 架构的最后一个组件是数据库。RDS是管理关系数据库的服务,例如MySQL和MariaDB。
如果您使用公共子网,您的数据库将可以公开访问。只要您不共享数据库服务器地址,这并不是什么安全问题。但这使得在创建密码时使用强密码变得更加重要。
也就是说,如果它在私有子网上,无论如何你都应该设置一个强密码!但是您不必担心数据库可以公开访问。但是,就像我们在 VPC 中提到的那样,您需要创建一个堡垒主机来连接它。
我们尚未谈论的一件事是上传。当您没有服务器时,上传会发生什么?好吧,那部分比我们目前看到的要复杂得多!
全尺寸
上图是更新后的图表,向您展示了我们的无服务器 WordPress 架构在媒体上传时的样子。事情从通过 CloudFront 的请求开始。一旦请求到达 CloudFront,它将决定这是无服务器 PHP 请求还是媒体文件请求。 (不仅仅是上传的文件)
如果它是媒体文件,则请求转至S3,这是最著名的 AWS 服务。它是一种文件存储服务,可让您以低廉的价格将文件存储在云中。有很多 WordPress 插件可以让您将文件上传到 S3。
也就是说,与插件相比,将 S3 与无服务器 WordPress 结合使用时存在一些显着差异。最大的问题是如何将 WordPress 媒体文件发送到 S3。使用插件,它看起来像这样:
您将媒体文件上传到您的 WordPress 服务器,就像通常没有插件一样。一旦文件在服务器上,插件本身会负责将文件上传到 S3。大多数情况下,这发生在使用WordPress cron的后台。
使用无服务器,您不能这样做,因为没有服务器可以先将文件上传到。相反,您需要立即将其上传到 S3。正确的方法是使用签名的 URL。
签名 URL 是一个临时 URL,可用于在 S3 上执行操作。所以你需要做的是联系 S3,它会创建一个签名的 URL。然后,您可以使用此签名 URL 将文件上传到 S3,而不会影响您的安全性。
这在实践中要困难得多,因为 WordPress 无法轻松接管此过程。您也不能直接访问服务器上的文件来创建不同的文件大小。因此,您还需要开发一种方法来创建它们。
这是迄今为止无服务器 WordPress 架构中更复杂的方面。这并不是因为 AWS 有什么特别之处。只是因为 WordPress 是一个旧软件。它的创建者在设计它时假设你总是有一个服务器可以上传文件。 (大多数 S3 上传插件也是如此。)没有简单的方法可以告诉它您不想这样做。
也就是说,WordPress 是非常可扩展的。您可以编写一个可以劫持 WordPress 媒体上传过程的插件(例如Ymir one)。 (另一个支持直接上传的插件是Media Cloud。)这是它与无服务器一起工作的必要条件。
如您所见,无服务器 WordPress 安装与现代 WordPress 服务器架构并不完全相同。但它基于相同的基本原理。只是您必须依赖 AWS 等云提供商的服务。
但这也是许多主机已经在做的事情。它们依赖于内容交付网络 (CloudFront)、托管数据库 (RDS) 和托管 Redis 缓存 (ElastiCache) 等服务。所以两者之间有一些相似的元素。
但正如媒体上传的问题所强调的那样,无服务器的许多架构挑战都来自 WordPress 本身。并不是说它不能在 Lambda 上运行。它的一些内部工作假设总是有一个服务器存在。