站点图标 高效码农

从无到有构建高可用AI系统:7步实现多容器Docker Compose部署与实时监控

构建高可用多容器AI系统:从Docker Compose到监控与可视化完整实践

Snippet/摘要

本文详细讲解如何使用Docker Compose构建多容器AI系统,包括核心服务、监控Prometheus、日志收集Fluentd、可视化Grafana及Streamlit前端,并提供完整配置示例与故障排查方法。


目录

  1. 系统概览与设计目标

  2. Docker Compose整体架构

  3. 核心服务部署

  4. 监控与可视化

  5. 日志收集系统Fluentd

  6. 前端展示与Streamlit服务

  7. Nginx反向代理配置

  8. 常见问题排查

  9. FAQ


系统概览与设计目标

本系统基于多代理架构(Multi-Agent System),支持企业级AI任务处理与分析。核心目标包括:

  • 多容器隔离部署:各服务通过独立容器运行,保证资源隔离和可扩展性。
  • 高可用性与自恢复:通过Docker Compose restart: unless-stopped策略和健康检查,实现自动重启和容器健康监控。
  • 集中监控和可视化:使用Prometheus抓取指标,Grafana提供实时可视化,支持性能分析和告警。
  • 日志集中化管理:Fluentd收集各服务日志,统一存储与分析。
  • Web交互界面:通过Streamlit提供用户友好的交互前端,并通过Nginx反向代理统一访问。

Docker Compose整体架构

系统使用Docker Compose version: '3.8'进行服务编排,主要组成如下:

服务名称 镜像/构建 端口映射 功能
multi-agent-system 本地Dockerfile 8000(API)、8501(Streamlit原本暴露) 核心AI业务逻辑
redis redis:7-alpine 6379 缓存与消息队列
postgres postgres:15-alpine 5432 数据存储与管理
prometheus prom/prometheus:latest 9090 监控数据抓取
grafana grafana/grafana:latest 3000 指标可视化与仪表盘
nginx nginx:alpine 80/443 统一HTTP/HTTPS访问与反向代理
fluentd fluent/fluentd:v1.16-debian-1 24224 日志收集
streamlit 本地Dockerfile 8501 用户交互界面(Web UI)
jupyter 本地Dockerfile.jupyter 8888 开发与调试环境(可选,dev profile)

网络通过 multi-agent-network 桥接,确保各容器可通过服务名称互相访问,IP段配置为 172.20.0.0/16


核心服务部署

Multi-Agent System

功能概述

  • 启动多代理系统,初始化核心代理(Research Agent、Analysis Agent)
  • 客服系统初始化(Tech Support、Billing Support、General Support)
  • 消息总线(Message Bus)实现内部消息通信,支持3个工作线程
  • 支持Workflow Engine和性能监控

Docker Compose配置

multi-agent-system:
  build:
    context: .
    dockerfile: Dockerfile
  container_name: multi-agent-system
  ports:
    - "8000:8000"
  environment:
    - PYTHONPATH=/app
    - REDIS_HOST=redis
    - POSTGRES_HOST=postgres
    - LANGSMITH_API_KEY=${LANGSMITH_API_KEY:-}
  volumes:
    - ./logs:/app/logs
    - ./data:/app/data
  depends_on:
    - redis
    - postgres
  networks:
    - multi-agent-network
  restart: unless-stopped
  healthcheck:
    test: ["CMD", "python", "-c", "import requests; requests.get('http://localhost:8000/metrics')"]
    interval: 30s
    timeout: 10s
    retries: 3
    start_period: 40s

经验总结

  • 健康检查应使用实际可访问的HTTP端点 /metrics,而非不存在的 /health
  • /metrics端口必须在Python中使用 start_http_server(8000) 明确启动,保证Prometheus可抓取。

Redis缓存

  • 镜像:redis:7-alpine
  • 端口映射:6379:6379
  • 数据卷:redis_data
  • 健康检查:redis-cli ping

经验提示:Prometheus不能直接抓取原生Redis端口,需要额外部署 redis-exporter 服务。


PostgreSQL数据库

  • 镜像:postgres:15-alpine
  • 数据卷挂载初始化SQL:./scripts/init_db.sql
  • 环境变量配置:数据库名、用户名、密码
  • 健康检查:pg_isready -U postgres

Prometheus抓取PostgreSQL指标同样需要 postgres-exporter,不能直接抓5432端口。


监控与可视化

Prometheus配置

monitoring/prometheus.yml 示例:

global:
  scrape_interval: 15s
  evaluation_interval: 15s

scrape_configs:
  - job_name: "multi-agent-system"
    static_configs:
      - targets: ["multi-agent-system:8000"]

  - job_name: "redis"
    static_configs:
      - targets: ["multi-agent-redis:9121"]

  - job_name: "postgres"
    static_configs:
      - targets: ["multi-agent-postgres:9187"]

  - job_name: "grafana"
    metrics_path: /metrics
    static_configs:
      - targets: ["multi-agent-grafana:3000"]

