一个小米SRE的日常问题排查记录

在日常巡检中发现新扩容的web转发服务器负载异常,SRE团队通过细致排查,包括系统版本一致性、软件环境、硬件及驱动、CPU使用情况等,最终定位到nginx配置中的accept_mutex参数导致的epoll_wait惊群效应问题,并成功解决。
  1. 日常巡检发现新扩容的一台web转发服务器负载异常。比原来的稍高仍然在正常范围内,but作为一个SRE是不能放过任何异常。

\"\"

  1. 安排好其他日常工作开始排查。

    • 新增服务器系统版本跟原来不一致。(原来为centos6.x,异常服务器为centos7.x) ,异常服务器从lvs下线重装,保证系统版本都为6.x依然没有恢复。(论:保持环境统一重要性。)为什么要重新装centos6.x呢?当时怀疑线上nginx是在centos6.x环境下编译的,运行在centos7.x下面,可能会是这个原因。

    • 仔细对比下环境,确认系统版本nginx版本nginx配置完全一样。

\"\"

  1. 通过火焰图分析大部分cpu占用为https握手阶段函数(bn_sqr8x_interna,mul4x_internall),查看log发现问题服务器及正常服务器https及http请求数量相同。(此路不通。)

\"\"

  1. 既然软件环境一样来看硬件及驱动。通过监控确定新增一批服务负载都比原来的稍高,新增服务器及原来服务器从cpu,内存硬盘配置一样。确定新增服务器没有节能没开,cpu内存频率正常硬盘读写正常,找系统同事查看未见硬件故障。部分驱动版本信息不同,进行了替换验证,整个过程是痛苦的,感谢系统及dell同学。(大家一个team一起背锅)

\"\"

  1. 通过找不同没有解决问题了。但是我们还是要继续,现在我们很好奇很想知道答案。继续分析我们发现了问题服务器cpu很不均衡。为什么不均衡了,strace一下发现大量的(Resourcetemporarilyunavailable)cpu在空转。

    来看下nginx对请求分配的模型。master进程监听端口号(例如80),所有的nginx worker进程开始用epoll_wait来处理新事件(linux下),如果不加任何保护,一个新连接来临时,会有多个worker进程在epoll_wait后被唤醒然后只有一个线程处理这个请求其他的则会失败。cpu空转负载升高。这就是所谓epoll_wait惊群效应。当然nginx会有办法处理这个问题:加锁。

\"\"

  1. 剩下的就简单了。对问题服务器手动配置上锁(accept_mutex),然后负载正常了(每把锁都是双刃剑,加不加要具体问题具体分析)。但是,你可能会有疑问版本是一样的啊,正常的服务器也没手动加锁啊。伟大福尔摩斯说过:When you have eliminated the impossibles,whatever remains,however improbable,must be the truth真相就是线上nginx根本不是一个版本(一脸懵逼)。手动查看下线上运行的nginx文件被删除了,线上运行了一个不存在的版本,存在的版本是更新了的。原来正常的而服务器上线是reload新版nginx不会生效,新增的服务器是start运行的是新版nginx。

\"\"

  1. 下面的问题就是tengine2.1跟tengine2.2accept_mutex参数由默认的on改为了off为什么要改呢。与时俱进。当初这个参数是为了避免在epoll_wait所出现惊群效应。可以参考(https://www.jianshu.com/p/21c3e5b99f4a)新版内核已经有了处理这个方法不再需要nginx单独配置。

总结:反思并完善整个运维流程,以避免相关问题再次发生,对SRE来说永远是最重要的。

一些启示:

  • 线上环境尽量完全一致(容器化可以很好的解决这一点);

  • 每次变更都要谨慎及测试。

### SRE 常见面试问题及答案 #### 1. 什么是 SRESRE(站点可靠性工程)是 Google 首创的一种结合软件工程和系统管理的实践方法,旨在通过自动化、监控和优化来确保系统的高可用性、性能和可扩展性[^1]。SRE 的核心目标是将运维任务转化为可编程的问题,从而减少手动干预。 #### 2. SRE 和 DevOps 有什么区别? 虽然 SRE 和 DevOps 都关注于提高系统的可靠性和效率,但它们的起源和实践方式有所不同。DevOps 是一种文化和实践的集合,强调开发和运维团队之间的协作;而 SRE 更加具体化,通常由工程师编写代码来解决运维中的复杂问题[^1]。 #### 3. 什么是持续集成和持续部署 (CI/CD)? CI/CD 是一种软件开发实践,其中持续集成(Continuous Integration)指的是频繁地将代码更改合并到主分支中,并通过自动化构建和测试确保质量。持续部署(Continuous Deployment)则是在 CI 的基础上,自动将通过测试的代码部署到生产环境[^2]。 #### 4. 在 K8s 生产环境中处理过哪些复杂或印象深刻的问题? 在 Kubernetes 生产环境中,可能会遇到以下复杂问题: - **Pod 调度失败**:由于资源不足或调度策略问题导致 Pod 无法启动。可以通过调整节点资源分配或修改调度器配置来解决。 - **网络连接问题**:例如 Service 和 Pod 之间的通信中断。需要检查 CNI 插件配置以及网络策略是否正确。 #### 5. 如何排查上下文切换频繁的问题? 可以使用 `vmstat` 命令查看系统的上下文切换次数,`cs` 列表示上下文切换的总数。如果需要针对特定进程进行监控,可以使用 `pidstat -w pid` 命令,其中 `cswch` 表示自愿切换次数,`nvcswch` 表示非自愿切换次数。频繁的上下文切换可能表明系统负载过高或存在 I/O 瓶颈[^3]。 #### 6. 如何排查磁盘性能问题? 磁盘性能问题排查可以从以下几个方面入手: - 使用 `iostat` 命令查看磁盘的读写延迟、吞吐量等指标。 - 检查是否有过多的随机 I/O 操作,这可能导致磁盘负载过高。 - 分析是否存在磁盘队列过长的情况,通常可以通过 `await` 指标判断[^3]。 #### 7. 什么是 SLA、SLO 和 SLI? - **SLA(Service Level Agreement)**:服务级别协议,定义了服务提供商与客户之间的服务水平约定。 - **SLO(Service Level Objective)**:服务级别目标,具体描述了服务需要达到的性能指标,例如 99.9% 的可用性。 - **SLI(Service Level Indicator)**:服务级别指标,用于衡量实际的服务表现是否符合 SLO 的要求[^1]。 #### 8. 如何设计一个高可用的系统? 设计高可用系统的关键点包括: - 使用冗余架构,确保单点故障不会影响整体服务。 - 实施负载均衡,合理分配流量以避免单个节点过载。 - 定期进行故障演练(如 Chaos Engineering),验证系统的容错能力。 - 建立完善的监控和报警机制,及时发现并解决问题。 ```python # 示例:简单的健康检查脚本 import requests def check_service_health(url): try: response = requests.get(url, timeout=5) if response.status_code == 200: print("Service is healthy") else: print("Service returned status code:", response.status_code) except requests.exceptions.RequestException as e: print("Service is unreachable:", e) check_service_health("http://example.com/health") ``` ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值