通常,基于 PHP 的应用程序(如 Laravel)会部署在服务器上运行。但实际上,它们也可以以无服务器方式运行,例如在 AWS Lambda 上。
这种方式提供以下几个优势:

  • 无需额外配置即可实现即时、自动的流量扩容。
  • 内置冗余和弹性基础设施,无需额外的复杂性。
  • 按请求量付费的计费模式。

PlanetScale 是一个非常适合与运行在 Lambda 上的无服务器 Laravel 应用配套使用的数据库。在本文中,我们将创建一个新的 Laravel 应用,使用 Bref 将其运行在 AWS Lambda 上,连接到 PlanetScale MySQL 数据库,并进行负载测试以观察性能表现。


创建新的 Laravel 应用

首先,我们从头开始创建一个新的 Laravel 项目,使用 Composer 命令:

composer create-project laravel/laravel example-app  
cd example-app  

我们可以通过以下命令在本地运行应用:

php artisan serve  

不过,我们的目标是将它部署到云端,在 AWS Lambda 上运行。


将 Laravel 部署到 AWS Lambda

为了将 Laravel 部署到 AWS Lambda,我们可以使用 **Bref**。Bref 是一个开源项目,用于在 AWS Lambda 上支持 PHP,并且提供用于 Laravel 的集成,简化了 Laravel 在 Lambda 上的配置过程。

先决条件

在部署到 AWS Lambda 之前,你需要:

  1. 一个 AWS 账户(登录 aws.amazon.com,点击“注册”以创建账户)。
  2. 安装在本地计算机上的 serverless CLI。

你可以使用 NPM 安装 serverless CLI:

npm install -g serverless

如果你没有 NPM,或想了解更多内容,请参考 Serverless 文档
接着,使用 AWS 的访问密钥将 serverless CLI 与 AWS 账户连接起来。按照指南生成 AWS 访问密钥,然后使用以下命令设置凭据:

serverless config credentials --provider aws --key <key> --secret <secret>

使用 Bref 和 Laravel 配置

现在我们已经准备好了环境,可以安装 Bref 及其 Laravel 集成:

composer require bref/bref bref/laravel-bridge --update-with-dependencies

接着,生成 serverless.yml 配置文件:

php artisan vendor:publish --tag=serverless-config

该文件描述了需要部署到 AWS 的内容。现在运行以下命令进行部署:

serverless deploy

部署完成后,命令输出的 URL 就是我们部署的 Laravel 应用的访问地址。


使用 PlanetScale 作为数据库

现在 Laravel 已在云端运行,接下来配置 PlanetScale 数据库。首先,在 PlanetScale 上创建与 AWS 应用区域相同的数据库(默认区域为 us-east-1)。
点击 “Connect” 按钮,然后选择“Connect with: PHP (PDO)”连接方式。这样可以获取主机地址(host)、数据库名称(database name)、用户名(user)和密码(password)。
编辑项目的 .env 文件并设置数据库连接:

DB_CONNECTION=mysql  
DB_HOST=<host url>  
DB_PORT=3306  
DB_DATABASE=<database_name>  
DB_USERNAME=<user>  
DB_PASSWORD=<password>  
MYSQL_ATTR_SSL_CA=/opt/bref/ssl/cert.pem  

对于 DB_DATABASE,如果你使用 PlanetScale 数据库的单一非分片(unsharded)键范围(keyspace),可以直接使用数据库名称。如果是分片(sharded)键范围,需要添加 @primary,它会自动将查询路由到正确的键范围或分片。
请注意,不要跳过 MYSQL_ATTR_SSL_CA 行:它要求 SSL 证书以确保 Laravel 与 PlanetScale 的连接安全。还需注意,AWS Lambda 上的路径为 /opt/bref/ssl/cert.pem,而本地路径可能是 /etc/ssl/cert.pem。本地运行应用时需要切换该环境变量的路径。
接下来,重新部署应用:

serverless deploy

现在 Laravel 配置完成,我们可以运行数据库迁移命令来设置数据库表。通过以下命令在 AWS Lambda 上运行 Laravel Artisan 命令:

serverless bref:cli --args="migrate --force"

至此,数据库已准备好使用。


创建测试数据

为了测试数据库连接,我们来创建一些测试数据,存储在 Laravel 默认提供的 users 表中。
编辑 database/seeders/DatabaseSeeder.php 文件,取消注释以下代码行,使我们可以生成 10 个测试用户:

\App\Models\User::factory(10)->create();

接着,我们在 routes/api.php 中添加一个公共 API 路由,用于返回数据库中的所有用户数据:

Route::get('/users', function () {
    return \App\Models\User::all();
});

部署这些更改:

serverless deploy

然后运行以下命令以种子数据库(seed database):

