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

news/2024/7/8 16:29:31 标签: 运维, ubuntu, chrome

文章目录

  • 前言
  • 增加守护进程
      • 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.niftyadmin.cn/n/5537486.html

相关文章

绝地求生PUBG没有开始游戏按钮的解决办法

绝地求生是一款特别热门的战术竞技型射击类游戏,游戏中玩家需要在游戏地图上收集各种资源,并在不断缩小的安全区域内持武器对抗其他玩家,让自己生存到最后。当游戏最后场上只剩下一支队伍的时候即可获得游戏胜利。然而一些玩家在游玩绝地求生…

复分析——第9章——椭圆函数导论(E.M. Stein R. Shakarchi)

第 9 章 椭圆函数导论 (An Introduction to Elliptic Functions) The form that Jacobi had given to the theory of elliptic functions was far from perfection; its flaws are obvious. At the base we find three fundamental functions sn, cn and dn. These functio…

springcloud 面试经常被问问题

Spring Cloud 是一个基于 Spring Boot 的微服务架构解决方案,包含了许多用于构建和管理微服务的工具和框架。在面试中,与 Spring Cloud 相关的问题通常会涉及其核心概念、组件、常用模式和解决方案。以下是一些在 Spring Cloud 面试中经常被问到的问题及…

python 进阶教程--matplotlib

matplotlib 3.1 安装配置3.2 Matplotlib 快速入门3.3 图形绘制线图散点图条形图饼图 3.4 风格样式使用内置样式创建自定义样式临时使用样式 3.1 安装配置 Matplotlib 是一个用于创建高质量图表的 Python 绘图库。在开始使用 Matplotlib 之前,需要先安装它。以下是安…

配置tmux,使用tmux的方法,tmux的相关指令,以及tmux相关的快捷键

配置tmux的方法,以及使用tmux的方法,相关指令,以及和tmux相关的快捷键吗? 首先,先列出来tmux 的最基本的使用方法,再详细介绍:tmux最基本使用方法:tmux相关快捷键 之后是tmux 的详细…

winform2

12.TabControl 导航控制条 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace zhiyou_…

【控制Android.bp的编译】

1.首先Android.bp的语法是不支持if 条件语句的 2.查到可以用enabled来控制Android.bp中的模块是否参与编译,但是并不能实现动态的控制,比如你需要根据获取到的安卓版本来控制一个Android.bp是否编译,是无法做到的。enabled只能是固定的true或…

Impala JDBC/ODBC driver返回不完整数据的解决办法

背景 用户在升级到CDP或Impala-3.4后,可能遇到JDBC/ODBC driver返回不完整数据的情况。比如实际查询结果有100行,但返回90行就结束了,每次的结果不一定相同,只有在时长超过10秒的查询会出现。这可能是遇到了JDBC/ODBC driver的bu…