Su的技术博客

  • 首页
  • 原创
  • 视频
  • Java
  • MySQL
  • DDD
  • 事故复盘
  • 架构方案
  • AI
  • Other
  • 工具
    • AI工具集
    • 工具清单
    • JSON在线格式化
    • JSON在线比较
    • SQL在线格式化
  • 打赏
  • 关于
路很长,又很短
  1. 首页
  2. 事故复盘
  3. 正文
                           

【转载】Vim 一下日志文件,Java 进程没了?

2023-11-24 1424点热度 0人点赞 0条评论

一次端口告警,发现 java 进程被异常杀掉,而根因竟然是因为在问题机器上 vim 查看了 nginx 日志。下面我将从时间维度详细回顾这次排查,希望读者在遇到相似问题时有些许启发。

时间线

15:19 收到端口异常 odin 告警。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<span style="font-size: 10pt;">状态:P1故障
名称:应用端口8989
指标:data-stream-openapi.port.8989
主机:data-stream-openapi-nmg-sf-a9457-1.docker.nmg01
节点:hbb-v.data-stream-openapi.data-stream.datadream.didi.com
当前值:0.00
说明:happen(data-stream-openapi.port.8989,#12,12) = 0
故障时间:2022-11-15 15:21:10</span>
<span style="font-size: 10pt;">状态:P1故障 名称:应用端口8989 指标:data-stream-openapi.port.8989 主机:data-stream-openapi-nmg-sf-a9457-1.docker.nmg01 节点:hbb-v.data-stream-openapi.data-stream.datadream.didi.com 当前值:0.00 说明:happen(data-stream-openapi.port.8989,#12,12) = 0 故障时间:2022-11-15 15:21:10</span>
状态:P1故障
名称:应用端口8989
指标:data-stream-openapi.port.8989
主机:data-stream-openapi-nmg-sf-a9457-1.docker.nmg01
节点:hbb-v.data-stream-openapi.data-stream.datadream.didi.com
当前值:0.00
说明:happen(data-stream-openapi.port.8989,#12,12) = 0
故障时间:2022-11-15 15:21:10

Vim 一下日志文件,Java 进程没了?

收到告警之后,登陆机器发现 java 进程消失了,第一反应是先摘流容器,然后再排查问题。

15:23 摘掉容器流量。

15:24 开始重建容器。

15:26 重建容器成功并上线。

Vim 一下日志文件,Java 进程没了?

请求成功率恢复,端口恢复。

Vim 一下日志文件,Java 进程没了?

排查路径

线上告警解除,业务恢复正常后,开始排查问题。首先排除日常发布的因素,先查看容器性能相关的监控,是否存在异常。查看 odin 用户内存使用率的监控,发现有异常:在 15:19 内存使用率突然飙升,然后极速下跌。看着内存使用率有问题,第一反应是否有 FullGC 的问题?

Vim 一下日志文件,Java 进程没了?

 

奇怪的是,在告警发生前后,居然一直没有 FullGC。

Vim 一下日志文件,Java 进程没了?

YGC 在问题发生点没有异常,15:25 YGC 较高,但很快恢复,应该和应用刚启动有关。

Vim 一下日志文件,Java 进程没了?

此时顺便查看 cpu 使用率有无问题。线上性能问题,往往是内存、cpu、io 这些情况。cpu 使用率没有明显的波动,15:25有短暂升高,原因是容器重建,java 代码即时编译。

Vim 一下日志文件,Java 进程没了?

 

既然性能层面监控没有头绪,试着查看应用监控和日志。成功率下跌是基于 nginx 的灭火图监控,查看应用层面接口的成功率监控,发现在告警发生期间,应用接口成功率并没有下跌。

Vim 一下日志文件,Java 进程没了?

根因定位

没有 FullGC,应用监控和应用日志都没有明显异常,为什么 java 进程无缘无故没有了?难道被 Linux 杀掉了,这时只能抱着试试的心态,看看是不是这个原因。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
dmesg -T | grep java。
dmesg -T | grep java。
dmesg -T | grep java。

Vim 一下日志文件,Java 进程没了?

发现 java 进程1155805在15:17时候被 linux 操作系统杀掉了,原因是发生了out of memory。再看看端口异常的告警配置,在12个周期(12*10s=2min)端口均不通会触发告警。到此,时间点串起来了。15:17 linux oom killer 杀掉了 java 进程,15:19 触发了端口异常告警。       

Vim 一下日志文件,Java 进程没了?

 

奇怪的是,java 进程并没有 FullGC,为啥会触发 linux 系统 OOM 呢?就在排查原因陷入困境时,有同事反馈他刚才在问题机器看过日志,是使用 vim 查看 nginx 日志,打开文件过程中,vim 程序报错。

Vim 一下日志文件,Java 进程没了?

有资料反馈 oom killer 有 case 和 vim 操作有关

vim 查看日志为什么会干掉 java 进程呢?看一下日志大小,居然有37G,而我们的容器规格仅有8G。

Vim 一下日志文件,Java 进程没了?

至此,问题原因基本定位:使用 vim 命令查看37G的的文件,文件在加载过程中耗尽了内存,触发了 linux oom killer 的机制,进而杀掉了 java 进程。

 

问题是,为什么不杀掉 vim 进程,而要杀掉 java 进程呢?

 

原理解析

这里有两个问题要验证:

  • vim 是不是要将文件全部加载到内存?

  • linux oom killer的机制是什么?

查阅资料吧,进入知识盲区了。有一篇不错的 vim 原理介绍 ,有兴趣可以阅读:《Linux 编辑器之神 vim 的 IO 存储原理》

归纳一下,vim 在加载文件时会调用 readfile 函数(readfile 内部在系统调用read),而 readfile 会读完文件。看来 vim 加载大文件确实会干爆内存。

划重点:readfile 会读完文件。这就是为什么当 vim 打开一个超大文件的时候,会非常慢的原因

那 linux oom killer 的机制又是什么?为什么不杀 vim 进程,杀掉 java 进程呢?核心原理是在内存快被耗尽的时候,linux 会尝试杀掉一些进程,不让系统变得更糟糕,具体杀掉哪个进程,有一个打分机制,得分高的进程容易被杀掉。具体原理可阅读《Linux 内核 OOM killer 机制》、《oom kill 内存源码》。

文章内容在此不赘述,分享两个核心:一个是 linux 内核源码注释

* If we run out of memory, we have the choice between either 
* killing a random task (bad), letting the system crash (worse) 
* OR try to be smart about which process to kill. Note that we 
* don't have to be perfect here, we just have to be good.

一个是 oom killer 相关结论

你的进程被Linux杀掉几个可能的原因:一种是内存泄露;一种是你的进程所需要的内存资源太大,系统无法满足,
应该在设计时对进程需要的资源有个最大限制,不能让他无限增长;当然,也不一定全是你的问题,也有可能是同
一主机的其他进程占用资源过多,但是Linux OOM选择“最坏“进程杀掉的算法是很简单粗暴的,就选中你的进程杀
掉,也是有可能的

linux oom killer 会在系统内存耗尽的时候,触发杀掉糟糕进程的保护机制,但选择糟糕进程的机制不是很精准,存在误杀的可能。

 

运维规范

查看或者搜索日志有很多很好用的命令,比如 less、grep、tail。

vim 命令严禁用在查看日志的场景,如果需要用 vim 编辑文件,一定要先确认文件的大小。

 

 

 

 

本文仅供学习!所有权归属原作者。侵删!文章来源: 滴滴技术 -师彬杰 :http://mp.weixin.qq.com/s/LKTw0RO-kMYkM4SJ61TIUw

 

更多文章:

  1. 系统设计 | 如何表达迭代技术方案?(战术篇)
  2. 系统设计 | 哪些技术标准可以帮助系统设计?
  3. 一次磁盘占用率 100% 的排查记录
  4. 用这10个技巧帮你写出更好的Java代码
  5. 6种限流实现,附代码![通俗易懂]
  6. 【进阶玩法】策略+责任链+组合实现合同签章
  7. 记一次堆内外内存问题的排查和优化
  8. 生产环境JVM崩溃问题排查解决
  9. 从滴滴的故障我们能学到什么
  10. 殷浩详解DDD系列 第一讲 - Domain Primitive
标签: 转载 日志 线上事故 Java Vim 滴滴
最后更新:2023-11-24

coder

分享干货文章,学习先进经验。

打赏 点赞
< 上一篇
下一篇 >

文章评论

razz evil exclaim smile redface biggrin eek confused idea lol mad twisted rolleyes wink cool arrow neutral cry mrgreen drooling persevering
取消回复

广告
文章目录
  • 时间线
  • 排查路径
  • 根因定位
  • 原理解析
  • 运维规范
最新 热点 推荐
最新 热点 推荐
干货 | 论Elasticsearch数据建模的重要性 马蜂窝消息总线——面向业务的消息服务设计 基于 MySQL Binlog 实现可配置的异构数据同步 视频笔记:Google发布Agent2Agent协议 视频笔记:什么是微服务,为什么是微服务? 视频笔记:什么是AI 智能体? 视频笔记:什么是Flink? 如何秒级实现接口间“幂等”补偿:一款轻量级仿幂等数据校正处理辅助工具
Elasticsearch 使用误区之六——富文本内容写入前不清洗基于 MySQL Binlog 实现可配置的异构数据同步马蜂窝消息总线——面向业务的消息服务设计干货 | 论Elasticsearch数据建模的重要性你可以不用RxJava,但必须得领悟它的思想!如何秒级实现接口间“幂等”补偿:一款轻量级仿幂等数据校正处理辅助工具视频笔记:什么是Flink?视频笔记:什么是AI 智能体?
RocketMQ消息回溯实践与解析 一文带你了解OpenAI Sora 干货 | Elasticsearch 数据建模指南 JVM 内存分析神器 MAT: Shallow Heap Vs Retained Heap 你理解的对吗? 系统设计 | 企业应用数据交换 研发日常踩坑-Mysql分页数据重复 从滴滴的故障我们能学到什么 关于聚合根、领域事件的那点事——深入浅出理解DDD

CRUD (1) Event Sourcing (1) graphql (1) id (1) NoSQL (1) quarkus (1) rest (1) RocketMQ (2) Spring Boot (1) zk (1) zookeeper (1) 上下文 (1) 事务消息 (1) 二级缓存 (1) 值对象 (1) 关系数据库 (1) 分布式缓存 (1) 原子性 (1) 唯一ID (1) 商品 (1) 多对多 (1) 子域 (1) 字符集 (1) 客户端心跳 (1) 幂等 (2) 干货 (1) 并发 (1) 应用场景 (1) 应用架构图 (1) 康威定律 (2) 异步复制 (1) 微服务架构 (2) 总体方案 (1) 技术方案 (2) 技术架构 (2) 技术架构图 (1) 技能 (1) 持续集成 (1) 支撑域 (1) 故障恢复 (1) 数据架构图 (1) 方案选型 (1) 日记 (1) 服务发现 (1) 服务治理 (1) 服务注册 (2) 机房 (1) 核心域 (1) 泄漏 (1) 洋葱架构 (1) 消息队列 (5) 源码剖析 (1) 灰度发布 (1) 熔断 (1) 生态 (1) 画图工具 (1) 研发团队 (1) 线程 (2) 组织架构 (1) 缓存架构 (1) 编码 (1) 视频 (18) 读写分离 (1) 贵州 (1) 软件设计 (1) 迁移 (1) 通用域 (1) 集群化 (1) 雪花算法 (1) 顺序消息 (1)

推荐链接🔗
  • AI工具集
  • 工具箱🛠️

站点已运行 1468 天

COPYRIGHT © 2014-2025 verysu.com . ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang

粤ICP备15033072号-2

x

通知