thinkphp本身不内置负载均衡能力,所有请求分发必须由外部反向代理(如nginx)完成;upstream必须定义在http块顶层,不可置于server或location内,否则报错unknown directive "upstream"。

ThinkPHP 本身不内置负载均衡能力,所有请求分发必须由外部反向代理(如 Nginx)完成;直接在 PHP 层做轮询或重定向不仅性能差、状态难维护,还会绕过健康检查和连接复用机制。
upstream 配置写在哪?别塞进 server 块里
Nginx 的 upstream 必须定义在 http 块内,不能放在 server 或 location 里——否则会报错 unknown directive "upstream"。
- 正确位置:
/etc/nginx/nginx.conf的http { ... }区域,或/etc/nginx/conf.d/thinkphp.conf中顶层作用域 - 常见错误:把
upstream写在server { ... }里面,reload 时nginx -t直接失败 - 多个集群可共存:比如
upstream thinkphp_api和upstream thinkphp_admin,互不影响
proxy_pass 后面的斜杠影响路径转发
proxy_pass 的末尾是否有 /,决定后端收到的 URI 是否被重写。ThinkPHP 的 public/index.php 路由依赖原始路径,错配会导致 404 或路由失效。
- 写成
proxy_pass http://thinkphp_cluster;(无尾部/):原始请求路径完整透传,如/user/login→ 后端收到/user/login - 写成
proxy_pass http://thinkphp_cluster/;(有尾部/):Nginx 会剥离location /匹配的部分,/user/login→ 后端收到user/login(丢失开头/,ThinkPHP 路由解析失败) - 验证方法:curl -I 访问任意接口,看响应头中
X-Upstream-Addr是否出现,再查对应后端 access.log 中的request_uri
ip_hash 不能和 health_check 混用
Nginx 开源版的 health_check(需配合 ngx_http_upstream_module)与 ip_hash 不兼容——启用 ip_hash 后,即使某台后端宕机,流量仍会被固定路由过去,健康检查形同虚设。
- 真实场景:用户 A 的 IP 被 hash 到
192.168.1.10,该服务器挂了,但后续所有请求仍打过去,返回 502 - 替代方案:不用
ip_hash,改用 Redis 存储 Session,并在 ThinkPHP 中配置session.type = redis和session.options.host - 若必须保持会话粘性,且无法改造 Session,可用
least_conn+ 定期人工剔除故障节点,或升级到 Nginx Plus 使用match+health_check高级功能
后端服务器的 public 目录权限和 index.php 入口必须一致
所有 ThinkPHP 实例的 Web 根目录必须指向 public/,且 index.php 文件内容、版本、环境配置(如 .env 中的 APP_DEBUG)需完全一致;否则会出现部分机器返回 500、部分返回空白、或路由规则不统一。
- 典型问题:一台机器用了 TP6.3,另一台还是 TP6.1,
Route::rule()行为差异导致 404 - 部署建议:用 rsync 或 Ansible 统一推送代码,禁止手工修改单台服务器的
public/index.php或config/app.php - 快速验证:访问每台后端的
http://192.168.x.x/public/index.php?s=api/test,确认返回相同结构的 JSON
真正麻烦的从来不是配置几行 upstream,而是让所有后端实例在运行时行为完全一致——Session 存哪、日志写哪、缓存清哪、数据库连接池怎么管,这些细节一旦错位,负载均衡反而放大故障面。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











