【运维】如何在Ubuntu中设置一个内存守护进程来确保内存不会溢出

news2025/1/11 8:54:53

文章目录

  • 前言
  • 增加守护进程
      • 1. 编写监控脚本
      • 2. 创建 systemd 服务文件
      • 3. 启动并启用服务
      • 4. 验证服务是否运行
      • 注意事项
  • 如何修改守护进程
      • 1. 修改监控脚本
      • 2. 重新加载并重启服务
      • 3. 验证服务是否运行
      • 总结
  • 如何设置一个日志文件来查看信息
      • 1. 修改监控脚本以记录日志
        • 方法一:使用 `logger` 命令记录日志
        • 方法二:将日志重定向到文件
      • 2. 修改 systemd 服务文件(如果使用日志文件)
      • 3. 重新加载并重启服务
      • 4. 查看日志
        • 查看系统日志(如果使用 `logger` 命令)
        • 查看日志文件(如果将日志重定向到文件)
  • 服务脚本含义
      • `[Unit]` 部分
      • `[Service]` 部分
      • `[Install]` 部分
  • 总结全文【直接用这个即可】
      • 1. 编写监控脚本
      • 2. 创建 systemd 服务文件
      • 3. 启动并启用服务
      • 4. 验证服务是否运行
      • 5. 使用 `journalctl` 查看日志

前言

内存溢出后,服务器可能就打不开了,死机了。所以设置个程序监测内存占用状态,超出95%后,直接关掉那个最占用内存的进程。

增加守护进程

在Ubuntu上设置一个守护进程来监控内存使用情况,并在内存超过90%时终止内存占用最多的进程,可以通过编写一个shell脚本和使用systemd来实现。以下是详细的步骤和代码示例:

1. 编写监控脚本

创建一个脚本文件,例如monitor_memory.sh,其内容如下:

我在/root中创建了。

#!/bin/bash

# 设置内存阈值为95%
MEMORY_THRESHOLD=95

while true; do
  # 获取总内存和已用内存
  TOTAL_MEM=$(free | grep Mem | awk '{print $2}')
  USED_MEM=$(free | grep Mem | awk '{print $3}')
  
  # 计算已用内存的百分比
  MEMORY_USAGE=$(($USED_MEM * 100 / $TOTAL_MEM))
  
  # 如果内存使用超过阈值,找到并终止占用内存最多的进程
  if [ $MEMORY_USAGE -gt $MEMORY_THRESHOLD ]; then
    echo "Memory usage is at $MEMORY_USAGE%, which is above the threshold of $MEMORY_THRESHOLD%."
    TOP_PROCESS_INFO=$(ps -eo pid,comm,%mem,user --sort=-%mem | head -n 2 | tail -n 1)
    TOP_PROCESS_PID=$(echo $TOP_PROCESS_INFO | awk '{print $1}')
    TOP_PROCESS_USER=$(echo $TOP_PROCESS_INFO | awk '{print $4}')
    TOP_PROCESS_MEM=$(echo $TOP_PROCESS_INFO | awk '{print $3}')
    echo "Killing process $TOP_PROCESS_PID, owned by $TOP_PROCESS_USER, which is using $TOP_PROCESS_MEM% of memory."
    kill -9 $TOP_PROCESS_PID
  fi
  
  # 每隔60秒检查一次
  sleep 60
done

确保脚本具有可执行权限:

chmod +x monitor_memory.sh

2. 创建 systemd 服务文件

/etc/systemd/system/目录下创建一个服务文件,例如memory_monitor.service,其内容如下:

[Unit]
Description=Memory Monitor Service
After=network.target

[Service]
Type=simple
ExecStart=/root/monitor_memory.sh
Restart=on-failure

[Install]
WantedBy=multi-user.target

请将/path/to/your/monitor_memory.sh替换为实际的脚本路径。

3. 启动并启用服务

重新加载systemd,启动并启用服务:

