M2LOrder模型在Ubuntu服务器上的生产环境部署与监控

张开发
2026/4/14 17:21:09 15 分钟阅读

分享文章

M2LOrder模型在Ubuntu服务器上的生产环境部署与监控
M2LOrder模型在Ubuntu服务器上的生产环境部署与监控你肯定遇到过这种情况在本地电脑上跑模型跑得好好的代码也没问题但一把它放到服务器上让它24小时不间断地提供服务各种幺蛾子就来了。服务莫名其妙挂掉、内存悄悄涨到爆、请求一多就卡死半夜还得爬起来重启。今天咱们就来彻底解决这个问题。这篇文章不是简单的“安装-运行”教程而是一份面向生产环境的全栈运维指南。我会手把手带你把一个M2LOrder模型服务从“能跑起来”的状态打造成一个高可用、可监控、易维护的线上服务。我们会用到Systemd、Nginx、Prometheus和Grafana这些工业级工具让模型服务像专业网站一样稳定运行。无论你是算法工程师需要自己运维服务还是运维同学需要接手AI模型部署这篇内容都能给你一套完整的、可落地的方案。1. 从零开始准备你的Ubuntu生产服务器在开始部署之前我们先得把“地基”打好。一个干净、安全、配置合理的服务器环境是后续一切稳定的前提。这里我以Ubuntu 20.04 LTS为例这也是目前很多云服务商推荐的稳定版本。1.1 系统初始化与安全加固拿到一台全新的Ubuntu服务器别急着装东西先做这几件事更新系统并安装基础工具首先通过SSH登录你的服务器。第一件事就是更新软件源并升级所有已安装的包这能确保我们使用最新的安全补丁。# 以root用户或使用sudo执行 sudo apt update sudo apt upgrade -y更新完成后安装一些后续部署和调试必备的工具sudo apt install -y curl wget vim git htop net-tools ufw python3-pip python3-venv创建一个专用的服务用户永远不要用root用户直接运行你的应用服务这非常危险。我们应该创建一个权限受限的专用用户。# 创建一个名为‘mlservice’的用户并指定其主目录 sudo useradd -m -s /bin/bash mlservice # 为该用户设置一个强密码 sudo passwd mlservice # 可选将该用户加入sudo组如果你需要它执行一些特权命令 # sudo usermod -aG sudo mlservice配置防火墙UFWUbuntu自带的ufw防火墙简单易用。我们只开放必要的端口。# 启用UFW sudo ufw enable # 默认拒绝所有入站连接允许所有出站连接 sudo ufw default deny incoming sudo ufw default allow outgoing # 允许SSH端口确保你在执行前已经通过SSH连接否则会被踢出 sudo ufw allow 22/tcp # 暂时允许我们后续会用到的端口模型服务端口假设用8000和Nginx的80/443 sudo ufw allow 8000/tcp sudo ufw allow 80/tcp sudo ufw allow 443/tcp # 查看防火墙状态 sudo ufw status verbose1.2 安装并配置Python环境生产环境强烈建议使用虚拟环境它能完美隔离不同项目的依赖。# 切换到我们创建的服务用户 sudo su - mlservice # 在用户主目录下创建项目文件夹 mkdir -p ~/m2lorder-service cd ~/m2lorder-service # 创建Python虚拟环境使用python3 python3 -m venv venv # 激活虚拟环境 source venv/bin/activate激活后你的命令行提示符前面应该会出现(venv)字样。接下来安装M2LOrder模型运行所需的核心依赖。这里假设你的模型是基于PyTorch的。# 升级pip pip install --upgrade pip # 安装PyTorch请根据你的CUDA版本到PyTorch官网获取最新安装命令 # 例如对于CUDA 11.8 pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118 # 安装其他可能需要的通用库 pip install numpy pandas scikit-learn # 安装Web服务框架这里以FastAPI为例因为它性能好适合生产环境 pip install fastapi uvicorn[standard] pydantic环境准备好后你可以先简单测试一下Python和主要库是否能正常导入。2. 部署M2LOrder模型服务现在我们来把模型代码变成一个有组织、可管理的服务。2.1 组织你的服务代码一个清晰的项目结构能让后期维护省心很多。在你的~/m2lorder-service目录下创建如下结构m2lorder-service/ ├── app/ # 应用核心代码 │ ├── __init__.py │ ├── main.py # FastAPI应用主文件 │ ├── model.py # 模型加载和推理逻辑 │ └── config.py # 配置文件 ├── requirements.txt # 项目依赖清单 ├── logs/ # 日志目录 │ └── .gitkeep └── README.md编写核心服务文件 (app/main.py)这个文件定义了我们的Web API接口。from fastapi import FastAPI, HTTPException from pydantic import BaseModel import logging from app.model import M2LOrderModel # 假设的模型类 from app.config import settings # 配置日志 logging.basicConfig( levelgetattr(logging, settings.LOG_LEVEL), format%(asctime)s - %(name)s - %(levelname)s - %(message)s ) logger logging.getLogger(__name__) # 创建FastAPI应用 app FastAPI(titleM2LOrder Model Service, version1.0.0) # 全局加载模型根据实际情况调整重型模型可能需懒加载 try: model M2LOrderModel(settings.MODEL_PATH) logger.info(M2LOrder model loaded successfully.) except Exception as e: logger.error(fFailed to load model: {e}) model None # 定义请求数据模型 class PredictionRequest(BaseModel): input_data: list # 根据你的模型输入格式调整 # 可以添加其他参数如top_k等 class PredictionResponse(BaseModel): prediction: list status: str model_version: str 1.0 # 健康检查端点 app.get(/health) async def health_check(): 服务健康状态检查 if model is None: raise HTTPException(status_code503, detailModel not loaded) return {status: healthy, model_loaded: True} # 模型预测端点 app.post(/predict, response_modelPredictionResponse) async def predict(request: PredictionRequest): 接收数据并返回模型预测结果 if model is None: raise HTTPException(status_code503, detailService unavailable) try: # 调用模型推理 result model.predict(request.input_data) logger.info(fPrediction request processed successfully.) return PredictionResponse(predictionresult, statussuccess) except Exception as e: logger.error(fPrediction error: {e}) raise HTTPException(status_code500, detailstr(e)) if __name__ __main__: # 开发时直接运行uvicorn app.main:app --reload --host 0.0.0.0 --port 8000 pass编写配置文件 (app/config.py)使用Pydantic的BaseSettings管理配置方便从环境变量读取。from pydantic import BaseSettings class Settings(BaseSettings): # 模型路径 MODEL_PATH: str ./models/m2lorder_model.pth # 服务配置 HOST: str 0.0.0.0 PORT: int 8000 WORKERS: int 4 # 日志级别 LOG_LEVEL: str INFO # 监控相关 METRICS_PORT: int 8001 # 为Prometheus暴露指标的端口 class Config: env_file .env # 可以从.env文件加载配置 settings Settings()2.2 使用Systemd托管服务手动在终端运行服务关掉终端服务就停了这不行。我们需要一个守护进程来管理它。Systemd是Linux系统的标准服务管理器用它来托管我们的Python服务非常合适。创建Systemd服务单元文件以root身份创建文件/etc/systemd/system/m2lorder.servicesudo vim /etc/systemd/system/m2lorder.service文件内容如下请根据你的实际路径修改[Unit] DescriptionM2LOrder Model Inference Service Afternetwork.target [Service] # 指定运行用户和组 Usermlservice Groupmlservice # 设置工作目录 WorkingDirectory/home/mlservice/m2lorder-service # 设置环境变量特别是PATH和Python虚拟环境 EnvironmentPATH/home/mlservice/m2lorder-service/venv/bin # 启动命令。使用uvicorn作为ASGI服务器指定worker数量 ExecStart/home/mlservice/m2lorder-service/venv/bin/uvicorn app.main:app --host 0.0.0.0 --port 8000 --workers 4 # 重启策略如果服务异常退出自动重启 Restartalways RestartSec10 # 日志相关 StandardOutputjournal StandardErrorjournal [Install] WantedBymulti-user.target启动并启用服务# 重新加载systemd配置使其识别新服务 sudo systemctl daemon-reload # 启动服务 sudo systemctl start m2lorder.service # 设置开机自启 sudo systemctl enable m2lorder.service # 查看服务状态 sudo systemctl status m2lorder.service如果状态显示active (running)恭喜你服务已经在后台稳定运行了你可以用curl测试一下curl http://localhost:8000/health应该返回{status:healthy,model_loaded:true}。常用管理命令sudo systemctl stop m2lorder.service# 停止服务sudo systemctl restart m2lorder.service# 重启服务sudo journalctl -u m2lorder.service -f# 实时查看服务日志3. 配置Nginx反向代理与SSL现在服务跑在8000端口但我们通常希望用标准的80HTTP或443HTTPS端口来访问并且可能一个服务器要跑多个服务。Nginx作为反向代理能帮我们实现这些还能提供负载均衡、静态文件服务等额外好处。3.1 安装并配置Nginx# 安装Nginx sudo apt install -y nginx为M2LOrder服务创建Nginx配置文件在/etc/nginx/sites-available/目录下创建一个配置文件例如m2lorder。sudo vim /etc/nginx/sites-available/m2lorder写入以下配置。这里假设你的域名是api.yourdomain.com如果没有域名可以暂时用服务器IP并注释掉server_name那行。server { listen 80; # 将 your_domain_or_ip 替换为你的域名或服务器IP地址 server_name api.yourdomain.com; # 访问日志和错误日志 access_log /var/log/nginx/m2lorder_access.log; error_log /var/log/nginx/m2lorder_error.log; # 反向代理到本地的FastAPI服务 location / { # 将请求转发给运行在8000端口的uvicorn服务 proxy_pass http://127.0.0.1:8000; # 传递重要的请求头信息 proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # 超时设置根据模型推理时间调整 proxy_read_timeout 300s; proxy_connect_timeout 75s; } # 可选为Prometheus指标暴露一个单独的路径下一节会用到 location /metrics { proxy_pass http://127.0.0.1:8001; proxy_set_header Host $host; allow 127.0.0.1; # 只允许本地访问或改为你的监控服务器IP deny all; } }启用站点并测试配置# 创建符号链接到sites-enabled目录 sudo ln -s /etc/nginx/sites-available/m2lorder /etc/nginx/sites-enabled/ # 测试Nginx配置语法是否正确 sudo nginx -t # 如果显示 syntax is ok 和 test is successful则继续 # 重新加载Nginx使配置生效 sudo systemctl reload nginx现在你应该可以通过服务器的IP地址或你配置的域名的80端口访问服务了http://your_server_ip/health。3.2 使用Let‘s Encrypt获取免费SSL证书为了安全生产环境必须使用HTTPS。Let‘s Encrypt提供了免费的SSL证书。# 安装Certbot和Nginx插件 sudo apt install -y certbot python3-certbot-nginx # 获取并自动配置SSL证书需要域名已解析到该服务器 sudo certbot --nginx -d api.yourdomain.com按照Certbot的提示操作输入邮箱、同意协议等它会自动修改你的Nginx配置将HTTP重定向到HTTPS并配置好证书路径。完成后你的Nginx配置会自动更新并添加类似下面的内容server { listen 443 ssl http2; server_name api.yourdomain.com; ssl_certificate /etc/letsencrypt/live/api.yourdomain.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/api.yourdomain.com/privkey.pem; # ... 其他SSL配置和原来的location块 } server { listen 80; server_name api.yourdomain.com; # 将HTTP请求重定向到HTTPS return 301 https://$server_name$request_uri; }现在用浏览器访问https://api.yourdomain.com/health应该能看到安全的小锁标志和健康的服务状态了。4. 搭建Prometheus Grafana监控看板服务跑起来了但我们怎么知道它是否健康、压力大不大、有没有出错呢不能总靠猜或者等用户投诉。我们需要一套监控系统。Prometheus负责收集指标Grafana负责漂亮地展示。4.1 为FastAPI服务添加指标暴露首先我们需要让M2LOrder服务暴露一些Prometheus能抓取的指标。# 在虚拟环境中安装prometheus的fastapi客户端 pip install prometheus-fastapi-instrumentator修改app/main.py添加指标收集# 在文件顶部导入 from prometheus_fastapi_instrumentator import Instrumentator # 在创建app之后定义路由之前添加指标收集器 Instrumentator().instrument(app).expose(app, include_in_schemaFalse, should_gzipTrue) # 注意expose方法会默认在/metrics路径暴露指标。 # 为了安全我们可能希望这个端点不被公网访问这就是为什么之前在Nginx里对/metrics做了IP限制。修改app/config.py中的Settings类确保我们为指标暴露指定了端口前面已定义METRICS_PORT 8001。但prometheus-fastapi-instrumentator默认会和主应用同一个实例如果你希望指标独立端口运行需要更复杂的设置。简单起见我们先使用默认的/metrics端点在主服务端口上。重启服务使更改生效sudo systemctl restart m2lorder.service访问https://api.yourdomain.com/metrics如果Nginx配置了IP限制你可能需要从服务器本地curl localhost:8000/metrics应该能看到一堆以# HELP和# TYPE开头的文本这就是Prometheus格式的指标。4.2 安装与配置Prometheus下载并安装Prometheus我们直接在服务器上安装Prometheus来抓取自身和M2LOrder服务的指标。# 切换到root或使用sudo cd /tmp # 下载最新稳定版的Prometheus请从官网检查最新版本号 wget https://github.com/prometheus/prometheus/releases/download/v2.48.0/prometheus-2.48.0.linux-amd64.tar.gz tar xvf prometheus-2.48.0.linux-amd64.tar.gz sudo mv prometheus-2.48.0.linux-amd64 /opt/prometheus创建Prometheus系统用户和目录sudo useradd --no-create-home --shell /bin/false prometheus sudo mkdir -p /var/lib/prometheus sudo chown -R prometheus:prometheus /opt/prometheus /var/lib/prometheus创建Systemd服务文件/etc/systemd/system/prometheus.service[Unit] DescriptionPrometheus Monitoring Wantsnetwork-online.target Afternetwork-online.target [Service] Userprometheus Groupprometheus Typesimple ExecStart/opt/prometheus/prometheus \ --config.file/opt/prometheus/prometheus.yml \ --storage.tsdb.path/var/lib/prometheus/ \ --web.console.templates/opt/prometheus/consoles \ --web.console.libraries/opt/prometheus/console_libraries \ --web.listen-address0.0.0.0:9090 Restartalways [Install] WantedBymulti-user.target配置Prometheus抓取目标编辑/opt/prometheus/prometheus.ymlglobal: scrape_interval: 15s # 每15秒抓取一次指标 evaluation_interval: 15s # 每15秒评估一次规则 scrape_configs: # 监控Prometheus自身 - job_name: prometheus static_configs: - targets: [localhost:9090] # 监控M2LOrder模型服务 - job_name: m2lorder-service static_configs: - targets: [localhost:8000] # 通过Nginx代理的/metrics端点 labels: service: m2lorder-inference # 如果Nginx限制了/metrics的访问你可能需要配置basic_auth或直接抓取本地端口 # - targets: [localhost:8001] # 如果指标运行在独立端口启动Prometheussudo systemctl daemon-reload sudo systemctl start prometheus sudo systemctl enable prometheus sudo systemctl status prometheus访问http://your_server_ip:9090应该能看到Prometheus的Web界面。在“Status - Targets”页面应该能看到prometheus和m2lorder-service两个job都是UP状态。4.3 安装与配置GrafanaPrometheus的界面比较原始我们用Grafana来创建漂亮的监控看板。# 安装Grafana的APT仓库密钥和仓库 sudo apt-get install -y software-properties-common sudo add-apt-repository deb https://packages.grafana.com/oss/deb stable main wget -q -O - https://packages.grafana.com/gpg.key | sudo apt-key add - # 安装Grafana sudo apt-get update sudo apt-get install -y grafana # 启动并启用Grafana服务 sudo systemctl start grafana-server sudo systemctl enable grafana-server访问http://your_server_ip:3000默认用户名和密码都是admin首次登录会要求修改密码。添加数据源登录后点击左侧齿轮图标“Configuration” - “Data Sources”。点击“Add data source”选择“Prometheus”。URL填写http://localhost:9090因为Grafana和Prometheus装在同一台机器。点击“Save Test”应该显示“Data source is working”。导入监控仪表板Grafana社区有大量现成的仪表板。我们可以找一个适合监控Web服务的。点击左侧“”号 - “Import”。在“Import via grafana.com”输入框中输入仪表板ID11074这是一个流行的“Node Exporter Full”仪表板但我们需要监控的是应用服务。实际上对于自定义的FastAPI服务我们可能需要自己创建。更实用的方法是自己创建。点击“Create” - “Dashboard” - “Add new panel”。创建关键监控面板对于模型服务我们最关心请求速率和延迟在Grafana中新建Panel查询语句用rate(http_request_duration_seconds_count[5m])看请求率histogram_quantile(0.95, rate(http_request_duration_seconds_bucket[5m]))看P95延迟。错误率rate(http_request_duration_seconds_count{status~5..}[5m]) / rate(http_request_duration_seconds_count[5m])。进程内存和CPU这需要安装node_exporter来暴露系统指标然后添加到Prometheus抓取配置中。自定义业务指标比如model_inference_duration_seconds模型推理耗时这需要你在代码中手动记录并暴露。自己搭建看板虽然需要一些学习成本但它能让你完全定制化监控你最关心的指标非常值得。5. 总结走完这一整套流程你的M2LOrder模型服务已经不再是实验室里的玩具而是一个具备生产级韧性的在线服务了。Systemd确保了服务的高可用性异常退出会自动重启Nginx提供了安全的访问入口、负载均衡潜力以及静态文件服务能力Prometheus和Grafana组成的监控栈则给了你一双“眼睛”让你能实时掌握服务的健康状态、性能瓶颈和错误趋势。这套组合拳下来你晚上应该能睡个安稳觉了。当然生产环境运维是个持续的过程接下来你还可以考虑加入日志集中管理如ELK Stack、设置告警Prometheus Alertmanager、实现蓝绿部署等更高级的策略。但有了今天打下的这个坚实基础后续的扩展都会顺畅很多。建议你先让这套系统稳定跑上一段时间熟悉各个组件的日志和指标含义之后再根据实际遇到的新问题去迭代和优化你的部署架构。获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。

更多文章