生产环境配置

本指南带你逐项完成 Viswoole 应用的生产环境(Production)部署:关闭调试、守护进程启动、制定重启策略、开启路由缓存,并梳理日志与连接池的注意事项。

关闭调试模式

框架默认开启调试模式(config/app.php'debug' => env('app_debug', true),默认值为 true)。生产环境必须在项目根目录 .env 中显式关闭:

ini
app_debug=false

调试模式影响框架的异常输出与调试行为;config/database.phpdebug 也默认引用同一变量,关闭后数据库调试输出一并关闭。修改后需重启服务生效。

必须显式设置

由于默认值是 true,生产环境漏配即开启。部署检查清单中请将 app_debug=false 作为第一项核对。

守护模式启动

server:start 的完整参数

参数/选项类型默认值说明
servicestringserver.default_start_server(即 http服务名,对应 config/server.phpservers 的键名
-f, --force选项服务已运行时,先关闭再启动
-d, --daemonize选项以守护进程方式在后台运行
bash
# 前台启动(开发环境)
php viswoole server:start

# 守护进程启动(生产环境,手动管理时)
php viswoole server:start -d

守护模式下 Swoole 的运行日志写入 config/server.phpoptions[OPTION_LOG_FILE] 指定的路径,默认为 BASE_PATH/runtime/sysLog.log

与进程管理器配合时不要用 -d

若由 systemd / Supervisor 等进程管理器托管,请前台启动(不加 -d):进程管理器要求主进程保持前台,否则无法感知服务存活状态并正确重启。

重启策略

服务管理命令速查

命令作用
php viswoole server:start [服务名] [-f] [-d]启动服务
php viswoole server:reload [服务名] [-t] [-f]重载服务(-t 仅重载 Task 进程,-f 关闭全部进程后整体重启)
php viswoole server:close [服务名]关闭服务

不传服务名时操作 default_start_server 指定的默认服务。

变更生效边界

Swoole 服务由 Master / Manager / Worker 等多个进程组成,不同变更需要不同的生效方式:

变更内容生效方式
业务类实现(方法体逻辑)server:reload 重载 Worker 进程
路由定义、配置文件、.env建议完整重启
服务提供者(Provider)注册、启动期初始化逻辑必须server:close + server:start 完整重启

原因是服务提供者在进程启动阶段注册进容器(App::factory() 只执行一次),reload 重载的 Worker 进程不会重新执行完整的启动流程。

bash
# 生产环境推荐的完整重启流程
php viswoole server:close
php viswoole server:start -d

发布流程建议

发布新版本代码时统一执行 server:close + server:start 最稳妥;server:reload 仅适用于确认不影响启动期状态的小幅逻辑调整。若服务重启失败,可用 server:start -f 强制重启。

路由缓存

注解路由需要启动时扫描控制器目录并解析注解。生产环境建议开启路由缓存,将解析结果落盘,跳过重复解析:

php
// config/router.php
'cache' => [
    // 是否开启路由缓存(默认 false)
    'enable' => true,
    // 路由缓存存放目录(默认 runtime/route)
    'path' => BASE_PATH . '/runtime/route',
],
参数类型默认值说明
enableboolfalse是否开启路由缓存
pathstringBASE_PATH . '/runtime/route'缓存文件存放目录

开启后每次发布需确保缓存重新生成;当框架版本升级导致旧缓存格式不兼容时,执行:

bash
php viswoole router:clear-cache

日志要点

  • Swoole 运行日志:由 config/server.php 全局 options 控制,默认 OPTION_LOG_LEVEL => SWOOLE_LOG_WARNING(生产合理的级别)与 OPTION_LOG_FILE => runtime/sysLog.log,可将 LOG_FILE 指到磁盘容量充足的挂载点。
  • 应用日志config/log.phpconsole 控制是否同时输出到控制台,生产环境保持 false(默认值即为 false),避免守护进程下控制台输出产生额外开销。
  • runtime/ 目录需保证运行用户可写,且建议纳入日志切割/清理策略,防止磁盘写满。

日志系统的通道与级别详解见 日志

连接池要点

数据库(PDO)与 Redis 连接由框架的连接池(Connection Pool)统一管理,协程内自动获取与归还:

  1. 不要手动缓存连接——连接对象被协程上下文隔离复用,业务代码长期持有某个连接会破坏池化;
  2. 连接池随 Worker 进程启动而建立(每个 Worker 独立持有,修改数据库连接配置后需完整重启服务);
  3. 高并发场景按需调整各通道的池参数(见 数据库配置);
  4. 总连接数按 Worker 估算——Master/Manager 进程不持有池连接,启动阶段与主进程回调中的 Db/Cache 调用走一次性短连接(用完即毁),总连接数 = 单 Worker 最大占用 × Worker 数量,不会额外增加(详见 数据库配置);
  5. 避免在非 Worker 进程高频操作数据库/缓存——短连接模式下每条语句各建一次连接,高频循环会产生大量 TIME_WAIT 并显著增加耗时,此类场景请通过 Task::emit 投递到工作进程执行。

Nginx 反向代理

生产环境推荐 Nginx 作为反向代理,Swoole 服务只监听内网:

nginx
upstream viswoole_backend {
    server 127.0.0.1:9501;
    keepalive 64;
}

server {
    listen 80;
    server_name api.example.com;

    # 请求体大小需大于框架上传限制(默认 5MB)
    client_max_body_size 20m;

    location / {
        proxy_pass http://viswoole_backend;
        proxy_http_version 1.1;

        # 传递真实客户端信息
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        # WebSocket 升级支持(如需要)
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}

要点:

  • 对外只开放 Nginx 端口,用防火墙禁止外部直连 9501;
  • client_max_body_size 需大于 config/server.phpOPTION_UPLOAD_MAX_FILESIZE 的限制;
  • HTTPS 建议在 Nginx 终结(SSL 终止),或按 Swoole 文档配置 OPTION_SSL_CERT_FILE / OPTION_SSL_KEY_FILE

systemd 进程守护

创建 /etc/systemd/system/viswoole.service(前台运行,由 systemd 负责拉起与重启):

ini
[Unit]
Description=Viswoole HTTP Server
After=network.target mysql.service redis.service

[Service]
Type=simple
User=www-data
Group=www-data
WorkingDirectory=/var/www/app

# 前台启动,不加 -d(守护交给 systemd 管理)
ExecStart=/usr/local/bin/php viswoole server:start
ExecStop=/usr/local/bin/php viswoole server:close

Restart=on-failure
RestartSec=5

# Swoole 高并发依赖的文件描述符限制
LimitNOFILE=65535

[Install]
WantedBy=multi-user.target
bash
sudo systemctl daemon-reload
sudo systemctl enable --now viswoole
sudo journalctl -u viswoole -f   # 查看服务输出

下一步