构建自动化运维脚本:监控与维护cv_unet_image-colorization推理服务

发布时间:2026/8/2 9:45:15

构建自动化运维脚本:监控与维护cv_unet_image-colorization推理服务 构建自动化运维脚本监控与维护cv_unet_image-colorization推理服务想象一下这个场景你花了不少功夫终于把那个能把黑白照片变彩色的cv_unet_image-colorization模型部署到了服务器上。刚开始一切顺利生成的图片效果惊艳你也松了口气。但没过几天半夜突然收到用户投诉说服务挂了图片传上去半天没反应。你手忙脚乱地爬起来远程登录服务器发现是GPU显存爆了进程早就悄悄退出了。这种救火队员式的运维不仅让人身心俱疲更关键的是影响了服务的可靠性和用户体验。对于这类需要持续提供服务的AI推理应用尤其是像图像上色这种可能被频繁调用的服务仅仅完成部署是远远不够的。如何确保它能够7x24小时稳定运行在出现问题时能自动恢复甚至提前预警才是真正考验技术人的地方。今天我们就来聊聊怎么用Python编写一套自动化运维脚本为你的cv_unet_image-colorization推理服务穿上“金钟罩”。1. 为什么需要自动化运维脚本在深入代码之前我们先搞清楚为什么要费这个劲。手动检查不是不行但对于一个生产环境服务来说缺点太明显了。首先人力成本高。你需要时刻惦记着服务状态定时去敲命令检查这本身就是一种低效的重复劳动。其次响应延迟大。问题往往发生在你休息或者注意力不在的时候等用户反馈或你自己发现服务可能已经中断了好几个小时。最后问题排查难。服务突然挂了如果没有完善的日志和监控你就像在黑暗中摸索很难快速定位根因。自动化运维脚本就是为了解决这些问题而生的。它能帮你持续监控像不知疲倦的哨兵24小时盯着服务的健康状况。快速响应一旦发现问题能在几秒到几分钟内自动尝试修复比如重启服务。提前预警在问题彻底爆发如显存耗尽、进程崩溃前通过资源趋势分析发出警报给你留出主动干预的时间。积累数据记录服务的历史运行状态、资源使用情况为后续的容量规划和性能优化提供数据支持。对于cv_unet_image-colorization这类服务自动化运维的重点通常集中在进程存活状态、GPU资源、服务端口响应以及日志管理这几个核心维度上。2. 运维脚本核心功能设计一套实用的自动化运维脚本应该像一个细心的管家兼顾“检查”、“记录”、“处理”和“通知”四个方面。围绕cv_unet_image-colorization服务我们可以设计以下几个核心模块。2.1 服务健康检查这是最基础的检查目标是确认服务是否“活着”并能正常干活。进程检查服务通常以后台进程如通过gunicorn、uvicorn启动的Python进程形式运行。脚本需要检查该特定进程是否存在于系统进程列表中。端口监听检查服务进程在不代表它能对外提供服务。需要检查它监听的端口比如常用的7860、5000或8000是否处于LISTEN状态。API接口检查这是最彻底的检查。模拟一个真实的客户端请求比如发送一张小的测试图片到服务的推理接口验证其是否能返回正确的、预期的彩色化结果。这能发现进程僵死进程在但已不工作等更深层次的问题。2.2 系统与GPU资源监控cv_unet_image-colorization模型推理通常依赖GPU因此GPU资源是监控的重中之重。GPU显存监控持续监控GPU的显存使用率。如果发现显存使用率持续超过某个安全阈值例如90%可能意味着有内存泄漏或者当前并发请求量过大需要预警。GPU利用率监控监控GPU的计算单元使用率了解服务的负载情况。系统资源监控虽然主要压力在GPU但CPU使用率、系统内存和磁盘空间也需要适当关注避免因系统级问题导致服务异常。2.3 日志管理日志是排查问题的黄金线索。好的日志管理能让你事半功倍。日志轮转服务的访问日志和错误日志如果无限增长迟早会撑爆磁盘。脚本需要定期对日志文件进行轮转比如按天切割、压缩旧日志、只保留最近N天的日志等。关键错误扫描可以定期扫描最新的错误日志捕捉类似“CUDA out of memory”、“推理超时”、“模型加载失败”等关键错误信息并将其作为触发警报的事件之一。2.4 异常自愈与报警监控发现了问题接下来就要行动。自动重启当健康检查失败确认服务已不可用时脚本应能自动尝试重启服务进程。这是保障服务高可用的关键一步。多级报警不是所有问题都需要人工立即干预。可以设置多级报警机制预警例如GPU显存持续高于85%发送提醒告知需要关注。错误服务健康检查失败但自动重启成功发送错误通知告知已自动恢复。严重服务健康检查失败且自动重启多次仍不成功需要立即人工介入通过电话、钉钉/飞书机器人强提醒等方式通知负责人。3. 手把手编写Python运维脚本理论讲完了我们开始动手。下面我将用一个逐步深入的Python脚本示例把上述功能串联起来。这个脚本使用了psutil、requests、nvidia-ml-py3等常用库你可以根据实际情况调整。首先安装可能需要的库pip install psutil requests nvidia-ml-py33.1 基础监控与健康检查我们先从最核心的健康检查和GPU监控开始。#!/usr/bin/env python3 cv_unet_image-colorization 服务自动化运维监控脚本 作者你的名字 功能服务健康检查、GPU监控、自动重启、日志轮转、报警 import os import sys import time import logging import subprocess import smtplib from email.mime.text import MIMEText from datetime import datetime import psutil import requests import pynvml # 用于GPU监控需安装nvidia-ml-py3 # 配置区域 - 根据你的实际环境修改 SERVICE_NAME cv_unet_colorization # 你的服务进程名或包含的关键字 SERVICE_PORT 7860 # 你的服务监听端口 API_HEALTH_URL fhttp://localhost:{SERVICE_PORT}/health # 假设有健康检查接口 API_INFER_URL fhttp://localhost:{SERVICE_PORT}/infer # 推理接口 SERVICE_START_CMD cd /path/to/your/service python app.py # 启动服务的命令 LOG_DIR /var/log/colorization_service LOG_FILE os.path.join(LOG_DIR, service.log) # 报警配置 ALERT_EMAILS [adminyourcompany.com] SMTP_SERVER smtp.yourcompany.com SMTP_PORT 587 SMTP_USER monitoryourcompany.com SMTP_PASSWORD your_password # 监控阈值 GPU_MEMORY_THRESHOLD 90 # GPU显存使用率报警阈值% CHECK_INTERVAL 60 # 监控检查间隔秒 # 设置日志 logging.basicConfig( levellogging.INFO, format%(asctime)s - %(name)s - %(levelname)s - %(message)s, handlers[ logging.FileHandler(/var/log/ai_service_monitor.log), logging.StreamHandler(sys.stdout) ] ) logger logging.getLogger(__name__) def check_service_process(): 检查服务进程是否存在 for proc in psutil.process_iter([pid, name, cmdline]): try: cmdline .join(proc.info[cmdline]) if proc.info[cmdline] else # 通过进程命令行中包含的服务名或启动脚本名来识别 if SERVICE_NAME in cmdline or app.py in cmdline: logger.debug(f找到服务进程PID: {proc.info[pid]}) return True, proc.info[pid] except (psutil.NoSuchProcess, psutil.AccessDenied): pass logger.warning(未找到服务进程) return False, None def check_service_port(): 检查服务端口是否在监听 try: # 检查是否有进程在监听指定端口 for conn in psutil.net_connections(kindinet): if conn.laddr.port SERVICE_PORT and conn.status LISTEN: logger.debug(f端口 {SERVICE_PORT} 处于监听状态) return True except Exception as e: logger.error(f检查端口时出错: {e}) logger.warning(f端口 {SERVICE_PORT} 未找到监听) return False def check_service_api(): 通过健康检查接口或简单推理请求验证服务可用性 try: # 方法1调用健康检查接口如果服务提供了的话 resp requests.get(API_HEALTH_URL, timeout10) if resp.status_code 200: logger.debug(服务健康检查接口响应正常) return True except requests.RequestException as e: logger.debug(f健康检查接口请求失败尝试推理接口: {e}) # 方法2如果没有健康接口尝试一个极小的推理请求例如一个纯色小图 try: # 这里构造一个非常简单的测试请求避免消耗过多资源 test_data {image: base64_encoded_small_image_or_url} # 替换为你的测试数据 resp requests.post(API_INFER_URL, jsontest_data, timeout30) if resp.status_code 200: logger.debug(服务推理接口响应正常) return True else: logger.warning(f服务推理接口返回异常状态码: {resp.status_code}) except requests.RequestException as e: logger.error(f服务推理接口请求失败: {e}) return False def check_gpu_status(): 检查GPU状态返回显存使用率等信息 gpu_info [] try: pynvml.nvmlInit() device_count pynvml.nvmlDeviceGetCount() for i in range(device_count): handle pynvml.nvmlDeviceGetHandleByIndex(i) mem_info pynvml.nvmlDeviceGetMemoryInfo(handle) util pynvml.nvmlDeviceGetUtilizationRates(handle) gpu_info.append({ index: i, mem_used_mb: mem_info.used // 1024 // 1024, mem_total_mb: mem_info.total // 1024 // 1024, mem_percent: (mem_info.used / mem_info.total) * 100, gpu_util_percent: util.gpu }) # 检查是否超过阈值 if gpu_info[-1][mem_percent] GPU_MEMORY_THRESHOLD: logger.warning(fGPU {i} 显存使用率过高: {gpu_info[-1][mem_percent]:.1f}%) pynvml.nvmlShutdown() except Exception as e: logger.error(f获取GPU信息失败: {e}) return [] return gpu_info3.2 自动重启与日志管理接下来我们添加自动重启和简单的日志轮转功能。def restart_service(): 重启服务 logger.info(尝试重启服务...) try: # 先尝试优雅地停止现有进程如果有的话 process_found, pid check_service_process() if process_found and pid: try: os.kill(pid, 15) # 发送SIGTERM信号 time.sleep(5) if check_service_process()[0]: os.kill(pid, 9) # 如果还在发送SIGKILL强制终止 time.sleep(2) except ProcessLookupError: pass # 启动新进程 # 使用nohup或setsid让进程在后台运行避免脚本退出导致服务停止 start_cmd fnohup {SERVICE_START_CMD} {LOG_FILE} 21 subprocess.run(start_cmd, shellTrue, checkTrue) logger.info(服务重启命令已执行) time.sleep(10) # 等待服务启动 return True except subprocess.CalledProcessError as e: logger.error(f重启服务失败: {e}) return False def rotate_logs(log_file_path, max_backup_count7): 简单的日志轮转保留最近N天的日志 if not os.path.exists(log_file_path): return file_size_mb os.path.getsize(log_file_path) / (1024 * 1024) # 例如日志文件超过100MB时进行轮转 if file_size_mb 100: logger.info(f日志文件过大({file_size_mb:.1f}MB)开始轮转...) try: import shutil # 为旧日志添加时间戳后缀 timestamp datetime.now().strftime(%Y%m%d_%H%M%S) backup_file f{log_file_path}.{timestamp} shutil.move(log_file_path, backup_file) logger.info(f日志已备份至: {backup_file}) # 清理过旧的备份按文件名中的日期判断 log_dir os.path.dirname(log_file_path) base_name os.path.basename(log_file_path) backups sorted([f for f in os.listdir(log_dir) if f.startswith(base_name .)]) if len(backups) max_backup_count: for old_log in backups[:-max_backup_count]: os.remove(os.path.join(log_dir, old_log)) logger.debug(f删除旧日志: {old_log}) except Exception as e: logger.error(f日志轮转失败: {e})3.3 报警通知模块发现问题后要及时通知到人。这里提供邮件和命令行打印两种方式你可以轻松扩展成钉钉、企业微信机器人等。def send_alert(subject, message, levelERROR): 发送报警通知邮件示例 # 打印到日志和控制台 alert_msg f[{level}] {subject}: {message} if level ERROR: logger.error(alert_msg) elif level WARNING: logger.warning(alert_msg) else: logger.info(alert_msg) # 发送邮件这里以SMTP为例实际环境可能用邮件API try: msg MIMEText(message, plain, utf-8) msg[Subject] f[AI服务监控]{level} - {subject} msg[From] SMTP_USER msg[To] , .join(ALERT_EMAILS) with smtplib.SMTP(SMTP_SERVER, SMTP_PORT) as server: server.starttls() # 如果需要TLS server.login(SMTP_USER, SMTP_PASSWORD) server.send_message(msg) logger.info(报警邮件发送成功) except Exception as e: logger.error(f发送报警邮件失败: {e}) # 在实际生产中你还可以在这里添加钉钉/飞书机器人、短信等报警方式 # send_dingding_alert(subject, message)3.4 主监控循环最后我们把所有功能整合到一个持续运行的主循环里。def main_monitor_loop(): 主监控循环 consecutive_failures 0 # 连续失败次数 last_log_rotate_time time.time() logger.info(AI推理服务监控脚本启动...) logger.info(f监控服务端口: {SERVICE_PORT}, 检查间隔: {CHECK_INTERVAL}秒) while True: try: current_time time.time() logger.info(*50) logger.info(f开始第{int(current_time)}次监控检查...) # 1. 检查服务进程和端口 process_ok, pid check_service_process() port_ok check_service_port() api_ok check_service_api() service_healthy process_ok and port_ok and api_ok if not service_healthy: consecutive_failures 1 error_detail [] if not process_ok: error_detail.append(进程不存在) if not port_ok: error_detail.append(端口未监听) if not api_ok: error_detail.append(API无响应) alert_msg f服务健康检查失败({consecutive_failures}次)。详情: {; .join(error_detail)} if consecutive_failures 3: # 连续失败3次尝试重启 send_alert(服务不可用尝试重启, alert_msg, ERROR) if restart_service(): send_alert(服务已自动重启, 服务重启成功正在恢复监控, INFO) consecutive_failures 0 else: send_alert(服务重启失败, 自动重启失败需要人工介入, CRITICAL) else: send_alert(服务健康检查异常, alert_msg, WARNING) else: if consecutive_failures 0: logger.info(服务已恢复健康) consecutive_failures 0 # 2. 检查GPU状态 gpu_status check_gpu_status() for gpu in gpu_status: logger.info(fGPU{gpu[index]}: 显存 {gpu[mem_percent]:.1f}% ({gpu[mem_used_mb]}/{gpu[mem_total_mb]}MB), 利用率 {gpu[gpu_util_percent]}%) if gpu[mem_percent] GPU_MEMORY_THRESHOLD: send_alert(fGPU{gpu[index]}显存使用率过高, f当前使用率: {gpu[mem_percent]:.1f}%, WARNING) # 3. 定期日志轮转例如每天一次 if current_time - last_log_rotate_time 24 * 3600: # 每天一次 rotate_logs(LOG_FILE) last_log_rotate_time current_time logger.info(f本次检查完成。服务状态: {健康 if service_healthy else 异常}。等待下一次检查...) except Exception as e: logger.critical(f监控循环发生未捕获异常: {e}, exc_infoTrue) send_alert(监控脚本自身异常, str(e), CRITICAL) time.sleep(CHECK_INTERVAL) if __name__ __main__: # 可以在这里添加一些启动前的环境检查 if not os.path.exists(LOG_DIR): os.makedirs(LOG_DIR, exist_okTrue) main_monitor_loop()4. 让脚本真正自动化起来写好的脚本不能总靠手动运行。我们需要把它变成系统里一个可靠的后台服务。方案一使用Systemd推荐适用于Linux系统这是最规范、最强大的方式。创建一个systemd服务单元文件比如/etc/systemd/system/ai-service-monitor.service[Unit] DescriptionAI Colorization Service Monitor Afternetwork.target [Service] Typesimple Useryour_username # 指定运行用户 WorkingDirectory/path/to/your/script ExecStart/usr/bin/python3 /path/to/your/script/monitor.py Restartalways # 脚本意外退出时自动重启 RestartSec10 StandardOutputjournal StandardErrorjournal [Install] WantedBymulti-user.target然后启用并启动它sudo systemctl daemon-reload sudo systemctl enable ai-service-monitor.service sudo systemctl start ai-service-monitor.service # 查看状态和日志 sudo systemctl status ai-service-monitor.service journalctl -u ai-service-monitor.service -f方案二使用Supervisor如果你更喜欢Supervisor配置也很直观[program:ai-service-monitor] commandpython3 /path/to/your/script/monitor.py directory/path/to/your/script useryour_username autostarttrue autorestarttrue redirect_stderrtrue stdout_logfile/var/log/supervisor/ai-monitor.log方案三使用Crontab简单但不够健壮如果脚本本身是短时间运行检查一次然后退出可以用crontab定时执行# 编辑crontab crontab -e # 添加一行每5分钟运行一次 */5 * * * * /usr/bin/python3 /path/to/your/script/monitor.py /var/log/ai-monitor-cron.log 215. 总结与进阶思考到这里一个具备基本监控、自愈和报警功能的自动化运维脚本就搭建完成了。把它部署起来你基本上可以告别半夜被叫起来重启服务的烦恼服务的稳定性也会大大提升。实际用下来这套脚本在大多数场景下已经能解决80%的问题。它能帮你抓住服务进程崩溃、端口无响应、GPU显存泄漏这些常见毛病。但自动化运维的世界远不止于此你可以根据自己业务的复杂程度继续往里面添砖加瓦。比如你可以把监控数据GPU使用率、服务响应时间上报到Prometheus这类专业的监控系统里再用Grafana做成漂亮的仪表盘这样就能一眼看清服务的历史状态和趋势。报警也可以做得更智能不是一有问题就“狼来了”而是根据故障的严重程度、发生频率甚至结合业务流量来判断该发预警的发预警该打电话的打电话。另外这个脚本目前主要关注单个实例。如果你的服务是用Docker跑的或者后面做了集群化部署那监控的维度就要扩展到容器健康、节点状态、负载均衡这些层面了。不过别担心核心思路是相通的——定义清楚什么是“健康”然后持续检查发现问题就按预定规则处理或通知。自动化运维不是一个一劳永逸的项目而是一个持续迭代的过程。先从最影响稳定性的核心痛点开始搭一个能用的脚本让它跑起来。然后在实际运行中你会不断发现新的可以优化的点比如某个阈值设得不合理或者某种异常情况脚本没考虑到。慢慢完善它让它越来越贴合你的实际业务。最终你会发现花在编写和维护这些脚本上的时间会加倍地回报你在服务稳定性和个人时间上的自由。获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。

相关新闻