sudo systemctl daemon-reload
sudo systemctl start memory_monitor.service
sudo systemctl enable memory_monitor.service

4. 验证服务是否运行

使用以下命令检查服务状态:

sudo systemctl status memory_monitor.service

如果一切正常,服务应该会显示为“active (running)”。

注意事项

  1. 这种方法会强制终止占用内存最多的进程,可能导致数据丢失或服务中断。请谨慎使用。
  2. 可根据需要调整脚本的检查频率和阈值。
  3. 可以在脚本中添加日志记录以便后续分析。

通过上述步骤,你就可以在Ubuntu上设置一个守护进程来监控内存使用情况,并在内存超过95%时终止占用最多的进程。

在这里插入图片描述

如何修改守护进程

比如要将监控频率从每60秒一次改为每10秒一次,同时更新和重启服务,你需要进行以下修改和操作:

1. 修改监控脚本

编辑之前创建的 monitor_memory.sh 脚本,将 sleep 时间从 60 秒改为 10 秒:

#!/bin/bash

# 设置内存阈值为95%
MEMORY_THRESHOLD=95

while true; do
  # 获取总内存和已用内存
  TOTAL_MEM=$(free | grep Mem | awk '{print $2}')
  USED_MEM=$(free | grep Mem | awk '{print $3}')
  
  # 计算已用内存的百分比
  MEMORY_USAGE=$(($USED_MEM * 100 / $TOTAL_MEM))
  
  # 如果内存使用超过阈值,找到并终止占用内存最多的进程
  if [ $MEMORY_USAGE -gt $MEMORY_THRESHOLD ]; then
    echo "Memory usage is at $MEMORY_USAGE%, which is above the threshold of $MEMORY_THRESHOLD%."
    TOP_PROCESS_INFO=$(ps -eo pid,comm,%mem,user --sort=-%mem | head -n 2 | tail -n 1)
    TOP_PROCESS_PID=$(echo $TOP_PROCESS_INFO | awk '{print $1}')
    TOP_PROCESS_USER=$(echo $TOP_PROCESS_INFO | awk '{print $4}')
    TOP_PROCESS_MEM=$(echo $TOP_PROCESS_INFO | awk '{print $3}')
    echo "Killing process $TOP_PROCESS_PID, owned by $TOP_PROCESS_USER, which is using $TOP_PROCESS_MEM% of memory."
    kill -9 $TOP_PROCESS_PID
  fi
  
  # 每隔10秒检查一次
  sleep 10
done

保存并关闭文件。

2. 重新加载并重启服务

执行以下命令重新加载 systemd,然后重启并启用服务:

sudo systemctl daemon-reload
sudo systemctl restart memory_monitor.service

3. 验证服务是否运行

使用以下命令检查服务状态:

sudo systemctl status memory_monitor.service

如果服务正常运行,它将显示为“active (running)”。

总结

通过以上步骤,你将监控频率改为每10秒检查一次,并重启了服务。这样,守护进程将每10秒检查一次内存使用情况,并在内存超过阈值时终止占用最多的进程。

如何设置一个日志文件来查看信息

为了查看脚本中 echo 命令打印的日志信息,可以将其输出重定向到一个日志文件。可以在 monitor_memory.sh 脚本中添加日志记录,并确保 systemd 服务配置正确处理日志输出。以下是详细步骤:

1. 修改监控脚本以记录日志

编辑 monitor_memory.sh 脚本,添加日志记录功能。可以使用 logger 命令将信息写入系统日志,也可以将日志输出重定向到一个专用的日志文件。以下是两种方法:

方法一:使用 logger 命令记录日志

echo 命令替换为 logger 命令,将信息写入系统日志:

#!/bin/bash

# 设置内存阈值为95%
MEMORY_THRESHOLD=95