核心经验

  1. 原有端口8501未运行Streamlit时应禁用抓取。
  2. Redis、Postgres必须抓HTTP暴露端点(Exporter),否则Prometheus报EOF。
  3. Grafana默认不暴露指标,需要启用 GF_METRICS_ENABLED=true

Grafana配置

  • 默认管理员密码设置为 admin
  • 仪表盘存放路径:./monitoring/grafana/dashboards
  • 数据源配置路径:./monitoring/grafana/datasources
  • 网络:multi-agent-network
  • 依赖:Prometheus服务

经验提示:保证Grafana抓取Prometheus数据前,Prometheus job必须为UP状态。


日志收集系统Fluentd

fluentd.conf 配置:

<source>
  @type forward
  port 24224
  bind 0.0.0.0
</source>

<match **>
  @type file
  path /var/log/multi-agent
  append true
</match>
  • Fluentd收集所有容器日志
  • 容器挂载 /logs 到宿主机,方便统一分析
  • 端口:24224 TCP/UDP

前端展示与Streamlit服务

新增独立Streamlit服务,解决原主容器8501端口未监听问题:

streamlit:
  build:
    context: .
    dockerfile: Dockerfile.streamlit
  container_name: multi-agent-streamlit
  ports:
    - "8501:8501"
  volumes:
    - ./ui:/app
  networks:
    - multi-agent-network
  restart: unless-stopped

关键点

  1. Streamlit监听 0.0.0.0:8501,保证外部访问。
  2. Nginx反向代理 /streamlit/streamlit:8501,统一入口。
  3. 避免在主应用容器占用8501端口,减少冲突。

经验提示:在Windows上,检查端口占用:

netstat -ano | findstr :8501

Nginx反向代理配置

完整示例 nginx/nginx.conf

user  nginx;
worker_processes  auto;
error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}

http {
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    keepalive_timeout  65;

    upstream multi_agent_system {
        server multi-agent-system:8000;
    }

    upstream streamlit_app {
        server streamlit:8501;
    }

    server {
        listen 80;
        server_name localhost;

        location / {
            proxy_pass http://multi_agent_system;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
        }

        location /streamlit/ {
            proxy_pass http://streamlit_app/;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
        }
    }
}

注意

  • unknown log format "main" 错误是因为 log_format 配置缺失或写法错误,已修正。
  • /streamlit/ 代理单独Streamlit容器,避免空响应。

常见问题排查

  1. 空响应 ERR_EMPTY_RESPONSE

    • 检查容器是否真正监听端口
    • 检查Nginx upstream配置是否正确
    • 检查容器网络互通:
    docker exec -it multi-agent-nginx sh -c "apk add curl; curl -sI http://streamlit:8501"
    

    返回200/302表示网络可达。

  2. Prometheus抓取失败

    • 原因:抓取端口非HTTP或未启动
    • 解决:使用Exporter(Redis、Postgres),确保 /metrics可访问
  3. Streamlit未运行

    • 确认服务已启动:
    docker compose ps
    docker logs --tail=50 multi-agent-streamlit
    
    • 确认端口8501映射正确,监听地址为 0.0.0.0

FAQ

Q1: 为什么访问 localhost:8501 返回空白?
A1: 原主应用未监听8501端口,需通过独立Streamlit服务监听,并确保Nginx代理正确。

Q2: Redis和Postgres指标为何Prometheus抓不到?
A2: 原端口不是HTTP服务,Prometheus必须抓HTTP Exporter(Redis Exporter 9121、Postgres Exporter 9187)。

Q3: Nginx日志报 unknown log format "main"
A3: 因log_format定义缺失或格式错误,已在 nginx.conf修复。

Q4: 如何验证Multi-Agent System健康?
A4: 使用 /metrics端点:

curl http://localhost:8000/metrics

返回Prometheus文本格式即健康。


总结与经验要点

  1. 服务隔离:每个容器功能单一,避免端口冲突和依赖耦合。
  2. 端口健康检查:Prometheus抓取端口必须监听HTTP服务。
  3. 日志统一管理:Fluentd收集所有服务日志,方便长期审计和监控。
  4. 前端与反向代理:Streamlit独立服务 + Nginx代理,统一访问入口。
  5. 容器网络配置:使用桥接网络,确保服务名解析正常。
  6. 重建镜像和缓存清理:出现端口或依赖错误时,执行
docker compose build --no-cache
docker compose up -d

通过以上部署和配置,系统可实现:

  • 可靠的多代理AI服务运行
  • Prometheus统一监控核心指标
  • Grafana仪表盘实时可视化
  • Streamlit前端页面稳定访问
  • Fluentd集中日志收集与分析

该方案经过实际运行验证,确保容器间通信、端口暴露、监控抓取和Web访问均可正常运作。

退出移动版