当前位置: 首页 > news >正文

PHP 容器化引发线上 502 错误状态码的修复

最后更新时间 2023-01-24.

背景

笔者所在公司技术栈为 Golang + PHP,目前部分项目已经逐步转 Go 语言重构,部分 PHP 业务短时间无法用 Go 重写。

相比 Go 语言,互联网公司常见的 Nginx + PHP-FPM 模式,经常会出现性能问题——

特别是我们的活动业务,尽管底层用了鸟哥的 Yaf 框架,

但由于业务逻辑繁重,即使框架层面上完全零损耗,常常支撑不了流量高峰。

一旦某个时间段开启活动,虚拟机的扩容真的非常痛苦。

SRE、开发、QA 三方经常需要因为某个运营活动的进行,提前压测预估容量。

目前活动业务已经逐步用 Go 语言改造,此处不具体展开,防止跑题哈哈。

正因为 PHP 虚拟机模式,每次扩容需要流量剔除、克隆、操作负载均衡、验证流量等等,

推进 PHP 容器化就显得格外重要。

公司在去年年中,已经开始进行 PHP 容器化,不过由于项目优先级以及人力原因,进度较为迟缓。

事情经过

  1. 某项目进行 PHP 容器化改造,切换少许流量到容器中
  2. 逐步加大灰度流量
  3. 某一天开发上线新功能,发现滚动部署过程中存在 502 错误

分析原因

nginx 发生了 502,很多时候是后端,也就是 php-fpm 不在工作。

我们的 PHP 业务的 Pod,由以下 5 个容器组成:

  • nginx
  • php-fpm
  • metric(监控)
  • jaeger(链路追踪)
  • log(日志收集)

滚动时存在关闭旧 Pod 启动新 Pod 的过程,借助 K8s 官方文档 的描述,我们看看 Pod 结束的一个例子:

  1. 你使用 kubectl 工具手动删除某个特定的 Pod,而该 Pod 的体面终止限期是默认值(30 秒)。
  2. API 服务器中的 Pod 对象被更新,记录涵盖体面终止限期在内 Pod 的最终死期,超出所计算时间点则认为 Pod 已死(dead)。 如果你使用 kubectl describe 来查验你正在删除的 Pod,该 Pod 会显示为 “Terminating” (正在终止)。 在 Pod 运行所在的节点上:kubelet 一旦看到 Pod 被标记为正在终止(已经设置了体面终止限期),kubelet 即开始本地的 Pod 关闭过程。
  3. 在 kubelet 启动体面关闭逻辑的同时,控制面会将关闭的 Pod 从对应的 EndpointSlice(和 Endpoints)对象中移除,过滤条件是 Pod 被对应的服务以某 选择算符选定。 ReplicaSet 和其他工作负载资源不再将关闭进程中的 Pod 视为合法的、能够提供服务的副本。 关闭动作很慢的 Pod 也无法继续处理请求数据, 因为负载均衡器(例如服务代理)已经在终止宽限期开始的时候将其从端点列表中移除。
  4. 超出终止宽限期限时,kubelet 会触发强制关闭过程。容器运行时会向 Pod 中所有容器内仍在运行的进程发送 SIGKILL 信号。 kubelet 也会清理隐藏的 pause 容器,如果容器运行时使用了这种容器的话。
  5. kubelet 触发强制从 API 服务器上删除 Pod 对象的逻辑,并将体面终止限期设置为 0 (这意味着马上删除)。
  6. API 服务器删除 Pod 的 API 对象,从任何客户端都无法再看到该对象。

通常情况下,容器运行时会发送一个 TERM 信号到每个容器中的主进程。很多容器运行时都能够注意到容器镜像中 STOPSIGNAL 的值,并发送该信号而不是 TERM。一旦超出了体面终止限期,容器运行时会向所有剩余进程发送 KILL 信号,之后 Pod 就会被从 API 服务器上移除。 如果 kubelet 或者容器运行时的管理服务在等待进程终止期间被重启,集群会从头开始重试,赋予 Pod 完整的体面终止限期。

所以,我们可以发现:

  1. nginx、php-fpm 收到 TERM 信号后,不做请求的优雅处理,直接强制退出了!强制退出的原因,可以移步这俩文档:nginx - http://nginx.org/en/docs/control.html、php-fpm - https://linux.die.net/man/8/php-fpm;
  2. 参考上面的第 3 点,在容器运行时发送 TERM 信号后,也同时移除 endpoint,此处不是串行的。一旦 endpoint 移除的时间晚了,流量就会剔不干净,到达了 nginx 后,php-fpm 进程已经退出从而导致 502 的产生。

