运维自动化脚本监控与维护霜儿-汉服-造相Z-Turbo GPU部署环境的健康状态做AI应用部署最怕什么不是模型效果不好而是半夜被报警电话吵醒告诉你服务器挂了服务停了GPU又过热了。尤其是像“霜儿-汉服-造相Z-Turbo”这类对GPU资源要求高、持续运行的应用手动维护不仅耗时还容易出错。今天咱们就来聊聊怎么用几段简单的脚本把GPU服务器的监控和维护工作自动化起来。你不用再整天盯着命令行脚本会帮你检查GPU状态、清理垃圾文件、重启异常服务甚至每天给你发一份资源使用报告。咱们的目标是让运维工作从“救火”变成“防火”睡个安稳觉。1. 环境准备与脚本基础在开始写脚本之前得先把“战场”准备好。咱们的脚本主要用Shell和Python这两种语言在Linux服务器上几乎是标配用起来也方便。1.1 检查你的工具箱首先登录到你的GPU服务器打开终端看看必要的工具齐不齐。# 检查Python3是否安装 python3 --version # 检查pip3Python包管理器是否安装 pip3 --version # 检查nvidia-smi命令是否可用这是监控GPU的核心工具 nvidia-smi --help | head -5如果nvidia-smi命令找不到那可能是NVIDIA驱动没装好得先解决这个问题。python3和pip3一般系统都自带如果没有用系统包管理器安装一下也很简单比如在Ubuntu上就是sudo apt install python3 python3-pip。1.2 安装必要的Python库我们的脚本会用到一些Python库来处理数据和发邮件。用pip安装一下很快。pip3 install psutil pandaspsutil一个跨平台的库能轻松获取系统信息比如CPU、内存、磁盘使用情况。pandas处理数据和生成漂亮报表的神器虽然我们只用它一点基础功能。好了工具齐了咱们就可以动手写脚本了。记住所有脚本你都可以直接复制粘贴然后根据自己服务器的实际情况改改文件路径、邮箱地址这些参数就能用。2. 核心监控脚本给你的GPU做“体检”监控是运维的眼睛。第一个脚本咱们来写一个全面的“体检”脚本定期检查GPU和系统的健康状况。2.1 检查GPU状态与温度GPU是这类AI应用的核心它的状态和温度是首要监控指标。我们可以用nvidia-smi命令来获取这些信息。创建一个文件叫check_gpu_health.sh#!/bin/bash # 脚本check_gpu_health.sh # 功能检查GPU使用率、内存占用、温度及电源状态并在异常时告警。 LOG_FILE/var/log/gpu_health.log # 设置告警阈值 GPU_UTIL_THRESHOLD90 # GPU使用率阈值% GPU_MEM_THRESHOLD90 # GPU内存使用率阈值% GPU_TEMP_THRESHOLD85 # GPU温度阈值摄氏度 echo $(date) GPU健康检查报告 $LOG_FILE # 使用nvidia-smi查询GPU状态并以逗号分隔格式输出方便解析 nvidia-smi --query-gpuindex,name,utilization.gpu,utilization.memory,memory.total,memory.used,memory.free,temperature.gpu,power.draw,power.limit --formatcsv,noheader,nounits | while IFS, read -r index name gpu_util mem_util mem_total mem_used mem_free temp power_draw power_limit do # 去除变量中的空格 index$(echo $index | xargs) name$(echo $name | xargs) echo GPU [$index]: $name $LOG_FILE echo - 使用率: ${gpu_util}% $LOG_FILE echo - 显存使用: ${mem_used} MiB / ${mem_total} MiB (${mem_util}%) $LOG_FILE echo - 温度: ${temp}°C $LOG_FILE echo - 当前功耗: ${power_draw} W / 限制: ${power_limit} W $LOG_FILE # 异常判断与告警这里以日志记录为例实际可集成邮件、钉钉等通知 if (( $(echo ${gpu_util} $GPU_UTIL_THRESHOLD | bc -l) )); then echo [警告] GPU使用率过高 $LOG_FILE fi if (( $(echo ${mem_util} $GPU_MEM_THRESHOLD | bc -l) )); then echo [警告] GPU显存占用过高 $LOG_FILE fi if (( temp $GPU_TEMP_THRESHOLD )); then echo [警告] GPU温度过高 $LOG_FILE fi done echo $LOG_FILE这个脚本做了几件事记录检查时间。读取每块GPU的详细信息。把使用率、内存、温度、功耗这些关键数据写到日志文件里。如果任何一项指标超过了预设的阈值比如GPU使用率超过90%就在日志里标一个[警告]。你可以用crontab设置这个脚本每5分钟或10分钟跑一次# 编辑crontab crontab -e # 添加一行例如每10分钟运行一次 */10 * * * * /bin/bash /path/to/your/check_gpu_health.sh2.2 监控应用服务进程光GPU健康还不够部署的“霜儿-汉服-造相Z-Turbo”应用本身的服务进程也得活着。写个脚本检查它是否在运行。创建check_app_service.sh#!/bin/bash # 脚本check_app_service.sh # 功能检查特定AI应用服务进程是否存活若死亡则尝试重启。 APP_NAMEyour_app_process_name # 替换为你的实际进程名例如“python app.py”的一部分 LOG_FILE/var/log/app_service.log MAX_RETRY3 echo $(date) 开始检查服务: $APP_NAME $LOG_FILE if pgrep -f $APP_NAME /dev/null then echo $(date) 服务运行正常。 $LOG_FILE else echo $(date) [错误] 服务未运行尝试重启... $LOG_FILE # 这里替换为你的服务启动命令例如 # cd /path/to/your/app nohup python3 app.py app.log 21 YOUR_START_COMMAND_HERE # 简单重试机制 sleep 10 for i in $(seq 1 $MAX_RETRY); do if pgrep -f $APP_NAME /dev/null; then echo $(date) 服务重启成功 $LOG_FILE break else echo $(date) 第$i次重启尝试失败。 $LOG_FILE if [ $i -lt $MAX_RETRY ]; then sleep 5 # 再次尝试启动命令 YOUR_START_COMMAND_HERE fi fi done fi echo $LOG_FILE关键一步你需要把脚本里的your_app_process_name和YOUR_START_COMMAND_HERE替换成你实际的应用信息。怎么找进程名用ps aux | grep -i turbo或ps aux | grep python看看你的应用是怎么显示的。3. 自动化维护脚本当好服务器的“保洁”和“医生”监控发现问题维护脚本就来解决问题。接下来是几个实用的自动化维护脚本。3.1 自动清理过期生成文件AI应用在运行中会产生大量的临时文件或生成的结果文件比如图片时间长了会占满磁盘。写个脚本定期清理。创建clean_old_files.py#!/usr/bin/env python3 脚本clean_old_files.py 功能递归扫描指定目录删除超过设定天数的文件。 import os import time import shutil from datetime import datetime, timedelta def clean_directory(directory_path, days_old): 清理指定目录中超过days_old天的文件。 if not os.path.isdir(directory_path): print(f错误目录 {directory_path} 不存在。) return cutoff_time time.time() - (days_old * 86400) # 计算截止时间戳 deleted_count 0 total_freed_size 0 for root, dirs, files in os.walk(directory_path): for file in files: file_path os.path.join(root, file) try: file_mtime os.path.getmtime(file_path) if file_mtime cutoff_time: file_size os.path.getsize(file_path) os.remove(file_path) deleted_count 1 total_freed_size file_size print(f已删除: {file_path} (修改于 {time.ctime(file_mtime)})) except Exception as e: print(f删除文件 {file_path} 时出错: {e}) # 可选删除空文件夹谨慎使用确保不会误删 # for root, dirs, files in os.walk(directory_path, topdownFalse): # for dir in dirs: # dir_path os.path.join(root, dir) # if not os.listdir(dir_path): # os.rmdir(dir_path) # print(f已删除空文件夹: {dir_path}) print(f\n清理完成。共删除 {deleted_count} 个文件释放空间约 {total_freed_size / (1024**3):.2f} GB。) if __name__ __main__: # 在这里配置 TARGET_DIRECTORIES [ /path/to/your/app/static/generated_images, # 替换为你的图片生成目录 /path/to/your/app/logs, # 日志目录如果需要 /tmp/your_app_cache # 临时缓存目录 ] DAYS_TO_KEEP 7 # 保留最近7天的文件 # for dir_path in TARGET_DIRECTORIES: print(f\n正在清理目录: {dir_path}) clean_directory(dir_path, DAYS_TO_KEEP)使用前注意务必务必把TARGET_DIRECTORIES里的路径换成你服务器上真实的目录。可以先在一个测试目录上跑一下确认没问题再添加到定时任务。设置DAYS_TO_KEEP保留天数也要根据你的业务需求来。3.2 服务异常自动重启增强版我们把之前简单的进程检查升级一下加入更全面的健康检查比如检查服务端口是否可访问然后再决定是否重启。创建enhanced_service_guard.py#!/usr/bin/env python3 脚本enhanced_service_guard.py 功能增强版服务守护。检查进程是否存在并尝试检查服务端口是否响应若异常则重启。 import subprocess import time import socket import sys import logging # 配置日志 logging.basicConfig( levellogging.INFO, format%(asctime)s - %(levelname)s - %(message)s, handlers[ logging.FileHandler(/var/log/enhanced_service_guard.log), logging.StreamHandler(sys.stdout) ] ) logger logging.getLogger(__name__) def is_process_running(process_name): 检查进程是否在运行 try: # 使用pgrep查找进程 result subprocess.run([pgrep, -f, process_name], capture_outputTrue, textTrue) return result.returncode 0 and result.stdout.strip() ! except Exception as e: logger.error(f检查进程 {process_name} 时出错: {e}) return False def is_port_open(host, port, timeout5): 检查指定主机的端口是否开放并可连接 try: with socket.create_connection((host, port), timeouttimeout): return True except (socket.timeout, ConnectionRefusedError, OSError): return False except Exception as e: logger.error(f检查端口 {host}:{port} 时出错: {e}) return False def restart_service(start_command, work_dirNone): 重启服务 logger.info(正在尝试重启服务...) try: if work_dir: # 如果需要切换到特定目录 full_cmd fcd {work_dir} {start_command} else: full_cmd start_command # 使用nohup和让命令在后台运行 subprocess.Popen(full_cmd, shellTrue, stdoutsubprocess.DEVNULL, stderrsubprocess.DEVNULL) logger.info(f已执行重启命令: {full_cmd}) return True except Exception as e: logger.error(f执行重启命令失败: {e}) return False def main(): # 在这里配置 SERVICE_PROCESS_NAME your_app_process_name # 进程名 SERVICE_HOST 127.0.0.1 # 服务监听地址 SERVICE_PORT 7860 # 服务监听端口替换为你的 SERVICE_START_CMD python3 app.py # 服务启动命令 SERVICE_WORK_DIR /path/to/your/app # 服务所在目录可选 CHECK_INTERVAL 60 # 检查间隔秒 # logger.info(f开始守护服务: {SERVICE_PROCESS_NAME} (端口 {SERVICE_HOST}:{SERVICE_PORT})) while True: process_ok is_process_running(SERVICE_PROCESS_NAME) port_ok is_port_open(SERVICE_HOST, SERVICE_PORT) if not process_ok: logger.warning(f服务进程 {SERVICE_PROCESS_NAME} 未运行。) restart_service(SERVICE_START_CMD, SERVICE_WORK_DIR) elif not port_ok: logger.warning(f服务进程在运行但端口 {SERVICE_HOST}:{SERVICE_PORT} 无法连接可能已僵死。尝试重启...) # 先尝试终止进程 subprocess.run([pkill, -f, SERVICE_PROCESS_NAME], timeout10) time.sleep(3) restart_service(SERVICE_START_CMD, SERVICE_WORK_DIR) else: logger.info(f服务状态正常。) time.sleep(CHECK_INTERVAL) if __name__ __main__: main()这个脚本更聪明了它不仅看进程在不在还会去“敲门”检查端口。如果进程在但门敲不开端口不通说明服务可能“僵死”了它也会尝试重启。你可以用nohup python3 enhanced_service_guard.py 让这个脚本自己在后台一直运行。4. 生成资源使用日报表每天看一眼服务器的“体检报告”对长期稳定运行很有帮助。这个脚本会把GPU、CPU、内存、磁盘的使用情况汇总起来生成一份简单的日报甚至可以发到你的邮箱。创建generate_daily_report.py#!/usr/bin/env python3 脚本generate_daily_report.py 功能收集系统及GPU资源使用情况生成HTML格式的日报并支持邮件发送。 import subprocess import psutil import pandas as pd from datetime import datetime import smtplib from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart import socket def get_gpu_info(): 使用nvidia-smi获取GPU信息 gpu_data [] try: # 获取GPU详细信息 result subprocess.run([ nvidia-smi, --query-gpuindex,name,utilization.gpu,utilization.memory,memory.total,memory.used,temperature.gpu, --formatcsv,noheader,nounits ], capture_outputTrue, textTrue, checkTrue) for line in result.stdout.strip().split(\n): if line: idx, name, gpu_util, mem_util, mem_total, mem_used, temp line.split(, ) gpu_data.append({ GPU索引: idx, GPU名称: name, GPU使用率(%): float(gpu_util), 显存使用率(%): float(mem_util), 显存总量(MiB): int(mem_total), 显存已用(MiB): int(mem_used), 温度(°C): int(temp) }) except (subprocess.CalledProcessError, FileNotFoundError) as e: print(f获取GPU信息失败可能未安装NVIDIA驱动或nvidia-smi: {e}) gpu_data.append({错误: 无法获取GPU信息}) return gpu_data def get_system_info(): 获取系统CPU、内存、磁盘信息 info {} # CPU info[CPU使用率(%)] psutil.cpu_percent(interval1) info[CPU核心数] psutil.cpu_count() # 内存 mem psutil.virtual_memory() info[内存总量(GB)] round(mem.total / (1024**3), 2) info[内存已用(GB)] round(mem.used / (1024**3), 2) info[内存使用率(%)] mem.percent # 磁盘默认取根目录 disk psutil.disk_usage(/) info[磁盘总量(GB)] round(disk.total / (1024**3), 2) info[磁盘已用(GB)] round(disk.used / (1024**3), 2) info[磁盘使用率(%)] disk.percent return info def create_html_report(gpu_info, sys_info, hostname): 生成HTML格式的报告 report_date datetime.now().strftime(%Y年%m月%d日 %H:%M:%S) # 构建GPU信息表格 gpu_df pd.DataFrame(gpu_info) gpu_table gpu_df.to_html(indexFalse, classestable table-striped) if not gpu_df.empty else p无GPU数据/p # 构建系统信息表格 sys_df pd.DataFrame([sys_info]) sys_table sys_df.to_html(indexFalse, classestable table-striped) html_content f !DOCTYPE html html head meta charsetutf-8 title服务器资源日报 - {hostname}/title style body {{ font-family: Arial, sans-serif; margin: 20px; }} h1, h2 {{ color: #333; }} .table {{ border-collapse: collapse; width: 100%%; margin-bottom: 20px; }} .table th, .table td {{ border: 1px solid #ddd; padding: 8px; text-align: left; }} .table th {{ background-color: #f2f2f2; }} .warning {{ color: #e74c3c; font-weight: bold; }} .info {{ color: #3498db; }} .footer {{ margin-top: 30px; font-size: 0.9em; color: #7f8c8d; }} /style /head body h1 服务器资源使用日报/h1 pstrong服务器主机名:/strong {hostname}/p pstrong报告生成时间:/strong {report_date}/p h2 GPU状态/h2 {gpu_table} h2 系统资源状态/h2 {sys_table} div classfooter p此报告由自动化脚本生成建议每日查阅。/p p如有异常指标如使用率持续高于90%%请及时检查。/p /div /body /html return html_content def send_email_report(html_content, subject, to_emails): 发送邮件需要配置SMTP信息 # 在这里配置你的邮箱信息 SMTP_SERVER smtp.your-email-provider.com # 例如 smtp.qq.com, smtp.gmail.com SMTP_PORT 587 # 通常587是TLS端口 FROM_EMAIL your_emailexample.com FROM_PASSWORD your_email_password_or_app_specific_password # 注意可能是授权码非登录密码 # if not all([SMTP_SERVER, FROM_EMAIL, FROM_PASSWORD]): print(邮件配置不完整跳过发送。) return False msg MIMEMultipart(alternative) msg[Subject] subject msg[From] FROM_EMAIL msg[To] , .join(to_emails) # 添加HTML内容 html_part MIMEText(html_content, html) msg.attach(html_part) try: with smtplib.SMTP(SMTP_SERVER, SMTP_PORT) as server: server.starttls() # 启用TLS加密 server.login(FROM_EMAIL, FROM_PASSWORD) server.sendmail(FROM_EMAIL, to_emails, msg.as_string()) print(f日报已成功发送至 {to_emails}) return True except Exception as e: print(f发送邮件失败: {e}) return False def main(): hostname socket.gethostname() print(f正在为服务器 [{hostname}] 生成资源日报...) # 收集信息 gpu_info get_gpu_info() sys_info get_system_info() # 生成HTML报告 html_report create_html_report(gpu_info, sys_info, hostname) # 保存报告到本地文件 report_filename f/var/log/server_report_{datetime.now().strftime(%Y%m%d)}.html with open(report_filename, w, encodingutf-8) as f: f.write(html_report) print(f日报已保存至: {report_filename}) # 可选发送邮件 # 取消下面几行的注释并配置好邮箱信息即可自动发送邮件 # email_subject f服务器资源日报 - {hostname} - {datetime.now().strftime(%Y-%m-%d)} # recipient_list [admin1example.com, admin2example.com] # send_email_report(html_report, email_subject, recipient_list) if __name__ __main__: main()这个脚本生成一份带表格的HTML报告看起来挺清楚。你可以配置邮件发送功能需要填对SMTP信息这样每天报告就能自动飞到你的邮箱。如果不想发邮件它也会把报告保存在服务器的/var/log/目录下你可以随时用浏览器打开看。5. 总结把这些脚本组合起来一个基本的自动化运维框架就有了。定时运行check_gpu_health.sh帮你盯着硬件状态enhanced_service_guard.py像忠诚的卫士一样确保服务进程活着clean_old_files.py定期打扫“房间”清理垃圾generate_daily_report.py每天给你一份简洁明了的“工作简报”。刚开始用的时候建议你把脚本里的检查间隔设得短一点日志看得勤一点确保它们按你预期的方式工作。尤其是清理文件和重启服务的脚本一定要先在测试环境确认逻辑没问题。等跑顺了你就可以放心地把这些重复、琐碎的工作交给脚本自己腾出时间来处理更值得关注的问题。自动化运维的核心思路其实就是“把正确的操作固化下来让机器定时去执行”。今天这几个脚本算是个引子你可以根据自己的实际需求继续扩展比如监控网络流量、数据库连接状态或者把告警从日志升级成直接发到你的即时通讯软件里。工具是死的思路是活的怎么方便怎么来怎么稳定怎么来。获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。