生产环境配置
将 Viswoole 应用部署到生产环境时,需要对 Swoole 服务参数、PHP 配置和框架配置进行全面优化。
Swoole 服务配置
完整生产环境 server.php
php
<?php
// config/server.php - 生产环境版本
declare (strict_types=1);
use Swoole\Constant;
use Swoole\Http\Server as httpServer;
use Viswoole\HttpServer\Exception\HttpExceptionHandle;
use Viswoole\HttpServer\HttpEventHandle;
return [
'default_start_server' => env('DEFAULT_START_SERVER', 'http'),
'servers' => [
'http' => [
'type' => httpServer::class,
'exception_handle' => HttpExceptionHandle::class,
'construct' => [
// 监听地址:0.0.0.0 允许外部访问
'host' => env('SERVER_HOST', '0.0.0.0'),
// 监听端口
'port' => (int)env('SERVER_PORT', 9501),
// 运行模式:多进程模式
'mode' => SWOOLE_PROCESS,
// TCP 协议
'sock_type' => SWOOLE_SOCK_TCP,
],
'options' => [
// ===== 核心选项 =====
// 上传文件大小限制(KB),框架默认 5 * 1024(5MB),生产环境可适当调大
Constant::OPTION_UPLOAD_MAX_FILESIZE => 10 * 1024, // 10MB
// 启用 HTTP2 支持
Constant::OPTION_OPEN_HTTP2_PROTOCOL => true,
// ===== 进程配置 =====
// 守护进程运行(后台运行)
Constant::OPTION_DAEMONIZE => (bool)env('SWOOLE_DAEMONIZE', true),
// Task Worker 数量(CPU 核数或根据任务量调整)
Constant::OPTION_TASK_WORKER_NUM => (int)env('TASK_WORKER_NUM', swoole_cpu_num()),
// 启用 Task 协程支持
Constant::OPTION_TASK_ENABLE_COROUTINE => true,
// Task 最大请求数(防止内存泄漏)
Constant::OPTION_TASK_MAX_REQUEST => (int)env('TASK_MAX_REQUEST', 10000),
// ===== 性能调优 =====
// Worker 进程数(建议 = CPU 核数 × 2~4)
Constant::OPTION_WORKER_NUM => (int)env('WORKER_NUM', swoole_cpu_num() * 2),
// 每个 Worker 最大处理请求数后重启(防止内存泄漏)
Constant::OPTION_MAX_REQUEST => (int)env('MAX_REQUEST', 100000),
// Reactor 线程数(通常等于 CPU 核数)
Constant::OPTION_REACTOR_NUM => (int)env('REACTOR_NUM', swoole_cpu_num()),
// ===== 内存与缓冲区 =====
// Socket 缓冲区大小
Constant::OPTION_SOCKET_BUFFER_SIZE => 2 * 1024 * 1024, // 2MB
// 输出缓冲区大小
Constant::OPTION_BUFFER_OUTPUT_SIZE => 2 * 1024 * 1024, // 2MB
// 数据包最大长度
Constant::OPTION_PACKAGE_MAX_LENGTH => 2 * 1024 * 1024, // 2MB
// ===== 协程配置 =====
// 一键协程化 Hook 范围
Constant::OPTION_HOOK_FLAGS => SWOOLE_HOOK_ALL,
// 启用协程调度器
Constant::OPTION_ENABLE_COROUTINE => true,
// 单个协程最大栈空间(字节),8192 字节 = 8KB
Constant::OPTION_STACK_SIZE => 8192, // 8KB
// 最大协程数量
Constant::OPTION_MAX_CONCURRENCY => (int)env('MAX_COROUTINE', 100000),
// ===== 日志配置 =====
// 守护进程日志文件路径
Constant::OPTION_LOG_FILE => env('LOG_FILE', BASE_PATH . '/runtime/sysLog.log'),
// 日志级别(生产环境建议 WARNING 或更高)
Constant::OPTION_LOG_LEVEL => (int)env('LOG_LEVEL', SWOOLE_LOG_WARNING),
// ===== 连接配置 =====
// 是否启用 TCP 快速握手
Constant::OPTION_OPEN_TCP_NODELAY => true,
// Keep-Alive 探测间隔(秒),0 表示不探测
Constant::OPTION_KEEP_ALIVE_INTERVAL => 30,
// 空闲超时时间(秒)
Constant::OPTION_IDLE_TIMEOUT => 300,
// ===== 安全配置 =====
// 压缩传输(节省带宽但增加 CPU 消耗)
Constant::OPTION_HTTP_COMPRESSION => true,
// 压缩最小长度(字节)
Constant::OPTION_HTTP_COMPRESSION_MIN_LENGTH => 2048,
// 压缩级别(1-9)
Constant::OPTION_HTTP_COMPRESSION_LEVEL => 6,
],
// 事件回调
'events' => [
Constant::EVENT_REQUEST => [HttpEventHandle::class, 'onRequest'],
],
],
],
// 全局默认选项
'options' => [
Constant::OPTION_HOOK_FLAGS => SWOOLE_HOOK_ALL,
Constant::OPTION_ENABLE_COROUTINE => true,
Constant::OPTION_DAEMONIZE => (bool)env('SWOOLE_DAEMONIZE', true),
Constant::OPTION_LOG_FILE => env('LOG_FILE', BASE_PATH . '/runtime/sysLog.log'),
Constant::OPTION_WORKER_NUM => (int)env('WORKER_NUM', swoole_cpu_num()),
Constant::OPTION_TASK_WORKER_NUM => (int)env('TASK_WORKER_NUM', swoole_cpu_num()),
Constant::OPTION_MAX_REQUEST => (int)env('MAX_REQUEST', 100000),
],
// 全局事件
'events' => [],
];关键参数详解
进程模型参数
| 参数 | 开发环境推荐 | 生产环境推荐 | 说明 |
|---|---|---|---|
worker_num | swoole_cpu_num() | swoole_cpu_num() * 2~4 | Worker 进程数 |
task_worker_num | swoole_cpu_num() | swoole_cpu_num() | Task Worker 数 |
reactor_num | 默认值 | swoole_cpu_num() | Reactor 线程数 |
daemonize | false | false(使用 systemd/supervisor 管理时) | 守护进程模式 |
max_request | 100000 | 10000~100000 | Worker 最大请求数 |
Worker 数量计算公式:
text
Worker 数量 = CPU 核心数 × 每核心承载系数
- CPU 密集型: × 1~2
- IO 密集型(推荐): × 2~4
- 混合型: × 2~3示例(8 核服务器):
php
// IO 密集型应用(Web API)
'worker_num' => 24, // 8核 × 3
// CPU 密集型应用(数据处理)
'worker_num' => 8, // 8核 × 1内存管理参数
| 参数 | 推荐值 | 说明 |
|---|---|---|
max_coroutine | 100000 | 最大并发协程数 |
stack_size | 8192 (8KB) | 协程栈大小 |
socket_buffer_size | 2M | Socket 缓冲区 |
buffer_output_size | 2M | 输出缓冲区 |
package_max_length | 2M | 最大数据包 |
注意:
max_coroutine × stack_size会占用虚拟内存,需确保服务器内存充足。100000 个协程 × 8KB ≈ 800MB 虚拟内存(实际物理内存按需分配)。
日志参数
| 参数 | 开发环境 | 生产环境 | 说明 |
|---|---|---|---|
log_file | sysLog.log | /var/log/app/swoole.log | 日志文件路径 |
log_level | SWOOLE_LOG_INFO | SWOOLE_LOG_WARNING | 日志级别 |
日志文件位置建议:
bash
# Linux 标准日志目录
/var/log/app/
├── swoole.log # Swoole 系统日志
├── app/
│ ├── error.log # 应用错误日志
│ └── access.log # 访问日志.env 生产环境配置
ini
; ============================================
; 生产环境 .env 配置模板
; ============================================
; --- 应用基础(对应 app.php,env() 内部会将键名转为大写)---
APP_NAME=MyProductionApp
APP_ENV=production
APP_DEBUG=false # 必须 false!
APP_URL=https://api.example.com
DEFAULT_TIMEZONE=Asia/Shanghai # 对应 app.php 的 env('default_timezone', ...)
; --- Swoole 服务 ---
SERVER_HOST=0.0.0.0
SERVER_PORT=9501
SWOOLE_DAEMONIZE=true # 使用 systemd 管理时必须设为 false,见下文说明
WORKER_NUM=16
TASK_WORKER_NUM=8
MAX_REQUEST=50000
MAX_COROUTINE=100000
LOG_LEVEL=2 # SWOOLE_LOG_WARNING
LOG_FILE=/var/log/app/swoole.log
; --- 数据库(对应 database.php,环境变量名为 DATABASE_*)---
DATABASE_DEFAULT=default
DATABASE_HOST=127.0.0.1
DATABASE_PORT=3306
DATABASE_NAME=production_db
DATABASE_USER=app_user
DATABASE_PASSWORD=<strong_password_here>
; --- Redis ---
REDIS_HOST=127.0.0.1
REDIS_PORT=6379
REDIS_PASSWORD=<redis_password>
REDIS_DB=0
; --- 缓存(对应 cache.php 的 env('cache.store', ...))---
CACHE_STORE=redis # 需在 cache.php 中配置 redis store
; --- 安全 ---
APP_KEY=<generate_with_php_viswoole_key_generate>
CORS_ORIGIN=https://www.example.com注意:
config/log.php中的default、trace_source、console均为硬编码值,不通过环境变量配置,因此.env中无需设置LOG_*变量。如需按环境差异化配置日志,请自行修改log.php引入env()调用。
PHP 配置优化
php.ini 关键参数
ini
; ============================================
; 生产环境 php.ini 推荐配置
; ============================================
; --- 性能相关 ---
realpath_cache_size = 4096k
realpath_cache_ttl = 600
opcache.enable = 1
opcache.memory_consumption = 256
opcache.interned_strings_buffer = 16
opcache.max_accelerated_files = 20000
opcache.revalidate_freq = 60
opcache.validate_timestamps = 0 # 生产环境设为 0(不自动检测文件变更,提升性能),开发环境设为 1
opcache.save_comments = 1
opcache.fast_shutdown = 1
opcache.enable_cli = 1 # CLI 模式也启用(Swoole 需要)
; --- 内存限制 ---
memory_limit = 512M # 根据实际需求调整
; --- 执行时间 ---
max_execution_time = 30 # Swoole 中主要受 request_slowlog_timeout 控制
max_input_time = 60
; --- 文件上传 ---
upload_max_filesize = 20M
post_max_size = 20M
max_file_uploads = 20
; --- 错误报告(生产环境关闭)---
display_errors = Off
display_startup_errors = Off
error_reporting = E_ALL & ~E_NOTICE & ~E_DEPRECATED & ~E_STRICT
log_errors = On
error_log = /var/log/app/php_errors.log
; --- Session ---
session.save_handler = redis # 使用 Redis 存储 session
session.save_path = "tcp://127.0.0.1:6379"
session.gc_maxlifetime = 7200
session.cookie_httponly = Yes
session.cookie_secure = Yes # HTTPS 时开启
session.use_strict_mode = Yes
session.sid_length = 48
; --- 其他 ---
expose_php = Off # 隐藏 PHP 版本信息
date.timezone = Asia/ShanghaiNginx 反向代理配置
基础配置
nginx
upstream viswoole_backend {
least_conn; # 最少连接负载均衡
server 127.0.0.1:9501 weight=5;
server 127.0.0.1:9502 weight=5;
# 可添加更多实例...
keepalive 64; # 保持长连接
}
server {
listen 80;
server_name api.example.com;
# 强制 HTTPS(可选)
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name api.example.com;
# SSL 证书配置
ssl_certificate /etc/nginx/ssl/example.com.crt;
ssl_certificate_key /etc/nginx/ssl/example.com.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
# 访问日志
access_log /var/log/nginx/api.access.log;
error_log /var/log/nginx/api.error.log;
# 客户端请求体大小限制
client_max_body_size 20m;
# 代理超时设置
proxy_connect_timeout 10s;
proxy_send_timeout 60s;
proxy_read_timeout 120s;
location / {
proxy_pass http://viswoole_backend;
# 传递真实 IP
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_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# Swoole 友好设置
proxy_buffering off; # 禁用 nginx 缓冲(让 Swoole 自己控制)
proxy_cache off;
}
# 静态资源直接由 Nginx 处理(可选)
location ~* .(jpg|jpeg|png|gif|ico|css|js|svg|woff|woff2)$ {
expires 30d;
add_header Cache-Control "public, immutable";
try_files $uri =404;
}
}进程管理
systemd 服务单元
创建 /etc/systemd/system/viswoole.service:
重要:使用 systemd 管理进程时,
.env中的SWOOLE_DAEMONIZE必须设为false。systemd 要求服务进程在前台运行,若启用守护进程模式(true),主进程会立即退出导致 systemd 认为服务已停止并不断重启。
ini
[Unit]
Description=Viswoole HTTP Server
After=network.target mysql.service redis.service
Requires=mysql.service redis.service
[Service]
Type=simple
User=www-data
Group=www-data
WorkingDirectory=/var/www/app
# 启动命令(前台运行,由 systemd 管理 daemonize)
# 确保 .env 中 SWOOLE_DAEMONIZE=false
ExecStart=/usr/local/bin/php viswoole server:start --host=0.0.0.0 --port=9501
ExecReload=/usr/local/bin/php viswoole server:reload
ExecStop=/usr/local/bin/php viswoole server:close
# 自动重启策略
Restart=on-failure
RestartSec=5
StartLimitIntervalSec=60
StartLimitBurst=3
# 资源限制
LimitNOFILE=65535
LimitNPROC=65535
# 日志
StandardOutput=journal
StandardError=journal
SyslogIdentifier=viswoole
[Install]
WantedBy=multi-user.target使用方法:
bash
# 启动服务
sudo systemctl start viswoole
# 设置开机自启
sudo systemctl enable viswoole
# 查看状态
sudo systemctl status viswoole
# 重载服务
sudo systemctl reload viswoole
# 重启服务
sudo systemctl restart viswoole
# 查看日志
sudo journalctl -u viswoole -fSupervisor 配置(备选方案)
ini
[program:viswoole]
command=/usr/local/bin/php %(here)s/viswoole server:start
directory=/var/www/app
autostart=true
autorestart=true
startretries=3
user=www-data
redirect_stderr=true
stdout_logfile=/var/log/app/supervisor-viswoole.log
environment=APP_ENV="production"安全加固清单
1. 网络层
- 使用 HTTPS(SSL/TLS 终结在 Nginx)
- 配置防火墙规则,仅开放必要端口
- 禁止直接访问 Swoole 端口(9501 等),通过 Nginx 代理
- 配置速率限制
2. 应用层
APP_DEBUG=false- 设置强密码的
APP_KEY - 配置 CORS 白名单
- 移除或保护调试端点
- 定期更新依赖包
3. 文件系统
.env文件权限设为600runtime/目录权限设为755- 禁止执行
vendor/和config/下的 PHP 文件 - 敏感文件不在 Web 根目录
4. 进程安全
- 以非 root 用户运行(如 www-data)
- 限制文件描述符数量
- 配置 cgroup 资源限制