解决办法

有了上面的分析,解决起来就方便多了!

查看上面文档,我们可以了解到,nginx 和 php-fpm 喜欢 QUIT 信号,均可做到 graceful shutdown。

只需要在 Dockerfile 指定 STOPSIGNAL SIGQUIT 即可。

但我记得之前封装的 php-fpm 镜像使用的是社区维护版本,应该加上了才对。

而我看了线上的 Dockerfile,nginx 使用的是社区维护的,已经配置了 STOPSIGNAL SIGQUIT,没问题!

但是 PHP 由于之前的 alpine linux 因为监控扩展、链路追踪扩展编译环境的原因,使用了 CentOS 镜像。

镜像的来源都是自己打包的,并没有指定退出信号!

加上了之后,发现不会有 502 了!

至此,问题解决。

延伸思考

本来文章到此结束,突然想到线上的 Go 服务会不会有同样的问题?

想了一下,也好办!

要么自行处理 TERM 信号,做好优雅退出的姿势!

要么学 nginx,也用 QUIT 信号并做好优雅退出处理,Dockerfile 指定 STOPSIGNAL。

至于怎么处理信号,Go 实现起来非常舒服:

ch := make(chan os.Signal, 1)
signal.Notify(ch, syscall.SIGTERM, syscall.SIGQUIT)
<-ch
// 收到信号了(还可以根据信号类型做不同的处理逻辑),自行处理剩余任务实现优雅退出。

嗯,channel 大法好。


文章来源于本人博客,发布于 2022-09-03,原文链接:https://imlht.com/archives/398/

相关文章:

PHP 容器化引发线上 502 错误状态码的修复

最后更新时间 2023-01-24. 背景 笔者所在公司技术栈为 Golang PHP&#xff0c;目前部分项目已经逐步转 Go 语言重构&#xff0c;部分 PHP 业务短时间无法用 Go 重写。 相比 Go 语言&#xff0c;互联网公司常见的 Nginx PHP-FPM 模式&#xff0c;经常会出现性能问题—— 特…...

QT中UDP之UDPsocket通讯

目录 UDP&#xff1a; 举例&#xff1a; 服务器端&#xff1a; 客户端&#xff1a; 使用示例&#xff1a; 错误例子并且改正&#xff1a; UDP&#xff1a; &#xff08;User Datagram Protocol即用户数据报协议&#xff09;是一个轻量级的&#xff0c;不可靠的&#xff0…...

【C语言】10-三大结构之循环结构-1

1. 引言 在日常生活中经常会遇到需要重复处理的问题,例如 统计全班 50 个同学平均成绩的程序求 30 个整数之和检查一个班级的同学程序是否及格要处理以上问题,最原始的方法是分别编写若干个相同或相似的语句或者程序段进行处理 例如:处理 50 个同学的平均成绩可以先计算一个…...

Windows下RocketMQ的启动

下载地址&#xff1a;下载 | RocketMQ 解压后 一、修改runbroker.cmd 修改 bin目录下的runbroker.cmd set "JAVA_OPT%JAVA_OPT% -server -Xms2g -Xmx2g" set "JAVA_OPT%JAVA_OPT% -XX:MaxDirectMemorySize15g" set "JAVA_OPT%JAVA_OPT% -cp %CLASSP…...

linux内核升级 docker+k8s更新显卡驱动

官方驱动 | NVIDIA在此链接下载对应的显卡驱动 # 卸载可能存在的旧版本nvidia驱动(如果没有安装过可跳过&#xff0c;建议执行) sudo apt-get remove --purge nvidia* # 安装驱动需要的依赖 sudo apt-get install dkms build-essential linux-headers-generic sudo vim /etc/mo…...

express学习笔记2 - 三大件概念

中间件 中间件是一个函数&#xff0c;在请求和响应周期中被顺序调用&#xff08;WARNING&#xff1a;提示&#xff1a;中间件需要在响应结束前被调用&#xff09; 路由 应用如何响应请求的一种规则 响应 / 路径的 get 请求&#xff1a; app.get(/, function(req, res) {res…...

Steam搬砖蓝海项目

这个项目早在很久之前就已经存在&#xff0c;并且一直非常稳定。如果你玩过一些游戏&#xff0c;你一定知道Steam是什么平台。Steam平台是全球最大的综合性数字发行平台之一&#xff0c;玩家可以在该平台购买、下载、讨论、上传和分享游戏和软件。 今天我给大家解释一下什么是…...

就业并想要长期发展选数字后端还是ic验证?