while true; do
  # 获取总内存和已用内存
  TOTAL_MEM=$(free | grep Mem | awk '{print $2}')
  USED_MEM=$(free | grep Mem | awk '{print $3}')
  
  # 计算已用内存的百分比
  MEMORY_USAGE=$(($USED_MEM * 100 / $TOTAL_MEM))
  
  # 如果内存使用超过阈值,找到并终止占用内存最多的进程
  if [ $MEMORY_USAGE -gt $MEMORY_THRESHOLD ]; then
    logger "Memory usage is at $MEMORY_USAGE%, which is above the threshold of $MEMORY_THRESHOLD%."
    TOP_PROCESS_INFO=$(ps -eo pid,comm,%mem,user --sort=-%mem | head -n 2 | tail -n 1)
    TOP_PROCESS_PID=$(echo $TOP_PROCESS_INFO | awk '{print $1}')
    TOP_PROCESS_USER=$(echo $TOP_PROCESS_INFO | awk '{print $4}')
    TOP_PROCESS_MEM=$(echo $TOP_PROCESS_INFO | awk '{print $3}')
    logger "Killing process $TOP_PROCESS_PID, owned by $TOP_PROCESS_USER, which is using $TOP_PROCESS_MEM% of memory."
    kill -9 $TOP_PROCESS_PID
  fi
  
  # 每隔10秒检查一次
  sleep 10
done
方法二:将日志重定向到文件

将所有输出重定向到一个日志文件,例如 /var/log/memory_monitor.log

#!/bin/bash

# 设置内存阈值为95%
MEMORY_THRESHOLD=95
LOG_FILE="/var/log/memory_monitor.log"

while true; do
  # 获取总内存和已用内存
  TOTAL_MEM=$(free | grep Mem | awk '{print $2}')
  USED_MEM=$(free | grep Mem | awk '{print $3}')
  
  # 计算已用内存的百分比
  MEMORY_USAGE=$(($USED_MEM * 100 / $TOTAL_MEM))
  
  # 如果内存使用超过阈值,找到并终止占用内存最多的进程
  if [ $MEMORY_USAGE -gt $MEMORY_THRESHOLD ]; then
    echo "$(date): Memory usage is at $MEMORY_USAGE%, which is above the threshold of $MEMORY_THRESHOLD%." >> $LOG_FILE
    TOP_PROCESS_INFO=$(ps -eo pid,comm,%mem,user --sort=-%mem | head -n 2 | tail -n 1)
    TOP_PROCESS_PID=$(echo $TOP_PROCESS_INFO | awk '{print $1}')
    TOP_PROCESS_USER=$(echo $TOP_PROCESS_INFO | awk '{print $4}')
    TOP_PROCESS_MEM=$(echo $TOP_PROCESS_INFO | awk '{print $3}')
    echo "$(date): Killing process $TOP_PROCESS_PID, owned by $TOP_PROCESS_USER, which is using $TOP_PROCESS_MEM% of memory." >> $LOG_FILE
    kill -9 $TOP_PROCESS_PID
  fi
  
  # 每隔10秒检查一次
  sleep 10
done

确保日志文件具有写入权限:

sudo touch /var/log/memory_monitor.log
sudo chmod 666 /var/log/memory_monitor.log

2. 修改 systemd 服务文件(如果使用日志文件)

如果选择将日志输出重定向到文件,则需要确保 systemd 服务能够正确处理这些输出。在 /etc/systemd/system/memory_monitor.service 文件中,添加 StandardOutputStandardError 选项:

[Unit]
Description=Memory Monitor Service
After=network.target

[Service]
Type=simple
ExecStart=/root/monitor_memory.sh
StandardOutput=append:/var/log/memory_monitor.log
StandardError=append:/var/log/memory_monitor.log
Restart=on-failure

[Install]
WantedBy=multi-user.target

3. 重新加载并重启服务

执行以下命令重新加载 systemd,然后重启并启用服务:

sudo systemctl daemon-reload
sudo systemctl restart memory_monitor.service

4. 查看日志

根据你选择的日志记录方法,查看日志信息:

查看系统日志(如果使用 logger 命令)

使用 journalctl 查看日志:

sudo journalctl -u memory_monitor.service
查看日志文件(如果将日志重定向到文件)

使用 cattail 命令查看日志文件:

cat /var/log/memory_monitor.log
# 或
tail -f /var/log/memory_monitor.log

通过以上步骤,你可以在监控脚本中记录日志,并使用 systemd 服务来管理和查看这些日志。

服务脚本含义

这个 systemd 服务单元文件定义了一个名为 memory_monitor.service 的服务,该服务运行一个用于监控内存使用情况的脚本。以下是各部分的详细解释:

[Unit] 部分

  • Description=Memory Monitor Service:描述该服务的功能,这里是“内存监控服务”。
  • After=network.target:指定该服务应该在 network.target 之后启动。这意味着网络服务启动后才会启动该服务。

[Service] 部分

  • Type=simple:指定服务类型为 simple,表示 ExecStart 选项启动的进程不会派生其他子进程,且不会进入后台。systemd 会认为该服务的主进程就是 ExecStart 启动的进程。
  • ExecStart=/root/monitor_memory.sh:指定服务启动时执行的命令,即运行 /root/monitor_memory.sh 脚本。
  • StandardOutput=append:/var/log/memory_monitor.log:将标准输出(即脚本中 echo 或其他标准输出的内容)追加到 /var/log/memory_monitor.log 文件中。
  • StandardError=append:/var/log/memory_monitor.log:将标准错误输出(即脚本中错误信息的输出)追加到 /var/log/memory_monitor.log 文件中。
  • Restart=on-failure:如果服务因为非零退出状态失败,则自动重启服务。这有助于确保服务在意外故障时重新启动。

[Install] 部分

  • WantedBy=multi-user.target:指定该服务应该在多用户目标下启动。multi-user.target 是一个常用的系统运行级别,类似于传统的运行级别 3(多用户模式,不带图形界面)。

总结全文【直接用这个即可】

在Ubuntu上设置一个守护进程来监控内存使用情况,并在内存超过90%时终止内存占用最多的进程,可以通过编写一个shell脚本和使用systemd来实现。以下是详细的步骤和代码示例:

1. 编写监控脚本

创建一个脚本文件,例如monitor_memory.sh,其内容如下:

我在vim /root/monitor_memory.sh中创建了。

#!/bin/bash

# 设置内存阈值为95%
MEMORY_THRESHOLD=95

while true; do
  # 获取总内存和已用内存
  TOTAL_MEM=$(free | grep Mem | awk '{print $2}')
  USED_MEM=$(free | grep Mem | awk '{print $3}')
  
  # 计算已用内存的百分比
  MEMORY_USAGE=$(($USED_MEM * 100 / $TOTAL_MEM))
  
  # 如果内存使用超过阈值,找到并终止占用内存最多的进程
  if [ $MEMORY_USAGE -gt $MEMORY_THRESHOLD ]; then
    logger "Memory usage is at $MEMORY_USAGE%, which is above the threshold of $MEMORY_THRESHOLD%."
    TOP_PROCESS_INFO=$(ps -eo pid,comm,%mem,user --sort=-%mem | head -n 2 | tail -n 1)
    TOP_PROCESS_PID=$(echo $TOP_PROCESS_INFO | awk '{print $1}')
    TOP_PROCESS_USER=$(echo $TOP_PROCESS_INFO | awk '{print $4}')
    TOP_PROCESS_MEM=$(echo $TOP_PROCESS_INFO | awk '{print $3}')
    logger "Killing process $TOP_PROCESS_PID, owned by $TOP_PROCESS_USER, which is using $TOP_PROCESS_MEM% of memory."
    kill -9 $TOP_PROCESS_PID
  fi
  
  # 每隔10秒检查一次
  sleep 10
done

确保脚本具有可执行权限:

chmod +x monitor_memory.sh

2. 创建 systemd 服务文件

/etc/systemd/system/目录下创建一个服务文件,例如memory_monitor.service,其内容如下:

