【Linux系统】一个常驻进程问题的再次分析

简介: 问题发生在两年前,回顾当时,问题排查缓慢,最终还是其他同学解决了问题,主要还是因为对底层原理了解不够,另外问题分析思路也不够清晰。线上问题,尤其是涉及底层内存、共享内存、进程等等的问题,还是必须要对这些基本原理和运行机制有足够的了解,才能够快速定位并解决实际问题。

一 问题回顾

启动进程时,shm_attach()方法报错:failed for key 0x6104e88b: No space left on device

当时定位的原因是:

主进程异常退出,导致信号量和共享内存没有回收,资源耗尽,当再次申请资源时,无可用资源导致

解决方案:清理信号量及共享内存。

二 问题再次剖析

2.1 shm_attach()方法

   根据php官方文档中的描述 shm_attach:创建或打开一个共享内存段(Creates or open a shared memory segment),说明:

shm_attach ( int $key , int|null $size = null , int $permissions = 0666 ) : SysvSharedMemory|false

   方法返回一个id,这个id可以用来通过指定的key来访问System V共享内存,第一次调用时创建共享内存段,需要设置参数size 和 可选参数permissions,默认$permissions值为0666

   第二次调用如果使用相同的key,将返回一个不同的SysvSharedMemory实例,但两个实例都访问相同的底层共享内存。size 和 permissions 参数都会被忽略。

2.2 System V共享内存

System V IPC 机制下的共享内存本质是一段特殊的内存区域,进程间需要共享的数据被放在该共享内存区域中,所有需要访问该共享区域的进程都要把该共享区域映射到本进程的地址空间中去。共享内存允许一个或多个进程通过同时出现在他们的虚拟地址空间的内存进行通信,而这块虚拟内存的页面被每个共享进程的页表条目所引用,同时并不需要再所有进程的虚拟内存都有相同的地址。

1.System V共享内存是一种最为搞笑的进程间通信方式,进程可以直接读写内存,而不需要任何数据的拷贝。

2.为了在多个进程间交换信息,内核专门留出了一块内存区,可以由需要访问的进程将其映射到自己的私有地址空间。进程就可以直接读写这一块内存而不要进行数据的拷贝,从而大大提高效率。

3.由于多个进程共享一段内存,因此也需要依靠某种同步机制。

System V 的IPC(Inter-Process Communication,进程间通信)对象有共享内存、消息队列、信号量(灯)。

注意:在IPC的通信模式下,不管是共享内存、消息队列还是信号量,每个IPC的对象都有唯一的名字,称为"键(key)"。通过"键",进程能够识别所用的对象。"键"与IPC对象的关系就如同文件名称于文件,通过文件名,进程能够读写文件内的数据,甚至多个进程能够公用一个文件。而在IPC的通信模式下,通过"键"的使用也能使得一个IPC对象能为多个进程所共用。

2.3 再看问题原因

   报错信息是在shm_attach()方法,而错误原因是failed for key 0x6104e88b: No space left on device。比较容易确定非硬盘空间问题,加上已经对shm_attach()方法有了上面的了解,那么就是出在共享内存分配/获取。

   进一步定位,由2.2可知,System V的IPC对象有共享内存、消息队列和信号量,其中可查的是共享内存空间和信号量,查询命令使用ipcs,常用命令如下:

ipcs可用来显示当前Linux系统中的共享内存段、信号量集、消息队列等的使用情况。
命令示例:
ipcs -a或ipc 显示当前系统中共享内存段、信号量集、消息队列的使用情况;
ipcs -m 显示共享内存段的使用情况;
ipcs -s 显示信号量集的使用情况;
ipcs -q 显示消息队列的使用情况;
ipcrm可用来删除对应的共享内存段、信号量、消息队列;
命令示例:
ipcrm -s semid 删除对应的信号量集
ipcrm -m shmid 删除对应的共享内存段
ipcrm -q msqid 删除对应的消息队列
批量删除可以使用命令:
ipcs -s|grep xxx|cut -d" " -f2|xargs -n1 ipcrm -s
ipcs -s|awk '/xxx/{print $2}'|xargs -n1 ipcrm -s
ipcs -s|awk '/xxx/{system("ipcrm -s "$2)}'
for i in echo `ipcs|grep xxx|cut -d" " -f2`; do ipcrm -s $i; done

通过ipcs -m 和 ipcs -s,确认是共享内存和信号量满导致,所以直接的解决方法就是先清理共享内存和信号量:

2.4 根源

   为什么会造成共享内存和信号量满?一个可以想到的原因就是二者在使用时并没有被正常释放。那么就需要其他信息来辅助我们更精确地定位问题。

   通过与OP配合,以及当时常出现的问题(现象)结合考虑:

1)发布时间过长,脚本机kill pid失败后等待90s后触发kill -9 pid,而强杀进程可能会导致共享变量和信号量无法正常释放,这是其一;

2)为什么kill pid会无法生效?通常来说,除非在代码中做了hook处理或触发其他异常情况(权限问题等)导致失败,通常不会触发这个问题;再考虑kill pid命令,等同于kill -15 pid命令,那么是否是我们的进程没有正确感知到这个信号量?基于这个思路,并在测试环境不断尝试kill pid动作及进程关闭效果(代码日志),最终定位到是所使用的laravel框架版本及依赖的php版本的问题,导致异步信号量支持的判断失效。后面又通过重写进程、进程管理及信号量管理,彻底解决了这一问题。

