PHP 怎么用RoadRunner

wen PHP项目 2

本文目录导读:

PHP 怎么用RoadRunner

  1. 什么是 RoadRunner
  2. 安装 RoadRunner
  3. 创建配置文件 .rr.yaml
  4. 创建入口文件 worker.php
  5. 集成框架示例
  6. 启动 RoadRunner
  7. 高级配置示例
  8. 性能优化建议
  9. 监控和调试
  10. 常见问题解决

我将详细介绍如何在 PHP 项目中使用 RoadRunner,这是一个高性能的 PHP 应用服务器。

什么是 RoadRunner

RoadRunner 是一个基于 Go 语言编写的高性能 PHP 应用服务器,它通过保持 PHP 进程常驻内存来大幅提升性能。

安装 RoadRunner

使用 Composer 安装

# 创建项目
composer create-project spiral/roadrunner-demo my-app
# 或添加到现有项目
composer require spiral/roadrunner

下载二进制文件

# 使用 Composer 脚本下载
composer require spiral/roadrunner-cli
./vendor/bin/rr get
# 或直接下载
wget https://github.com/spiral/roadrunner/releases/download/v2.12.0/roadrunner-2.12.0-linux-amd64.tar.gz
tar -xzf roadrunner-2.12.0-linux-amd64.tar.gz

创建配置文件 .rr.yaml

version: "2.7"
# HTTP 服务器配置
http:
  address: "0.0.0.0:8080"
  middleware:
    - gzip
    - static
    - headers
  static:
    dir: "public"
    forbid:
      - ".php"
  pool:
    num_workers: 10
    max_jobs: 1000
    allocate_timeout: 60s
    destroy_timeout: 60s
# 日志配置
logs:
  mode: production
  level: info
  output: stderr
# 服务配置
service:
  # 用于监控
  metrics:
    listen: "tcp://0.0.0.0:2112"
# 核心配置
rpc:
  listen: "tcp://127.0.0.1:6001"

创建入口文件 worker.php

<?php
require __DIR__ . '/vendor/autoload.php';
use Spiral\RoadRunner;
use Nyholm\Psr7\Factory\Psr17Factory;
use Nyholm\Psr7\Response;
use Nyholm\Psr7\ServerRequest;
use Spiral\RoadRunner\Http\PSR7Worker;
// 创建 PSR-7 工厂
$factory = new Psr17Factory();
// 创建 PSR-7 Worker
$worker = new PSR7Worker(
    RoadRunner\Worker::create(),
    $factory,
    $factory,
    $factory
);
// 主循环
while ($req = $worker->waitRequest()) {
    try {
        // 处理请求
        $r = $req->getMethod() . ' ' . $req->getUri() . '<br>';
        // 创建响应
        $response = new Response(
            200,
            ['Content-Type' => 'text/html'],
            'Hello RoadRunner!<br>' . $r
        );
        // 发送响应
        $worker->respond($response);
    } catch (\Throwable $e) {
        $worker->getWorker()->error($e->getMessage());
    }
}

集成框架示例

Laravel 集成

# 安装 laravel 桥接包
composer require spiral/roadrunner-laravel

配置 laravel-worker.php

<?php
require __DIR__ . '/vendor/autoload.php';
require __DIR__ . '/bootstrap/app.php';
use Spiral\RoadRunner\Laravel\ServiceProvider;
use Illuminate\Http\Request;
// 启动 Laravel 应用
$app = require_once __DIR__ . '/bootstrap/app.php';
$app->make(Illuminate\Contracts\Console\Kernel::class)->bootstrap();
use Spiral\RoadRunner;
use Spiral\RoadRunner\Http\PSR7Worker;
$worker = RoadRunner\Worker::create();
$psr7Worker = new PSR7Worker(
    $worker,
    new \Nyholm\Psr7\Factory\Psr17Factory(),
    new \Nyholm\Psr7\Factory\Psr17Factory(),
    new \Nyholm\Psr7\Factory\Psr17Factory()
);
while ($req = $psr7Worker->waitRequest()) {
    try {
        // 转换为 Laravel 请求
        $request = \Spiral\RoadRunner\Laravel\Adaption::adaptRequest($req);
        // 处理请求
        $response = $app->handle($request);
        // 转换为 PSR-7 响应
        $psr7Response = \Spiral\RoadRunner\Laravel\Adaption::adaptResponse($response);
        // 发送响应
        $psr7Worker->respond($psr7Response);
    } catch (\Throwable $e) {
        $psr7Worker->getWorker()->error($e->getMessage());
    }
}

