解决云服务器内存占用高问题

任务

网站最初运行良好,但随着时间的推移出现了崩溃。长时间无法访问,阿里云发来告警短信、邮件,两次出击分别处理CPU占用高与内存占用高问题。

虚拟内存

这个是最初遇到的问题,因为在配置RSSHub:快速整合资源设置了虚拟内存以便解决下载中断问题,但此后频繁发生了CPU过高的问题。

通过阿里云监控面板可见cpu占用率会达到100%

究其原因,使用top指令,查看CPU占用高的进程,发现名为kswap0的进程占用了93.7%!

在这里插入图片描述

linux top命令VIRT,RES,SHR,DATA的含义

VIRT:virtual memory usage 虚拟内存

  1. 进程“需要的”虚拟内存大小,包括进程使用的库、代码、数据等
  2. 假如进程申请100m的内存,但实际只使用了10m,那么它会增长100m,而不是实际的使用量

RES:resident memory usage 常驻内存

  1. 进程当前使用的内存大小,但不包括swap out
  2. 包含其他进程的共享
  3. 如果申请100m的内存,实际使用10m,它只增长10m,与VIRT相反
  4. 关于库占用内存的情况,它只统计加载的库文件所占内存大小

SHR:shared memory 共享内存

  1. 除了自身进程的共享内存,也包括其他进程的共享内存
  2. 虽然进程只使用了几个共享库的函数,但它包含了整个共享库的大小
  3. 计算某个进程所占的物理内存大小公式:RES – SHR
  4. swap out后,它将会降下来

kswapd0

当然要搜索kswapd0它是何方神圣,不过名中内嵌的swap让人猜测大概:

kswapd0进程的作用:

它是虚拟内存管理中,负责换页的,操作系统每过一定时间就会唤醒kswapd ,看看内存是否紧张,如果不紧张,则睡眠,在 kswapd 中,有2 个阀值,pages_hige 和 pages_low,当空闲内存页的数量低于 pages_low 的时候,kswapd进程就会扫描内存并且每次释放出32 个free pages,直到 free page 的数量到达pages_high。

Linux设置大内存页解决kswapd0进程过渡消耗CPU的问题

更直接的表述如下:

  • swap分区的作用是当物理内存不足时,会将一部分硬盘当做虚拟内存来使用。
  • kswapd0 占用过高是因为 物理内存不足,使用swap分区与内存换页操作交换数据,导致CPU占用过高。

上面文章提供一种解决方案是设置大内存页,以减少换页的频率,当然我这里就直接将扩展的虚拟内存删除,以绝后患。

$ rm -rf /var/swapfile
   (这里的swapfile是之前设置的虚拟内存文件名)
$ df -h

php-fpm

还让人警惕的是服务器的内存占用依然很高,top命令后,输入M(shift+m)即可得到按内存占用率排序的进程。

在这里插入图片描述

可见php-fpm占据榜单大部,而重启php-fpm服务后,内存就得到了释放,因此需要在这里做文章。

在这里插入图片描述

那先了解一下php-fpm是什么

PHP-FPM(FastCGI Process Manager)是一个PHPFastCGI管理器,提供了进程管理的功能。

进程包含 master 进程和 worker 进程两种进程。 master 进程只有一个,负责监听端口,接收来自 Web Server 的请求,而 worker 进程则一般有多个(具体数量根据实际需要配置), 每个进程内部都嵌入了一个 PHP 解释器,是 PHP 代码真正执行的地方。

来自 <php-fpm-百度百科> <Nginx+PHP-FPM运行原理>

配置文件

参考文章:Linux的php-fpm优化心得-php-fpm进程占用内存大和不释放内存问题(转)

本机的配置文件为/etc/php-fpm.d/目录下的www.conf文件,具体的文件详情可以参考文章php-fpm配置文件详解

在阅读文章后,根据服务器1G的内存大小,只修改子进程的最大数量,把最大子进程数pm.max_children改为15与最大空闲子进程数pm.max_spare_servers改为 15

; Note: Used when pm is set to 'static', 'dynamic' or 'ondemand'
; Note: This value is mandatory.
; 同一时刻能够存活的最大子进程的数量
pm.max_children = 15 #50
; The number of child processes created on startup.
; Note: Used only when pm is set to 'dynamic'
; Default Value: min_spare_servers + (max_spare_servers - min_spare_servers) / 2
pm.start_servers = 5
; The desired minimum number of idle server processes.
; Note: Used only when pm is set to 'dynamic'
; Note: Mandatory when pm is set to 'dynamic'
pm.min_spare_servers = 5
; The desired maximum number of idle server processes.
; Note: Used only when pm is set to 'dynamic'
; Note: Mandatory when pm is set to 'dynamic'
; 最大空闲子进程数量,空闲子进程数量超过这个值,那么相应的子进程会被杀掉。
pm.max_spare_servers = 15 # 35

效果展示

此时php-fpm的进程数就龟缩为7、8个,而按照每个进程大约占用40-60M的内存空间,共计占用约400M,可以承载。

在这里插入图片描述

目前的free命令查看占用结果,available为1.1G,远高于之前的319M,再经过一段时间继续验证有效性。

在这里插入图片描述

Leave a comment

Your email address will not be published. Required fields are marked *