生产环境消失的进程如何排查

一、内存不够了怎么办

1.1 操作系统内存不够怎么办

1.2 什么是交换分区Swap 

1.3 swap配置参数:swappiness

1.4 应用场景

二、Linux内存扩容-swap配置

三、Linux的free  top命令

free命令(宏观命令 mpstat  、 vmstat )

 free列和available列的区别

top命令( 全局 + 局部 )

四、消失的进程怎么排查

4.1 生产环境问题描述

4.2 Demo + 基础知识

4.3 原因分析

4.4 如何发现问题

五、操作系统的OOM评分机制和进程雪崩

 什么是oom_score

一、内存不够了怎么办

1.1 操作系统内存不够怎么办

回收内存: 把不常用的内存 算法淘汰,比如LRU回收内存
内存置换:把不常用的内存通过交换分区直接写到磁盘中,置换一部分空间使用
杀死进程:内存紧张时系统还会通过 OOM(Out of Memory),会选择杀掉一些进程释放掉一些内存

1.2 什么是交换分区Swap 

进程占用内存很大,会导致内存消耗完,为解决该问题操作系统中运用Swap技术,拿部分硬盘空间来充当内存使用,作用是在物理内存使用完之后,将磁盘空间(也就是SWAP分区)虚拟成内存来使用

换页机制
      操作系统把物理内存中放不下的数据临时放到磁盘上,等到需要的时候再放回到物理内存中,提供超过物理内存容量的空间
    访问数据被swap换出 
        物理内存是有限资源,运行多进程时并不是每个进程都活跃,系统会启动  内存页面置换 (操作系统的页面置换算法)
        将长时间未使用的物理内存页帧放到swap分区,让出资源给其他进程
        当存在于swap分区的页面被访问时就会触发Page Fault 缺页异常,从而再置换回物理内存
预取机制
    换页过程涉及的磁盘IO操作,读取耗时比较多,因此操作系统会引入预取机制进行优化
    当发生换入操作时,预测还有哪些页会被访问,提前将它们一并换入物理页内存,减少发生缺页异常的次数 

1.3 swap配置参数:swappiness

 参数可以从0-100进行设置,默认值swappiness=60,表示内存使用率超过100-60=40%时开始使用交换分区
swappiness=0的时候表示最大限度使用物理内存,尽量不用 swap空间,有些云服务器厂商直接设置为0
注意:把swappiness设置成0不会禁止swap, 是最大限度不用, 不是一定不用,想要禁止,就不要开启swap
swappiness=100的时候表示积极的使用swap分区,把内存上的数据及时的搬运到swap空间

命令
查看  cat /proc/sys/vm/swappiness
临时修改 echo 10 > /proc/sys/vm/swappiness
永久调整 vim /etc/sysctl.conf  加上.  vm.swappiness=10
配置建议
	根据不同的应用,有不同的配置,比如有些性能要求高中间件,由于硬盘io较慢,会要求禁用 swap, 
	分配太多的Swap空间会浪费磁盘空间,而Swap空间太少,则系统内存不够就会发生错误

  1.4 应用场景

kubernetes集群一般要关闭swap
Java 的应用一般也是要关闭swap,像Rocketmq、ElasticSearch 等
    Java应用会用到堆,开启了swap就会部分存储到磁盘上
    程序在 GC 的时候会遍历所有堆的内存,如果这部分内存是被 swap 到磁盘上,GC遍历的时候就会有磁盘IO影响性能

二、Linux内存扩容-swap配置

查看是否有开启swap  free -m
如果说0,则说明没开启

Linux 支持两种类型的 Swap:Swap分区 和 Swap文件(本次使用文件方式)

命令
dd:用指定大小的块 拷贝一个文件,并在拷贝的同时进行指定的转换,下面是参数
if = 文件名:输入文件名,缺省为标准输入,即指定源文件。< if = input file >
of = 文件名:输出文件名,缺省为标准输出,即指定目的文件。 < of = output file >
bs = bytes:同时设置读入/输出的块大小为bytes个字节, 可代替 ibs 和 obs
count = blocks:仅拷贝blocks个块,块大小等于指定的字节数
bs是每次读或写的大小,即一个块的大小,count是读写块的数量 

Demo:
增加swap分区文件大小,创建一个大小为256M的文件(256 * 1024kb =262144)

dd if=/dev/zero of=/swapfile bs=1024 count=262144

#/dev/zero是一个输入设备,用它来初始化文件
# if -> input_file输入文件   of -> output_file输出文件   bs -> block_size块大小   count -> 计数

把创建的文件变成swap文件

mkswap /swapfile

 