serverless bref:cli --args="migrate:fresh --seed --force"

我们现在可以通过我们创建的 API 路由检索 10 个用户:

curl https://<application url>/api/users

使用 PlanetScale 进行简单负载测试

AWS Lambda 的执行模型允许我们无需任何配置即可实现即时扩展。为了验证这一点,我们对部署的应用进行了简单的负载测试。
在负载测试前,我禁用了 Laravel 默认的 API 调用速率限制(ThrottleRequests 中间件),修改了 app/Http/Kernel.php 文件。
测试时,我使用 Apache 的基准测试工具(ab)以 50 个线程并发请求 /api/users 端点:

ab -c 50 -n 10000 https://<my-api-url>/api/users

从 AWS Lambda 和 API Gateway 的指标中我们可以看到以下结果:

  • Laravel 在几秒内从零扩展到 3,800 个 HTTP 请求/分钟。
  • 100% 的 HTTP 请求处理成功。
  • 每个 HTTP 请求的 PHP 中位执行时间(p50)为 75 毫秒。
  • 95% 的请求(p95)处理时间不到 130 毫秒。
  • PlanetScale 处理峰值为 180 查询/秒。
  • PlanetScale 查询中位执行时间为 0.3 毫秒。

第二次负载测试:降低请求数

在前面的负载测试中,我们每次发送了 50 个并行请求以验证 AWS Lambda 的自动扩容能力。接下来,我们尝试将流量从 50 个并行请求降至 1 个请求,观察其性能表现。
测试结果显示,即使请求数减少,PHP 的执行时间保持不变。也就是说,负载的变化并没有对响应时间造成影响。这进一步证明了 AWS Lambda 的弹性扩容能力能够高效处理流量,并在任何负载条件下保持一致的性能表现。


提升性能:加速 SSL 连接

对于许多 Web 应用来说,响应时间在 100 毫秒左右已经足够令人满意。然而,在某些对延迟要求极高的场景中,进一步优化性能可能有所必要。
Laravel 与 PlanetScale 的连接是通过 SSL 实现的。创建 SSL 连接常常比实际执行 SQL 查询花费更多时间。虽然 PlanetScale 通过内置的连接池能够轻松处理无限制连接并显著提升性能,但 PHP 本身的设计是“无共享”(stateless)的,这意味着每个请求结束时 PHP 都会关闭与数据库的连接。
为了避免因频繁重建连接导致的性能损耗,可以使用 Laravel Octane 来解决这一问题。Laravel Octane 的好处有两点:

  1. 保持 Laravel 应用在多个请求之间常驻内存。
  2. 重用 SQL 连接(避免每次请求都重新连接数据库)。

Bref 对 Laravel Octane 的原生支持 Bref 已原生支持 Laravel Octane。要启用这一特性,你需要修改 serverless.yml 文件中的配置,将 HTTP 处理器更改为 Octane 的处理器。将 web 函数配置更新为:

web:
  handler: Bref\LaravelBridge\Http\OctaneHandler
  runtime: php-81
  environment:
    BREF_LOOP_MAX: 250
    OCTANE_PERSIST_DATABASE_SESSIONS: 1
  events:
    - httpApi: '*'

接下来,重新部署项目:

serverless deploy

然后再次执行负载测试。


使用 Laravel Octane 的优化负载测试结果

重新运行负载测试后,我们发现以下性能改进:

  • PHP 执行时间的中位数(p50)从 75 毫秒降至 14 毫秒。
  • 95% 的请求(p95)处理时间从 130 毫秒降至不到 35 毫秒。
  • Laravel 每分钟处理的请求数增加了 1,000(虽然此处理量对于负载测试来说不是重点,我们可以随时发送更多请求以测试其峰值能力)。

结论

通过结合 AWS Lambda 的无服务器架构和 PlanetScale 的强大数据库能力,我们可以将 Laravel 应用部署到云端,以实现高性能、弹性扩展的解决方案。这种架构能够带来以下优点:

  • 即时的自动扩展,处理大量并发请求。
  • 零维护的冗余和弹性基础设施。
  • 按请求计费,节省成本。

随着工具(如 Bref 和 Laravel Octane)的支持,以及数据库像 PlanetScale 那样为无服务器应用优化的特性,开发者可以轻松构建高效的无服务器应用,同时满足现代 Web 应用对性能和可用性日益增长的要求。



使用 AWS Lambda 和 PlanetScale 实现无服务器 Laravel 应用插图

关注公众号:程序新视界,一个让你软实力、硬技术同步提升的平台

除非注明,否则均为程序新视界原创文章,转载必须以链接形式标明本文链接

本文链接:http://folen.top/2025/09/13/aws-lambda-planetscale-laravel/