[Unit]
Description=Memory Monitor Service
After=network.target

[Service]
Type=simple
ExecStart=/root/monitor_memory.sh
StandardOutput=append:/var/log/memory_monitor.log
StandardError=append:/var/log/memory_monitor.log
Restart=on-failure

[Install]
WantedBy=multi-user.target

请将/root/monitor_memory.sh替换为实际的脚本路径。

3. 启动并启用服务

重新加载systemd,启动并启用服务:

sudo systemctl daemon-reload
sudo systemctl start memory_monitor.service
sudo systemctl enable memory_monitor.service

4. 验证服务是否运行

使用以下命令检查服务状态:

sudo systemctl status memory_monitor.service

如果一切正常,服务应该会显示为“active (running)”。

5. 使用 journalctl 查看日志

sudo journalctl -u memory_monitor.service

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1882765.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

使用机器学习,轻松预测问题产品,低成本高效率解决产品质量监测需求

01、案例说明 这个案例是一个酒厂,通过对其产品中不同化学性质的指标数值,寻找哪些是可能出现问题的产品。这是一个标准的离异点(Outlier)使用情形。 如果能够将在不同属性的一定范围之内的数据,作为判断的标准&#…

VSCode无法识别 node、npm

一、前提 电脑新安装了node.js,在cmd查看node和npm版本没有问题,但是在VSCode无法识别 1.cmd查看版本: 2.VSCode报错信息: 无法将“npm”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果…

Windows电脑自建我的世界MC服务器并与好友远程联机游戏教程

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

【一步一步了解Java系列】:对这个系列的总结以及对缺漏内部类知识的补充

看到这句话的时候证明:此刻你我都在努力 加油陌生人 br />个人主页:Gu Gu Study专栏:一步一步了解Java 喜欢的一句话: 常常会回顾努力的自己,所以要为自己的努力留下足迹 喜欢的话可以点个赞谢谢了。 作者&#xf…

08:结构体

结构体 1、为什么需要结构体2、如何定义结构体3、怎么使用结构体变量3.1、赋值和初始化3.2、结构体变量的输出 1、为什么需要结构体 为了表示一些复杂的事物,而普通的基本类型无法满足实际要求。什么叫结构体 把一些基本类型数据组合在一起形成的一个新的数据类型&…

Dns被莫名篡改的问题定位(笔记)

引言:最近发现用户的多台机器上出现了Dns被莫名修改的问题,从系统事件上看并未能正常确定到是那个具体软件所为,现在的需求就是确定和定位哪个软件具体所为。 解决思路: 首先到IPv4设置页面对Dns进行设置:通过ProcExp…

【MySQL备份】Percona XtraBackup基础篇

目录 1.关于Percona XtraBackup 2. Percona XtraBackup有哪些特点? 3.安装Percona XtraBackup 3.1.环境信息 3.2.安装步骤 4. xtrabackup内部流程图 5.Percona XtraBackup基础语法 5.1.全量备份 5.2.增量备份 5.2.1.基于全量备份的增量备份 5.2.2.基于前…

Java学习 (六) 面向对象--this、继承、方法重写、super