启用这个swap文件

swapon /swapfile

【可选】编辑  /etc/fstab 文件,末行添加下面命令,每次开机时自动加载swap文件

vim /etc/fstab
/swapfile swap swap default 0 0

【可选】如果不需要了,也可以卸载

swapoff /swapfile

【可选】查看swap文件位置

三、Linux的free  top命令

free命令(宏观命令 mpstat  、 vmstat )

显示Linux系统中空闲的、已用的物理内存、swap内存 和 被内核使用的buffer
格式 free [参数]

 显示结果说明:

 free列和available列的区别

free 是真正未被使用的物理内存数量
available 是应用程序的角度看到的可用内存数量
Linux 为了提升读写性能,会消耗一部分内存资源缓存磁盘数据,就是buffer 和 cache(下面篇幅有介绍)
没有足够的 free 内存可以用,内核就会从 buffer 和 cache 中回收内存
大概计算:available = free + buff/ cache     total = used + free + buff/cache  

top命令( 全局 + 局部 )

能够实时显示系统中各个进程的资源占用状况,包括进程ID、内存占用率、CPU占用率等
格式  top [参数] ,按1后 显示各个cpu明细情况

全局信息:
# 当前时间  系统启动到现在的时间,当前用户数 ,CPU的 1 5 15分钟负载
top - 15:05:58 up 27 days, 20:43,  1 user,  load average: 0.00, 0.04, 0.05

#共计96个进程  ,2个在运行,94个在睡眠 ,0个停止,0个僵尸进程
Tasks:  96 total,   2 running,  94 sleeping,   0 stopped,   0 zombie

#us用户态占用CPU的百分比,sy内核态占用CPU的百分比, id — 空闲CPU百分比
#wa等待IO占用CPU的百分比, hi硬中断(Hardware IRQ)占用CPU的百分比, si软中断(Software Interrupts)占用CPU百分比
%Cpu(s):  1.0 us,  0.7 sy,  0.0 ni, 98.3 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st

#内存状态  total物理内存总量,free空闲内存总量, used使用中的内存总量, buff/cache缓存的内存量 
KiB Mem :  7733316 total,  3722316 free,  1047632 used,  2963368 buff/cache

#swap交换分区信息  total交换区总量, free空闲交换区总量, used使用的交换区总量, avail进程可用内存空间
KiB Swap:   262140 total,   262140 free,        0 used.  6380096 avail Mem 

局部进行详细信息:
# 进程的状态信息 PID 进程id,USER进程所有者,PR进程优先级 是动态优先级 ;NI nice负值表示高优先级,静态优先级一般不变
# VIRT 进程使用的虚拟内存总量 VIRT=SWAP+RES,申请过的内存没有真正分配物理内存也会计算在内,进程的虚拟内存比常驻内存大得多
# RES 进程实际使用的、未被换出的物理内存大小,即不包括 Swap 和共享内存,单位kb
# SHR共享内存大小,单位kb


# S进程状态,D=不可中断的睡眠状态 R=运行 S=睡眠 T=停止 Z=僵尸进程了;%CPU上次更新到现在的CPU时间占用百分比
# %MEM 进程使用的物理内存百分比;TIME+ 进程使用的CPU时间总计,单位1/100秒; COMMAND  进程名称(命令名/命令行)
 

 PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND                                                                                                                    
16122 101       20   0 6600532 348952  77932 S   2.0  4.5 567:45.61 clickhouse-serv                                                                                                                             
11691 root      10 -10  151540  34696  10368 S   1.0  0.4 376:50.51 AliYunDunMonito                                                                                                                             
11681 root      10 -10  100436   8056   6524 S   0.3  0.1 101:38.64 AliYunDun                                                                                                                                   
1 root      20   0   43656   3796   2404 S   0.0  0.0   0:25.80 systemd     

四、消失的进程怎么排查

4.1 生产环境问题描述

一台机器线上的某个进程直接就消失了,别的机器上的服务都正常跑着,怎么排查原因?
举一反三:java进程、mysql、redis、mq 也是一样的情况

4.2 Demo + 基础知识

基础知识:
 gcc 是一个编译器,没有界面,在命令行模式下使用,通过 gcc 命令可以将源文件编译成可执行文件。
 gcc 命令如果不指定目标文件名时默认生成的可执行文件名为 a.out(linux) 或 a.exe(windows)。
 可用 gcc [源文件名] -o [目标文件名] 来指定目标文件路径及文件名
 C语言中,malloc函数的作用是动态分配内存,不能自动释放,申请的内存单位是字节
 安装 gcc  yum install gcc -y

