零停机部署PHP:无痛应对停机问题

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

当一秒停机价值百万

\n\n

想象一下:你正在更新一个基于PHP的在线商店,通过FTP上传新版本,此时网站宕机了5分钟。五分钟就是300秒。在这段时间里,100个潜在客户流失到竞争对手那里,你不仅损失了金钱,还损失了声誉。是不是很熟悉的心痛?

\n\n

在当今世界,用户不会容忍错误,PHP服务的零停机部署不是奢侈品,而是必需品。但是,如果你的技术栈是PHP、Nginx和几台服务器,如何实现无缝部署呢?让我们通过实际案例来探讨。

\n\n

为什么PHP比看起来更复杂?

\n\n

与Node.js或Python不同,PHP在经典意义上不支持多线程。每个请求都由一个独立的PHP-FPM进程处理。这带来了限制:你不能简单地“重新加载”代码而不丢失当前会话。然而,同样的特性也赋予了我们超能力——能够在不同版本之间平滑切换流量。

\n\n

PHP部署的主要问题:

\n
    \n
  • 连接中断 — 用户丢失表单数据或会话
  • \n
  • 脏缓存 — 旧代码返回过时缓存中的数据
  • \n
  • 损坏的迁移 — 新数据库版本与旧代码不兼容
  • \n
\n\n

为了避免这些陷阱,我们使用经过验证的策略。是的,零停机部署不是魔法,而是一个清晰的计划。

\n\n

策略一:蓝绿部署

\n\n

最可靠的方法是维护两个完整的应用程序副本:“蓝色”(当前)和“绿色”(新版本)。Nginx充当负载均衡器。

\n\n

实际运作方式

\n

假设你有两台服务器:app1.example.com(蓝色)和app2.example.com(绿色)。两者都运行PHP-FPM。当前蓝色处于活动状态。你将新版本部署到绿色,进行测试,然后将Nginx切换到绿色。

\n\n

用于切换的Nginx配置示例:

\n\n
# nginx.conf\nupstream php_backend {\n    # 首先激活蓝色\n    server app1.example.com:9000 weight=1;  # 蓝色\n    server app2.example.com:9000 weight=0;  # 绿色(已关闭)\n}\n\nserver {\n    listen 80;\n    server_name myshop.com;\n\n    location ~ \\.php$ {\n        fastcgi_pass php_backend;\n        include fastcgi_params;\n        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;\n    }\n}\n
\n\n

部署到绿色后,更改权重:

\n\n
# 部署后 — 切换流量\nupstream php_backend {\n    server app1.example.com:9000 weight=0;  # 蓝色(已关闭)\n    server app2.example.com:9000 weight=1;  # 绿色(已激活)\n}\n
\n\n

重新加载Nginx而不宕机:nginx -s reload。所有现有连接正常完成,新连接流向绿色。PHP零停机部署已实现!

\n\n

优缺点

\n

优点:完全容错,可以快速回滚(只需恢复权重)。
\n缺点:需要双倍的资源(服务器或容器)。

\n\n

策略二:滚动更新

\n\n

如果预算有限,我们使用滚动更新。思路:逐个更新PHP服务器,不关闭其他服务器。用户不会注意到停机,因为Nginx将请求重定向到活跃的服务器。

\n\n

在PHP-FPM上的实现

\n

假设你有3台运行PHP-FPM的服务器。我们依次将它们从轮换中移除,更新代码,然后重新加入。

\n\n

步骤1:从负载均衡器中移除服务器(优雅关闭):

\n\n
# 在要更新的服务器上\nsudo systemctl stop php8.1-fpm\n# Nginx将自动停止向此服务器发送请求,因为它不可用\n
\n\n

步骤2:更新代码(通过git pull、rsync或Docker)。

\n\n

步骤3:重新启动PHP-FPM:

\n\n
sudo                

博客

书籍推荐