PHP 怎么PHP 预热

wen PHP项目 1

本文目录导读:

PHP 怎么PHP 预热

  1. 预热 OpCache(最常用、最基础)
  2. 预热框架(Laravel / Symfony / ThinkPHP)
  3. 预热数据库连接 & 查询(连接池)
  4. 预热对象缓存(Redis / Memcached)
  5. 预热 JIT(PHP 8.0+)
  6. 多进程/常驻内存框架预热(Swoole / Workerman)
  7. 总结:你应该怎么做?

在 PHP 中,“预热”(Warmup)通常是指在正式接收用户请求之前,预先加载代码、建立数据库连接、填充缓存(如 OpCache、对象缓存)等操作,以消除第一次请求时的“冷启动”延迟(如编译、文件加载、连接建立)。

根据你的具体场景(Web 应用、CLI 脚本、常驻内存框架),预热的方法不同,以下是几种最常见的 PHP 预热方案:

预热 OpCache(最常用、最基础)

PHP 7/8 内置了 OpCache,默认情况下,第一个请求会触发编译并缓存 Opcode,后续请求直接使用缓存,可以在部署后主动访问所有关键页面来强制生成缓存。

方法:编写一个简单的预热脚本,请求所有重要 URL。

// warmup.php
$urls = [
    'https://yoursite.com/',
    'https://yoursite.com/api/status',
    'https://yoursite.com/product/1',
    // ... 所有关键路由
];
foreach ($urls as $url) {
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_TIMEOUT, 5);
    curl_exec($ch);
    curl_close($ch);
    echo "Warmed: $url\n";
}

部署时执行

# 在部署脚本的最后运行
php warmup.php

或者直接触发 OpCache 预热(需要 root/CLI 权限)

# 扫描目录并编译所有 PHP 文件
php -d opcache.enable_cli=1 -r "opcache_compile_file('/path/to/your/app/index.php');"
# 批量编译(使用 find)
find /var/www -name "*.php" -exec php -d opcache.enable_cli=1 -r "opcache_compile_file('{}');" \;

预热框架(Laravel / Symfony / ThinkPHP)

现代框架启动时加载大量服务提供者、配置文件,可以通过在部署后执行框架内置的“优化”命令来预热。

Laravel 示例

# 缓存配置、路由、视图
php artisan optimize
php artisan config:cache
php artisan route:cache
php artisan view:cache
# 预热所有服务提供者
php artisan serve --no-reload  # 或者通过请求框架入口

Symfony 示例

php bin/console cache:warmup --env=prod

ThinkPHP 示例

php think optimize:route
php think optimize:config

预热数据库连接 & 查询(连接池)

如果使用持久连接或连接池(如 Swoole、RoadRunner、Hyperf),需要预先建立连接。

原生 PDO 持久连接

// 在后台进程中预先建立连接
$pdo = new PDO('mysql:host=localhost;dbname=test', 'user', 'pass', [
    PDO::ATTR_PERSISTENT => true
]);
// 模拟一次查询,触发真实连接
$stmt = $pdo->query("SELECT 1");

在 Swoole/Hyperf 中预创建连接池

// config/autoload/databases.php
return [
    'default' => [
        'pool' => [
            'min_connections' => 10,  // 启动时创建 10 个连接
            'max_connections' => 50,
        ],
    ],
];

预热对象缓存(Redis / Memcached)

如果应用依赖缓存来存储数据(如 Session、配置、API 响应),可以在启动时填充常用键。

// 预热脚本
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
// 模拟加载热门数据
$hotProducts = getHotProductsFromDB(); // 从数据库获取
foreach ($hotProducts as $product) {
    $redis->setex('product:' . $product['id'], 3600, json_encode($product));
}

预热 JIT(PHP 8.0+)

如果使用了 JIT(Just-In-Time 编译),可以预先触发 JIT 编译热点代码。

// 在 php.ini 中配置
opcache.jit = tracing
opcache.jit_buffer_size = 100M
// 通过运行代表性请求来触发 JIT 编译(JIT 自动执行,无需手动调用)

多进程/常驻内存框架预热(Swoole / Workerman)

这类框架通常以守护进程运行,预热是整个生命周期的一部分。

Workerman 示例:在 onWorkerStart 回调中预热。

$worker->onWorkerStart = function($worker) {
    // 仅在工作进程启动时执行一次
    if ($worker->id === 0) {
        // 预热路由、初始化全局资源
        require_once __DIR__ . '/vendor/autoload.php';
        // 加载所有必要类
        new \App\Controllers\HomeController();
    }
};

Swoole 示例:使用 beforeStart 事件。

$server->on('beforeStart', function ($server) {
    // 预热代码,比如建立连接池、加载配置文件
    echo "Pre-warming database connections...\n";
    Database::initPool();
});

你应该怎么做?

场景 推荐预热方法
简单的共享主机/FPM 部署后运行 curl 脚本请求首页 + OpCache 编译
Laravel/Symfony 运行框架的 optimize:cache 系列命令
高并发 API(Swoole/Hyperf) 设置连接池最小连接数,在启动时加载所有服务
首次请求很慢 检查 OpCache 是否开启,并使用 opcache_compile_file 编译所有文件
CI/CD 自动部署 在部署脚本中加入预热步骤(curl + artisan cache)

最后提醒:预热只在部署后第一次启动时有效,如果代码本身有性能缺陷(如 N+1 查询、无索引),预热只能缓解“冷启动”问题,不能替代真正的性能优化。

抱歉,评论功能暂时关闭!