“就业并想要长期发展选数字后端还是ic验证&#xff1f;” 这是知乎上的一个热点问题&#xff0c;浏览量达到了13,183。看来有不少同学对这个问题感到疑惑。之前更新了数字后端&数字验证的诸多文章&#xff0c;从学习到职业发展&#xff0c;都写过&#xff0c;唯一没有做过…...

当服务器域名出现解析错误的问题该怎么办?

​  域名解析是互联网用户接收他们正在寻找的域的地址的过程。更准确地说&#xff0c;域名解析是人们在浏览器中输入时使用的域名与网站IP地址之间的转换过程。您需要站点的 IP 地址才能知道它所在的位置并加载它。但&#xff0c;在这个过程中&#xff0c;可能会出现多种因素…...

面试必考精华版Leetcode2095. 删除链表的中间节点

题目&#xff1a; 代码&#xff08;首刷看解析 day22&#xff09;&#xff1a; class Solution { public:ListNode* deleteMiddle(ListNode* head) {if(head->nextnullptr) return nullptr;ListNode *righthead;ListNode *lefthead;ListNode *NodeBeforeLeft;while(right!n…...

对 Redis 实现分布式事务的探索与实现

对 Redis 实现分布式事务的探索与实现 一、简介简介优势 二、Redis 的事务机制事务WATCH 命令MULTI 命令EXEC 命令UNWATCH 命令 三、Redis 的分布式事务集群架构分布式事务分布式事务实现方式1. 两阶段提交&#xff08;2PC&#xff09;方式Paxos 算法实现方式Raft 算法实现方式…...

Matlab实现Spectral Clustering算法

Spectral Clustering算法是一种基于图论的聚类算法&#xff0c;它可以将数据点按照图结构进行划分&#xff0c;发现复杂和非线性可分的结构。在这篇博客中&#xff0c;我将介绍Spectral Clustering算法的原理和步骤&#xff0c;并给出一个用Matlab实现的代码示例。 目录 一、…...

Android 测试

工程目录图 1- Espresso 2- uiautomator Espresso 文档UI Automator文档ui-automator 英文文档 请点击下面工程名称&#xff0c;跳转到代码的仓库页面&#xff0c;将工程 下载下来 Demo Code 里有详细的注释 代码&#xff1a;testespresso 参考文献 Android 利用 espre…...

全面解析大语言模型的工作原理

当ChatGPT在去年秋天推出时&#xff0c;在科技行业乃至世界范围内引起了轰动。当时&#xff0c;机器学习研究人员尝试研发了多年的语言大模型&#xff08;LLM&#xff09;&#xff0c;但普通大众并未十分关注&#xff0c;也没有意识到它们变得多强大。 如今&#xff0c;几乎每个…...

cmake+pybind11打包c++库成python wheel安装包

目录 写在前面准备1、pybind11获取源码编译安装 2、conda demo官方源码修改CMakeLists.txt编译生成安装测试 参考完 写在前面 1、本文内容 有时候我们需要用c代码&#xff0c;供python调用&#xff0c;本文提供将c库封装成python接口的方法&#xff0c;并将库打包成可通过pip安…...

史上最细,接口自动化测试框架-Pytest+Allure+Excel整理(代码)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 Allure框架 Allu…...

【计算机视觉中的 GAN 】 - 条件图像合成和 3D 对象生成(2)

一、说明 上文 【计算机视觉中的 GAN 】或多或少是GANs&#xff0c;生成学习和计算机视觉的介绍。我们达到了在 128x128 图像中生成可区分图像特征的程度。但是&#xff0c;如果你真的想了解GAN在计算机视觉方面的进展&#xff0c;你肯定必须深入研究图像到图像的翻译。…...

智安网络|常见的网络安全陷阱:你是否掉入了其中?

在数字化时代&#xff0c;网络安全成为了一个重要的议题。随着我们越来越多地在互联网上进行各种活动&#xff0c;诸如在线银行交易、社交媒体分享和在线购物等&#xff0c;我们的个人信息也更容易受到攻击和滥用。虽然有许多关于网络安全的指导和建议&#xff0c;但仍然有许多…...

亚马逊云科技HPC解决方案,帮助浙江大学实现成本和科研任务的双丰收

浙江大学土壤学科是朱祖祥院士等几代土壤科学家共同创建的A国家重点学科&#xff0c;整体实力雄厚&#xff0c;优势特色明显&#xff0c;总体水平居国内前列。在亚马逊云科技科研创新支持计划&#xff08;Amazon Web Services Cloud Credits for Research&#xff09;的多次支持…...

【Docker】Docker中安装MySQL数据库