一、this 关键字 1、this 演示 vi Person.java public class Person {String name;int age;//显示声明构造器public Person(String s , int i){name s;age i;}public void setAge(int age){age age;}}vi PersonTest.java public class PersonTest {public static void m…

nextTick的应用和原理理解

一.代码的理解 <template><div id"app"><div></div><button click"fn" ref"box"> {{ name }}</button></div> </template><script> export default {data: function () {return {n…

【Linux】计算机网络基础:协议、分层结构与数据传输解析

文章目录 前言1. 认识“协议”1.1. 什么是协议1.2. 网络分层结构——网络 vs OS之间的关系1.2.1. 软案分层1.2.2. 网络分层(为什么&#xff1f;是什么&#xff1f;怎么办&#xff1f;) 1.3. 站在语言角度&#xff0c;重新理解协议 2. 网络传输基本流程3. 数据包封装和分用4. 网…

【剑指Offer系列】68-二叉树的最近公共祖先(哈希)

思路&#xff1a;使用map存储每个节点的父节点&#xff0c;则两个节点的最近公共祖先&#xff0c;即二者的最近父节点 1、中序遍历二叉树&#xff08;当前节点的下一个节点&#xff09; 2、记录每个节点的父节点 3、列出p的族谱、q的族谱 4、寻找二者最近的祖先 class Soluti…

安装 Docker 环境(通过云平台创建一个实例实现)

目录 1. 删除原有 yum 2. 手动配置 yum 源 3. 删除防火墙规则 4. 保存防火墙配置 5. 修改系统内核。打开内核转发功能。 6. 安装 Docker 7. 设置本地镜像仓库 8.重启服务 1. 删除原有 yum rm -rfv /etc/yum.repos.d/* 2. 手动配置 yum 源 使用 centos7-1511.iso 和 Xi…

《Programming from the Ground Up》阅读笔记:p1-p18

《Programming from the Ground Up》学习第1天&#xff0c;p1-18总结&#xff0c;总计18页。 一、技术总结 1.fetch-execute cycle p9, The CPU reads in instructions from memory one at a time and executes them. This is known as the fetch-execute cycle。 2.genera…

安防监控视频平台LntonCVS视频融合共享平台水电站视频智能监控系统的设计与特点

水电站作为重要的能源基地&#xff0c;其安全运行对保障能源供应和社会稳定至关重要。然而&#xff0c;传统的人工监控方式存在高成本、监控范围有限和反应速度慢等问题。因此&#xff0c;引入先进的视频智能监控系统成为当务之急&#xff0c;以提高效率和安全性。 安徽羚通科技…

Anti-C-Myc Antibody (Chicken) - FITC Conjugated

C-myc基因是myc基因家族的重要成员之一&#xff0c;是一种可使细胞无限增殖&#xff0c;获永生化功能&#xff0c;促进细胞分裂的基因&#xff0c;c-myc基因与多种肿瘤发生发展有关。C-myc基因定位于染色体8q24、IgH、IgK、Igλ链的基因位点分别在14q32、2P13和 22q11&#xff…

SeeSR: Towards Semantics-Aware Real-World Image Super-Resolution

CVPR2024 香港理工大学&OPPO&bytedancehttps://github.com/cswry/SeeSR?tabreadme-ov-file#-licensehttps://arxiv.org/pdf/2311.16518#page5.80 问题引入 因为有些LR退化情况比较严重&#xff0c;所以超分之后的结果会出现语义的不一致的情况&#xff0c;所以本文训…

模拟电子学基本概念+Keil5安装指南!!

2024-7-1&#xff0c;星期一&#xff0c;16:56&#xff0c;天气&#xff1a;阴转小雨&#xff0c;心情&#xff1a;晴。大家好啊&#xff0c;今天换了一个新的主题&#xff0c;为什么嘞&#xff0c;是因为截止到昨天&#xff0c;电路基础部分的内容已经暂时告一段落啦&#xff…

高斯过程的数学理解

目录 一、说明 二、初步&#xff1a;多元高斯分布 三、 线性回归模型与维度的诅咒 四、高斯过程的数学背景 五、高斯过程的应用&#xff1a;高斯过程回归 5.1 如何拟合和推理高斯过程模型 5.2 示例&#xff1a;一维数据的高斯过程模型 5.3 示例&#xff1a;多维数据的高斯过程模…

奔驰G350升级原厂自适应悬挂系统有哪些作用

奔驰 G350 升级自适应悬挂系统后&#xff0c;可根据行车路况自动调整悬架高度和弹性&#xff0c;从而提升驾乘的舒适性和稳定性。 这套系统的具体功能包括&#xff1a; • 多种模式选择&#xff1a;一般有舒适、弯道、运动及越野等模式。例如&#xff0c;弯道模式在过弯时能为…