OneinStack 是传统 LNMP 环境Hyperf 是常驻内存的 Swoole 应用两者结合的核心思路是Nginx 做反向代理 Supervisor 守护进程 手动安装 Swoole 扩展。 --- 架构概览 用户请求 ↓ Nginx(OneinStack 管理,443/80)↓ proxy_pass Hyperf Swoole Server(127.0.0.1:9501)↓ Supervisor 守护进程 ↓ PHP8.x Swoole 扩展(OneinStack 安装)--- 第一步OneinStack 安装 PHP Swoole 扩展 OneinStack 默认安装 PHP-FPMHyperf 不用 FPM但需要同一套 PHP 二进制 Swoole 扩展。1.1安装 OneinStack选 PHP8.1/8.2不需要 FPM 也没关系# 下载并安装选择 Nginx PHP不需要 Apachewget-chttp://mirrors.linuxeye.com/oneinstack-full.tar.gztarxzf oneinstack-full.tar.gzcdoneinstack# 非交互式安装Nginx 1.24 PHP 8.1CLI 模式够用./install.sh--nginx_option1--php_option8--php82y--phpcache_option1--db_option2--dbinstallmethod1--dbrootpwdyour_db_password1.2安装 Swoole 扩展 OneinStack 的 PHP 在 /usr/local/php用它的 pecl 安装# 确认 PHP 路径/usr/local/php/bin/php-v# 安装编译依赖yuminstall-ygcc gcc-c autoconf automake# CentOS# apt install -y gcc g autoconf automake # Ubuntu# 用 pecl 安装 Swoole推荐 5.x 对应 PHP 8.x/usr/local/php/bin/peclinstallswoole# 安装过程中的选项全部回车默认或按需选# enable coroutine? yes# enable openssl? yes# enable http2? yes# enable mysqlnd? yes# enable swoole_curl? yes# 写入 php.iniechoextensionswoole.so/usr/local/php/etc/php.iniechoswoole.use_shortnameOff/usr/local/php/etc/php.ini# 验证/usr/local/php/bin/php--riswoole1.3安装其他必要扩展 /usr/local/php/bin/peclinstallredisechoextensionredis.so/usr/local/php/etc/php.ini# 验证所有扩展/usr/local/php/bin/php-m|grep-Eswoole|redis|pdo|json|mbstring--- 第二步部署 Hyperf 项目# 项目目录建议放在 OneinStack 的 web 根目录之外mkdir-p/data/www/hyperf-appcd/data/www/hyperf-app# 拉取代码gitclone https://github.com/your-org/your-hyperf-app.git.# 用 OneinStack 的 PHP Composer 安装依赖/usr/local/php/bin/php /usr/local/bin/composerinstall--no-dev --optimize-autoloader# 复制环境配置cp.env.example .envvim.env# 填写数据库、Redis 等配置# 生成注解缓存生产必做加速启动/usr/local/php/bin/php bin/hyperf.php di:init-proxy# 设置权限chown-Rwww:www /data/www/hyperf-appchmod-R755/data/www/hyperf-appchmod-R777/data/www/hyperf-app/runtime Hyperf 生产配置 config/config.php?phpreturn[app_nameenv(APP_NAME,hyperf),app_envenv(APP_ENV,production), // 生产环境开启扫描缓存避免每次启动重新扫描注解scan_cacheableenv(APP_ENV)production,];Server 配置 config/autoload/server.php?phpreturn[modeSWOOLE_PROCESS, // 生产用 PROCESS 模式支持热重载servers[[namehttp,typeServer::SERVER_HTTP,host0.0.0.0,port9501,sock_typeSWOOLE_SOCK_TCP,callbacks[Event::ON_REQUEST[Hyperf\HttpServer\Server::class,onRequest],],],],settings[enable_coroutinetrue,worker_numswoole_cpu_num()*2, // CPU 核数 *2pid_fileBASE_PATH./runtime/hyperf.pid,open_tcp_nodelaytrue,max_coroutine100000,open_http2_protocoltrue,max_request100000,socket_buffer_size2*1024*1024,buffer_output_size2*1024*1024, // 日志输出到文件不要输出到 stdoutSupervisor 会重定向log_fileBASE_PATH./runtime/swoole.log,log_levelSWOOLE_LOG_WARNING,],];--- 第三步Supervisor 进程守护 OneinStack 通常不预装 Supervisor需要手动安装。# CentOSyuminstall-ysupervisor systemctlenablesupervisord systemctl start supervisord# Ubuntuaptinstall-ysupervisor systemctlenablesupervisor systemctl start supervisor Supervisor 配置文件# /etc/supervisord.d/hyperf-app.conf (CentOS)# /etc/supervisor/conf.d/hyperf-app.conf (Ubuntu)[program:hyperf-app];使用 OneinStack 的 PHP 二进制command/usr/local/php/bin/php /data/www/hyperf-app/bin/hyperf.php startdirectory/data/www/hyperf-appuserwwwautostarttrueautorestarttrue;进程异常退出后等待3秒重启startsecs3startretries5stopwaitsecs60;等待 Hyperf 优雅停机处理完当前请求stopsignalSIGTERM;Hyperf 监听 SIGTERM 做优雅停机;日志stdout_logfile/data/logs/hyperf-app-stdout.logstdout_logfile_maxbytes50MBstdout_logfile_backups10stderr_logfile/data/logs/hyperf-app-stderr.logstderr_logfile_maxbytes50MB;环境变量也可以写在 .env 里environmentAPP_ENVproduction,TZAsia/Shanghai# 创建日志目录mkdir-p/data/logschownwww:www /data/logs# 重载 Supervisor 配置supervisorctl reread supervisorctl update supervisorctl start hyperf-app# 查看状态supervisorctl status hyperf-app --- 第四步Nginx 反向代理配置 在 OneinStack 中添加虚拟主机不要用 PHP-FPM改为 proxy_pass 到 Swoole。4.1创建 Nginx 虚拟主机# OneinStack 的 vhost 管理脚本cd/usr/local/oneinstack ./vhost.sh# 选择 Nginx填写域名选择不使用 PHP或直接手动编辑配置4.2Nginx 配置文件HTTP WebSocket# /usr/local/nginx/conf/vhost/api.yourdomain.com.confupstream hyperf_backend{server127.0.0.1:9501;keepalive64;# 保持长连接减少握手开销}server{listen80;server_name api.yourdomain.com;# 强制跳转 HTTPSreturn301https://$host$request_uri;}server{listen443ssl http2;server_name api.yourdomain.com;# OneinStack 生成的证书路径ssl_certificate /usr/local/nginx/conf/ssl/api.yourdomain.com.crt;ssl_certificate_key /usr/local/nginx/conf/ssl/api.yourdomain.com.key;ssl_protocols TLSv1.2 TLSv1.3;ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;ssl_session_cache shared:SSL:10m;ssl_session_timeout 10m;# 日志access_log /data/wwwlogs/api.yourdomain.com_access.log combined;error_log /data/wwwlogs/api.yourdomain.com_error.log;# 安全头add_header X-Frame-OptionsSAMEORIGIN;add_header X-Content-Type-Optionsnosniff;add_header X-XSS-Protection1; modeblock;# 静态文件直接由 Nginx 处理如果有location ~*\.(js|css|png|jpg|jpeg|gif|ico|svg|woff2?)${root /data/www/hyperf-app/public;expires 30d;access_log off;}# HTTP API 请求location /{proxy_pass http://hyperf_backend;proxy_http_version1.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 支持如果 Hyperf 有 WS 服务proxy_set_header Upgrade$http_upgrade;proxy_set_header Connectionupgrade;proxy_connect_timeout 60s;proxy_send_timeout 60s;proxy_read_timeout 60s;# 关闭缓冲适合 SSE / 流式响应proxy_buffering off;}}# 测试并重载 Nginx/usr/local/nginx/sbin/nginx-t/usr/local/nginx/sbin/nginx-sreload --- 第五步平滑重启零停机更新代码 Hyperf 支持 SIGUSR1 信号触发 Worker 平滑重启Master 进程不重启不断连接。# 部署脚本 /data/scripts/deploy.sh#!/bin/bashset-eAPP_DIR/data/www/hyperf-appPHP/usr/local/php/bin/phpPID_FILE$APP_DIR/runtime/hyperf.pidecho 拉取最新代码...cd$APP_DIRgitpull origin mainecho 安装/更新依赖...$PHP/usr/local/bin/composerinstall--no-dev --optimize-autoloaderecho 重新生成注解缓存...$PHPbin/hyperf.php di:init-proxyecho 平滑重启 Worker 进程...if[-f$PID_FILE];thenMASTER_PID$(cat$PID_FILE)kill-USR1$MASTER_PIDecho 已发送 SIGUSR1 到 PID$MASTER_PIDWorker 正在平滑重启...elseecho PID 文件不存在通过 Supervisor 重启...supervisorctl restart hyperf-appfiecho 部署完成chmodx /data/scripts/deploy.sh# 执行部署/data/scripts/deploy.sh ▎ 注意SIGUSR1 只重启 Worker不重启 Master已有连接不会断开。如果改了 server.php 配置需要完整重启supervisorctl ▎ restart hyperf-app。 --- 第六步日志与监控 日志配置 config/autoload/logger.php?phpreturn[default[handler[classMonolog\Handler\RotatingFileHandler::class,constructor[filenameBASE_PATH./runtime/logs/hyperf.log,maxFiles30, // 保留30天levelMonolog\Logger::INFO,],],formatter[classMonolog\Formatter\JsonFormatter::class,],],];系统服务开机自启# 确保 Supervisor 开机启动systemctlenablesupervisord# CentOSsystemctlenablesupervisor# Ubuntu# 验证 Hyperf 随 Supervisor 自启supervisorctl status --- 关键注意事项 ┌────────────────────────────┬───────────────────────────────────────────────────────────────┐ │ 问题 │ 说明 │ ├────────────────────────────┼───────────────────────────────────────────────────────────────┤ │swoole.use_shortnameOff │ 必须关闭否则 Hyperf 启动报错 │ ├────────────────────────────┼───────────────────────────────────────────────────────────────┤ │ 不要用 php-fpm 处理 Hyperf │ Nginx 直接 proxy_passFPM 只处理其他 PHP 站点 │ ├────────────────────────────┼───────────────────────────────────────────────────────────────┤ │scan_cacheabletrue │ 生产环境必开否则每次请求都扫描注解性能极差 │ ├────────────────────────────┼───────────────────────────────────────────────────────────────┤ │ worker_num │ 建议 CPU 核数 ×2不要设太大 │ ├────────────────────────────┼───────────────────────────────────────────────────────────────┤ │stopwaitsecs60│ Supervisor 等待时间要Hyperf 的 max_wait_time │ ├────────────────────────────┼───────────────────────────────────────────────────────────────┤ │ 日志目录权限 │ runtime/ 必须 www 用户可写 │ ├────────────────────────────┼───────────────────────────────────────────────────────────────┤ │ 多个 Hyperf 服务 │ 每个服务用不同端口9501、9502...各自一个 Supervisor 配置 │ └────────────────────────────┴───────────────────────────────────────────────────────────────┘