Vim 一下日志文件,Java 进程没了?
一次端口告警,发现 java 进程被异常杀掉,而根因竟然是因为在问题机器上 vim 查看了 nginx 日志。下面我将从时间维度详细回顾这次排查,希望读者在遇到相似问题时有些许启发。
时间线
15:19 收到端口异常 odin 告警。
状态: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 
收到告警之后,登陆机器发现 java 进程消失了,第一反应是先摘流容器,然后再排查问题。
15:23 摘掉容器流量。
15:24 开始重建容器。
15:26 重建容器成功并上线。

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

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

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

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

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

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

根因定位
没有 FullGC,应用监控和应用日志都没有明显异常,为什么 java 进程无缘无故没有了?难道被 Linux 杀掉了,这时只能抱着试试的心态,看看是不是这个原因。
dmesg -T | grep java。 
发现 java 进程1155805在15:17时候被 linux 操作系统杀掉了,原因是发生了out of memory。再看看端口异常的告警配置,在12个周期(12*10s=2min)端口均不通会触发告警。到此,时间点串起来了。15:17 linux oom killer 杀掉了 java 进程,15:19 触发了端口异常告警。

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

有资料反馈 oom killer 有 case 和 vim 操作有关
vim 查看日志为什么会干掉 java 进程呢?看一下日志大小,居然有37G,而我们的容器规格仅有8G。