文章目录 1. 前言2. Docker中安装MySQL服务2.1. 查看可用的MySQL版本2.2. 拉取MySQL镜像2.3. 查看本地镜像2.4. 运行容器2.5. 查看正在运行的容器2.6. 查看容器内部2.7. 授权root远程登录2.8. 在宿主机连接到容器的MySQL2.9. 用Navicat连接容器的MySQL 3. 如果是MySQL8.0可能需…...

Unity的IPostBuildPlayerScriptDLLs:深入解析与实用案例

Unity IPostBuildPlayerScriptDLLs Unity IPostBuildPlayerScriptDLLs是Unity引擎中的一个非常有用的功能&#xff0c;它可以让开发者在构建项目后自定义哪些文件需要被复制到输出目录中。这个功能可以帮助开发者更好地控制项目的构建过程&#xff0c;确保输出目录只包含必要的…...

MySQL数据库服务器安装与配置(步骤简单详细,看完可学会下载MySQL所有版本)

目录 引言 一&#xff0c;5.6.51数据库服务器下载 二&#xff0c;8.1.0最新版数据库服务器下载 三&#xff0c;MySQL客户端下载 引言 个人认为MySQl数据库目前推荐的两个版本系列为5.6.51和8.系列。 至于我们为什么要下载两个版本呢&#xff1f;是因为官方在数据库下载的结构…...

PowerDesigner16.5安装教程

一、什么是PowerDesigner PowerDesigner是Sybase的企业建模和设计解决方案&#xff0c;采用模型驱动方法&#xff0c;将业务与IT结合起来&#xff0c;可帮助部署有效的企业体系架构&#xff0c;并为研发生命周期管理提供强大的分析与设计技术。PowerDesigner独具匠心地将多种标…...

Java反射全面详解

1. 什么是反射&#xff1f; 首先听这个名字就有些疑惑&#xff0c;什么是反射&#xff0c;它能用来干什么呢&#xff1f; Java官方对反射的解释是 "反射允许对封装类的字段&#xff0c;方法和构造函数进行编程式访问"。这里的字段指的就是成员变量&#xff0c;方法…...

助力工业物联网,工业大数据之费用事实指标分析及实现【二十四】

文章目录 1&#xff1a;费用事实指标分析及实现2&#xff1a;差旅事实指标分析及实现3&#xff1a;网点物料事实指标分析及实现 1&#xff1a;费用事实指标分析及实现 目标&#xff1a;实现DWB层费用报销事实指标表的构建 路径 step1&#xff1a;目标需求step2&#xff1a;数据…...

Istio 安全 mTLS认证 PeerAuthentication

这里定义了访问www.ck8s.com可以使用http也可以使用https访问&#xff0c;两种方式都可以访问。 那么是否可以强制使用mtls方式去访问&#xff1f; mTLS认证 PeerAuthentication PeerAuthentication的主要作用是别人在和网格里的pod进行通信的时候&#xff0c;是否要求mTLS mTL…...

【MySQL】数据库基本使用

文章目录 一、数据库介绍二、数据库使用2.1 登录MySQL2.2 基本使用2.2.1 显示当前 MySQL 实例中所有的数据库列表2.2.2 创建数据库2.2.3 创建数据库表2.2.4 在表中插入数据2.2.5 在表中查询数据 三、服务器、数据库、表之间的关系四、SQL语句分类五、存储引擎 一、数据库介绍 …...

计算shell脚本执行的时间

我们在使用shell脚本进行一些批量活动的时候&#xff0c;在有的场景下会需要知道脚本执行用了多长的时间&#xff0c;一谈到这个话题&#xff0c;我们一般的想法就是记录时间再开始阶段&#xff0c;执行完成后再记录时间&#xff0c;然后求时间差&#xff0c;这样是可以的&…...

无网络环境下,如何部署Docker镜像

无网络环境下&#xff0c;如何部署Docker镜像 什么是Docker镜像 Docker镜像是Docker容器的基础构建块。它是一个轻量级、独立且可执行的软件包&#xff0c;其中包含了运行应用程序所需的所有文件系统、代码、依赖关系和配置。 Docker镜像由一系列只读层&#xff08;Layers&a…...

瑞吉外卖项目----(2)缓存优化

1 缓存优化 1.0 问题说明 1.1 环境搭建 将项目推送到远程仓库里&#xff0c;教程在git 提交远程仓库前建议取消代码检查 创建新的分支v1.0&#xff08;用于实现缓存优化&#xff09;并推送到远程仓库 1.1.1 maven坐标 导入spring-data-redis的maven坐标&#xff1a; &l…...