三 总结

   问题发生在两年前,回顾当时,问题排查缓慢,最终还是其他同学解决了问题,主要还是因为对底层原理了解不够,另外问题分析思路也不够清晰。线上问题,尤其是涉及底层内存、共享内存、进程等等的问题,还是必须要对这些基本原理和运行机制有足够的了解,才能够快速定位并解决实际问题。学无止境。

相关实践学习
CentOS 7迁移Anolis OS 7
龙蜥操作系统Anolis OS的体验。Anolis OS 7生态上和依赖管理上保持跟CentOS 7.x兼容,一键式迁移脚本centos2anolis.py。本文为您介绍如何通过AOMS迁移工具实现CentOS 7.x到Anolis OS 7的迁移。
相关文章
|
14天前
|
Linux
在 Linux 系统中,“cd”命令用于切换当前工作目录
在 Linux 系统中,“cd”命令用于切换当前工作目录。本文详细介绍了“cd”命令的基本用法和常见技巧,包括使用“.”、“..”、“~”、绝对路径和相对路径,以及快速切换到上一次工作目录等。此外,还探讨了高级技巧,如使用通配符、结合其他命令、在脚本中使用,以及实际应用案例,帮助读者提高工作效率。
52 3
|
14天前
|
监控 安全 Linux
在 Linux 系统中,网络管理是重要任务。本文介绍了常用的网络命令及其适用场景
在 Linux 系统中,网络管理是重要任务。本文介绍了常用的网络命令及其适用场景,包括 ping(测试连通性)、traceroute(跟踪路由路径)、netstat(显示网络连接信息)、nmap(网络扫描)、ifconfig 和 ip(网络接口配置)。掌握这些命令有助于高效诊断和解决网络问题,保障网络稳定运行。
39 2
|
8天前
|
Ubuntu Linux 网络安全
linux系统ubuntu中在命令行中打开图形界面的文件夹
在Ubuntu系统中,通过命令行打开图形界面的文件夹是一个高效且实用的操作。无论是使用Nautilus、Dolphin还是Thunar,都可以根据具体桌面环境选择合适的文件管理器。通过上述命令和方法,可以简化日常工作,提高效率。同时,解决权限问题和图形界面问题也能确保操作的顺利进行。掌握这些技巧,可以使Linux操作更加便捷和灵活。
14 3
|
11天前
|
网络协议 Linux 虚拟化
如何在 Linux 系统中查看进程的详细信息?
如何在 Linux 系统中查看进程的详细信息?
27 1
|
14天前
|
安全 网络协议 Linux
本文详细介绍了 Linux 系统中 ping 命令的使用方法和技巧,涵盖基本用法、高级用法、实际应用案例及注意事项。
本文详细介绍了 Linux 系统中 ping 命令的使用方法和技巧,涵盖基本用法、高级用法、实际应用案例及注意事项。通过掌握 ping 命令,读者可以轻松测试网络连通性、诊断网络问题并提升网络管理能力。
50 3
|
17天前
|
安全 Linux 数据安全/隐私保护
在 Linux 系统中,查找文件所有者是系统管理和安全审计的重要技能。
在 Linux 系统中,查找文件所有者是系统管理和安全审计的重要技能。本文介绍了使用 `ls -l` 和 `stat` 命令查找文件所有者的基本方法,以及通过文件路径、通配符和结合其他命令的高级技巧。还提供了实际案例分析和注意事项,帮助读者更好地掌握这一操作。
35 6
|
17天前
|
Linux
在 Linux 系统中,`find` 命令是一个强大的文件查找工具
在 Linux 系统中,`find` 命令是一个强大的文件查找工具。本文详细介绍了 `find` 命令的基本语法、常用选项和具体应用示例,帮助用户快速掌握如何根据文件名、类型、大小、修改时间等条件查找文件,并展示了如何结合逻辑运算符、正则表达式和排除特定目录等高级用法。
50 6
|
18天前
|
机器学习/深度学习 自然语言处理 Linux
Linux 中的机器学习:Whisper——自动语音识别系统
本文介绍了先进的自动语音识别系统 Whisper 在 Linux 环境中的应用。Whisper 基于深度学习和神经网络技术,支持多语言识别,具有高准确性和实时处理能力。文章详细讲解了在 Linux 中安装、配置和使用 Whisper 的步骤,以及其在语音助手、语音识别软件等领域的应用场景。
48 5
|
18天前
|
缓存 运维 监控
【运维必备知识】Linux系统平均负载与top、uptime命令详解
系统平均负载是衡量Linux服务器性能的关键指标之一。通过使用 `top`和 `uptime`命令,可以实时监控系统的负载情况,帮助运维人员及时发现并解决潜在问题。理解这些工具的输出和意义是确保系统稳定运行的基础。希望本文对Linux系统平均负载及相关命令的详细解析能帮助您更好地进行系统运维和性能优化。
41 3
|
18天前
|
监控 网络协议 算法
Linux内核优化:提升系统性能与稳定性的策略####
本文深入探讨了Linux操作系统内核的优化策略,旨在通过一系列技术手段和最佳实践,显著提升系统的性能、响应速度及稳定性。文章首先概述了Linux内核的核心组件及其在系统中的作用,随后详细阐述了内存管理、进程调度、文件系统优化、网络栈调整及并发控制等关键领域的优化方法。通过实际案例分析,展示了这些优化措施如何有效减少延迟、提高吞吐量,并增强系统的整体健壮性。最终,文章强调了持续监控、定期更新及合理配置对于维持Linux系统长期高效运行的重要性。 ####