服务准备: 一般普通C语言代码  user_service_oom.zip

 编译程序: gcc user_service.c -o user_service.out

 运行程序 ./user_service.out

服务运行中: 

服务消失:

 查看刚才的那个运行的代码: 

c语言中的malloc函数是不断申请内存的

 

进程消失重现分析: 

 # 释放所有缓存
  echo 3 > /proc/sys/vm/drop_caches

  # 动态查看机器内存
  free -h -s 1

终端一
  # 释放所有缓存
  echo 3 > /proc/sys/vm/drop_caches
  # 动态查看机器内存
  free -h -s 1

终端二
  # 实时查看top,进程的内存、CPU运行情况
  top

终端三
  # 编译程序
  gcc user_service.c -o user_service.out
  # 运行程序 
  ./user_service.out

4.3 原因分析

Linux服务器上有多个应用进程运行,应用压力突增情况下容易出现各种问题,在多应用部署时需要注意对内存分配和资源隔离

比如 :
Linux系统在内存不足等条件下会主动干预进程(OOM-Killer机制)
OOM killer 给进程打分,把 oom_score 最大的进程先杀死, 打分主要有两部分组成
一种系统根据该进程的内存占用情况打分,进程的内存开销是变化的,所以该值也会动态变化
另一种用户可以设置的 oom_score_adj,范围是 -1000到 1000


当然,另外一个常见情况,就是某个同事重启了机器,导致程序没开机自启动运行
通过执行last reboot 查看机器都什么时间是否重启过
或者top查看系统运行了多久

4.4 如何发现问题

/var/log/messages 日志

是核心系统日志文件,包括整体系统信息、系统启动时的引导消息、系统运行时的其他状态消息
在做故障诊断时可以首先查看该文件内容,比如IO 错误、网络错误和其他系统错误都会记录到这个文件中

#查看最新的10行
tail -10 /var/log/messages


#过滤kill进程相关的日志
cat /var/log/messages | grep Kill

 /var/log/dmesg
用dmesg查看,包含内核缓冲信息,在系统启动时,会在屏幕上显示许多与硬件有关的信息

#egrep 详细:   -i 忽略大小写  -C n key 输出匹配key关键字及关键字上下的n行

#过滤出  killed process 上下10行日志
dmesg | egrep -i -C10 'killed process'

#增加人类可读的时间戳
dmesg -T 

#常用完整命令
dmesg -T | egrep -i -C10 'killed process'

五、操作系统的OOM评分机制和进程雪崩

 什么是oom_score

对某一个task进程进行打分(oom_score),实际得分需要考虑两方面,然后把 oom_score 最大的进程先杀死
一部分是系统打分,主要是根据该task的内存使用情况,进程的内存开销是变化的,所以该值也会动态变化
另一部分是用户打分,也就是oom_score_adj,默认是0,取值范围是-1000~1000
         0表示用户不调整oom_score,负值表示要在实际打分值上减去一个折扣
         正值表示要惩罚对应的进程,也就是增加该进程的oom_score
         如果用户将该进程的 oom_score_adj 设定成 -1000,表示禁止OOM killer 杀死该进程,特别重要的服务可以配置

proc 文件系统是虚拟文件系统, 某个进程被杀掉, 则 /proc/pid/ 目录也就被销毁

 查看系统本身对进程的评分,内存是变化的,所以该值也会动态变化

#执行这个程序,调用多次
cat /proc/$(pidof user_service.out)/oom_score

程序再运行中的时候,才会有对应的目录产生

用户手工修改进程的评分(大量申请内存,操作的时候会卡顿)

#先查看系统的评分
cat /proc/$(pidof user_service.out)/oom_score
#先查看用户默认的评分
cat /proc/$(pidof user_service.out)/oom_score_adj

#手工修改评分
sudo sh -c "echo -500 > /proc/$(pidof user_service.out)/oom_score_adj"

#查看修改后的评分
cat /proc/$(pidof user_service.out)/oom_score_adj
#再查看系统的评分
cat /proc/$(pidof user_service.out)/oom_score

 注意:

把一个一直申请内存的进程的 oom_score_adj 设置为-1000,会导致大量的都进程被kill
因为使用了bash所以这个bash挂了,user_service.out也停止了,如果是后端运行,则更多进程都会被kill

#进程的 oom_score_adj 设置为-1000
sudo sh -c "echo -1000 > /proc/$(pidof user_service.out)/oom_score_adj"

#过滤kill进程相关的日志
cat /var/log/messages | grep Kill

#常用完整命令, 可能损坏查询不到信息
dmesg -T| grep "Out of memory"
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值