至此,问题原因基本定位:使用 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 编辑文件,一定要先确认文件的大小。
相关文章:
Vim 一下日志文件,Java 进程没了?
一次端口告警,发现 java 进程被异常杀掉,而根因竟然是因为在问题机器上 vim 查看了 nginx 日志。下面我将从时间维度详细回顾这次排查,希望读者在遇到相似问题时有些许启发。 时间线 15:19 收到端口异常 odin 告警。 状态:P1故障 名称:应用端…...
C# Dictionary的使用
在 C# 中,Dictionary 是一种常用的数据结构,用于存储键值对。以下是一些常见的 Dictionary 操作: 创建和初始化一个 Dictionary 可以使用以下代码创建并初始化一个 Dictionary: Dictionary<string, int> dict new Dicti…...
解决DaemonSet没法调度到master节点的问题
最近在kubernetes部署一个springcloud微服务项目,到了最后一步部署边缘路由:使用nginx-ingress和traefik都可以,必须使用DaemonSet部署,但是发现三个节点,却总共只有两个pod。 换句话说, DaemonSet没法调度…...
2023.11.20 关于 Spring MVC 详解
目录 MVC 工作流程 Spring MVC 掌握三个功能 创建 Spring MVC 项目 推荐安装插件 EditStarters 基础注解 RequestMapping 指定 GET 和 POST 方法类型 ResponseBody 获取参数 传递 单个 或 多个参数 参数重命名 RequestParam 接收 JSON 对象 RequestBody 获取 …...
救命~终于找到一款好看又舒适的家居服了
暖乎乎的软糯家居服 简直不要太好看太舒服了 双层舒棉绒舒适又暖和 防风收口设计,时尚与实用性兼具 经典版型不挑人穿 居家外出都可哦!!...
C#每天复习一个重要小知识day5:枚举与switch是天生一对
因为枚举一般用来表示条件和类型等等,所以它一般用条件分支来表现。所以枚举与switch是天生一对,因为很方便。(用if语句也可,但是没switch方便) 简单的举例: namespace 精细练习 {enum E_Player {Main,Ot…...
idea修改行号颜色
前言 i当idea用了深色主题后,发现行号根本看不清,或者很模糊 例如下面这样 修改行号颜色 在IntelliJ IDEA中,你可以根据自己的喜好和需求定制行号的颜色。下面是修改行号颜色的步骤: 打开 IntelliJ IDEA。 转到 “File”&…...
U-boot(四):start_armboot
本文主要探讨210的uboot启动的第二阶段,主要函数为start_armboot。 uboot 一阶段初始化SoC内部部件(看门狗、时钟等),初始化DDR,重定位 二阶段初始化其余硬件(iNand、网卡芯片)以及命令、环境变量等 启动打印硬件信息,进入bootdelay,读秒完后执行bootc…...
.Net面试题4
1.请解释一下泛型(Generics)在C#中的作用。 泛型是一种将数据类型参数化的机制,使得代码可以在编译时具有更强的类型安全性和灵活性。C#中的泛型可以用于类、接口、方法等的定义和实例化。泛型允许在编写代码时使用具有不同实参的类型&#x…...
python 列表插入数据的 四种方法 append insert extend 切片赋值
append insert 插入单个数据 append 加到末尾,insert 加到指定位置 extend、切片方式插入多个数据 extend 加到末尾,切片加到指定位置 my_list [1, 2, 3] my_list.append(4) print(my_list) # 输出: [1, 2, 3, 4]my_list [1, 2, 3] my_list.insert(…...
C++中std::string的=,+,+=使用过程中的问题
1. 调用构造函数时的运算符不支持int,char类型的操作数 string str1 a; //error 这是一个构造函数。C中string是一个类,内部封装了char *来管理这个字符串。 string的构造函数: string() // 创建一个空的字符串string(const char * s)…...
ruoyi-plus使用Statistic统计组件升级element-plus
原本使用的就是gitee上lionli的ruoyi-plus版本的代码。但是在使用过程中作首页数据看板时想使用elementui的Statistic统计组件。结果在浏览器控制台报错找不到组件el-statistic 于是查看elementui的历史版本,发现是在新版中才有这个组件,旧版本是没这个组…...
Python基础入门例程72-NP72 生成字典(字典)
最近的博文: Python基础入门例程71-NP71 喜欢的颜色(字典)-CSDN博客 Python基础入门例程70-NP70 首都(字典)-CSDN博客 Python基础入门例程69-NP69 姓名与学号(字典)-CSDN博客 目录 最近的博文: 描述...
flink的java.lang.IllegalStateException: Buffer pool is destroyed 异常
背景 最近flink的在线应用出现错误java.lang.IllegalStateException: Buffer pool is destroyed,本文记录下这个错误的原因 错误原因 详细的日志堆栈如下: Caused by: java.lang.IllegalStateException: Buffer pool is destroyed. at org.apache.flink.runtime…...
物联网AI MicroPython学习之语法 实时时钟RTC
学物联网,来万物简单IoT物联网!! RTC 介绍 模块功能: 实时时钟RTC驱动模块 接口说明 RTC - 构建RTC对象 函数原型:RTC()参数说明: 无 返回值: 构建的RTC对象。 datetime - RTC时钟操作 函数原型&a…...
GEE:kNN(k-最近邻)分类教程(样本制作、特征添加、训练、精度、最优参数、统计面积)
作者:CSDN @ _养乐多_ 本文将介绍在Google Earth Engine (GEE)平台上进行kNN(k-最近邻)分类的方法和代码,其中包括制作样本点教程(本地、在线和本地在线混合制作样本点,合并样本点等),加入特征变量(各种指数、纹理特征、时间序列特征、物候特征等),运行kNN(k-最近…...
【GitHub】保姆级使用教程
一、如何流畅访问GitHub 1、网易uu加速器 输入网址,无脑下载网易加速器;https://uu.163.com/ 下载安装完毕后,创建账号进行登录 登录后,在右上角搜索框中搜索“学术资源”,并点击; 稍等一会儿就会跳…...
Kotlin基础——Lambda和函数式编程
Lambda 使用 { } 定义Lamba,调用run运行 run { println(1) }更常用的为 { 参数 -> 操作 },还可以存储到变量中,把变量作为普通函数对待 val sum { x: Int, y: Int -> x y } println(sum(1, 2))maxBy()接收一个Lambda,传…...
mysql忘记密码,然后重置
数据库版本8.0.26 只针对以下情况 mysql忘记了密码,但是你navicat之前连接上了 解决方法: 第一步,选中mysql这个数据库,点击新建查询 第二步:重置密码 alter user rootlocalhost IDENTIFIED BY 你的密码; 然后就可…...
西门子S7-1500暖通空调冷水机组PLC程序案例, 硬件采用西门子1500CPU+ET200...
西门子S7-1500暖通空调冷水机组PLC程序案例, 硬件采用西门子1500CPUET200SP接口IO模块,HMI采用西门子触摸屏 程序采用SCL控制程序编程,系统水泵采用一用一备,通过程序实现了加减机控制,根据压差控制开启的水泵台数以及…...
当n和L大到1e18时,别再暴力模拟了!详解‘3437 melon’吃瓜问题的O(1)公式推导与边界条件处理
极端数据规模下的算法优化:从暴力模拟到O(1)公式推导 在算法竞赛和高性能编程中,我们常常会遇到数据规模极其庞大的问题。当输入参数达到1e18量级时,传统的暴力模拟或动态规划方法往往无法在合理时间内完成计算。本文将以经典的"3437 me…...
【限时首发|内部白皮书节选】Spring Boot 4.0 Agent-Ready架构设计规范V1.2(含12个不可绕过的SPI扩展点与8个已知CVE规避方案)
第一章:Spring Boot 4.0 Agent-Ready架构的演进背景与核心定位随着云原生可观测性标准(OpenTelemetry、eBPF、W3C Trace Context)的成熟,以及Java平台对JVM TI、JVMTI Attach API和Instrumentation API的持续增强,传统…...
SAP GUI 760环境下,ABAP Dialog Screen开发的5个新手常见坑及避坑指南
SAP GUI 760环境下ABAP Dialog Screen开发的5个新手常见坑及避坑指南 在SAP GUI 760环境下进行ABAP Dialog Screen开发时,新手开发者常常会遇到一些看似简单却令人头疼的问题。这些问题往往与新版GUI的特性、ABAP屏幕开发的特殊机制以及开发习惯有关。本文将深入剖析…...
告别万年历芯片!用STM32F4的RTC+BKP寄存器实现数据记录与事件时间戳(附代码)
用STM32F4的RTCBKP构建高精度事件日志系统 在嵌入式设备开发中,记录关键事件的时间戳是许多应用场景的刚需。无论是工业设备的故障诊断、医疗仪器的操作审计,还是智能家居的用户行为分析,精确的时间标记都至关重要。传统方案往往依赖外部RTC芯…...
Go的time.Ticker与time.Timer:精准的定时任务
Go的time.Ticker与time.Timer:精准的定时任务 在现代软件开发中,定时任务是常见的需求,无论是定时数据同步、周期性任务执行,还是超时控制,都需要精准的时间管理。Go语言的标准库提供了time.Ticker和time.Timer两种强…...
ViGEmBus虚拟游戏控制器驱动:终极安装与完整使用指南
ViGEmBus虚拟游戏控制器驱动:终极安装与完整使用指南 【免费下载链接】ViGEmBus Windows kernel-mode driver emulating well-known USB game controllers. 项目地址: https://gitcode.com/gh_mirrors/vi/ViGEmBus 你是否曾经遇到过这样的烦恼?想…...
CMake实战:在Qt Creator中优雅集成第三方库的完整指南
1. 为什么需要优雅集成第三方库? 最近在做一个图像处理项目时,我遇到了一个典型问题:在本机调试一切正常,但把程序发给同事后却报错"找不到opencv_world450.dll"。这种问题在Windows平台开发中太常见了,根本…...
Pandas 复制 DataFrame的方法总结
Pandas 复制 DataFrame的方法总结 1.pandas.DataFrame.copy() 方法语法 DataFrame.copy(deepTrue) 它返回 DataFrame 的副本。deep 默认为 True,这意味着在副本中所作的任何更改将不会反映在原始 DataFrame 中。但是,如果我们设置 deepFalseÿ…...
PZEM-004T v3.0 Arduino库终极指南:轻松实现精准电力监控的完整方案
PZEM-004T v3.0 Arduino库终极指南:轻松实现精准电力监控的完整方案 【免费下载链接】PZEM-004T-v30 Arduino library for the Updated PZEM-004T v3.0 Power and Energy meter 项目地址: https://gitcode.com/gh_mirrors/pz/PZEM-004T-v30 你是否曾为家庭电…...