Symfony 集成

<?php
require __DIR__ . '/vendor/autoload.php';
use Spiral\RoadRunner;
use Spiral\RoadRunner\Http\PSR7Worker;
use Nyholm\Psr7\Factory\Psr17Factory;
use Symfony\Bridge\PsrHttpMessage\Factory\PsrHttpFactory;
use Symfony\Bridge\PsrHttpMessage\Factory\HttpFoundationFactory;
// 创建 PSR-7 Worker
$worker = new PSR7Worker(
    RoadRunner\Worker::create(),
    new Psr17Factory(),
    new Psr17Factory(),
    new Psr17Factory()
);
// 创建 Symfony 应用
$kernel = new AppKernel('prod', false);
while ($req = $worker->waitRequest()) {
    try {
        // 转换请求
        $symfonyRequest = (new HttpFoundationFactory())->createRequest($req);
        // 处理请求
        $symfonyResponse = $kernel->handle($symfonyRequest);
        // 转换响应
        $psr7Response = (new PsrHttpFactory(
            new Psr17Factory(),
            new Psr17Factory(),
            new Psr17Factory(),
            new Psr17Factory()
        ))->createResponse($symfonyResponse);
        // 发送响应
        $worker->respond($psr7Response);
    } catch (\Throwable $e) {
        $worker->getWorker()->error($e->getMessage());
    }
}

启动 RoadRunner

# 开发模式
./rr serve -v -d
# 生产模式
./rr serve -c .rr.yaml
# 热重载
./rr serve -w
# 重置 workers
./rr reset
# 查看状态
./rr status

高级配置示例

version: "2.7"
http:
  address: "0.0.0.0:8080"
  middleware:
    - gzip
    - static
    - headers
    - cors
  pool:
    num_workers: 50
    max_jobs: 1000
    allocate_timeout: 60s
    destroy_timeout: 60s
    supervisor:
      watch_tick: 10s
      ttl: 3600s
      idle_ttl: 300s
# WebSocket 配置
websocket:
  broker:
    address: "tcp://127.0.0.1:6002"
# gRPC 配置
grpc:
  listen: "tcp://0.0.0.0:9001"
  proto:
    - "proto/helloworld.proto"
# 数据库连接池
pool:
  num_workers: 10
# 缓存配置
cache:
  type: "in-memory"

性能优化建议

# 生产环境优化配置
http:
  pool:
    num_workers: 100
    max_jobs: 2000
    allocate_timeout: 120s
    destroy_timeout: 120s
    supervisor:
      watch_tick: 1s
      max_worker_memory: 256
# 启用 HTTP/2
http:
  ssl:
    address: "0.0.0.0:443"
    redirect: true
    cert: "/etc/ssl/certs/server.crt"
    key: "/etc/ssl/private/server.key"

监控和调试

# 查看 metrics
curl http://localhost:2112/metrics
# 重置所有 workers
./rr reset
# 查看 worker 状态
./rr jobs:list

常见问题解决

内存泄漏

// 在 worker.php 中定期重启
if (memory_get_usage(true) > 256 * 1024 * 1024) {
    // 重置或退出 worker
    exit(0);
}

热重载配置

http:
  pool:
    supervisor:
      watch_tick: 10s
      ttl: 3600s
      idle_ttl: 300s

RoadRunner 的核心优势:

  • 🚀 高性能:常驻内存,避免每次请求都创建进程
  • 🔄 热重载:快速部署和更新代码
  • 📊 可监控:内置 metrics 和日志功能
  • 🔌 协议支持:HTTP、gRPC、WebSocket 等

使用 RoadRunner 可以显著提升 PHP 应用的性能和稳定性,特别是在高并发场景下。

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