03-N8N教程-基于Docker与PostgreSQL的N8N高可用部署指南:从零搭建到性能优化

📅 发布时间:2026/7/11 3:39:47 👁️ 浏览次数:
03-N8N教程-基于Docker与PostgreSQL的N8N高可用部署指南:从零搭建到性能优化
1. 为什么你需要一个高可用的N8N如果你已经跟着之前的教程用Docker和PostgreSQL把N8N跑起来了可能会觉得万事大吉。我刚开始也是这么想的直到有一次服务器半夜宕机第二天发现所有半夜该跑的自动化工作流——比如定时爬取数据、给客户发提醒邮件——全都停了。更糟的是因为当时数据只存在容器里重启后一些临时的凭证和流程状态也丢了花了好几个小时才恢复。那次教训让我明白个人玩玩和生产环境部署完全是两码事。所谓“高可用”听起来高大上其实核心目标就一个让你的自动化工作流7x24小时稳定运行出点小毛病也能自动恢复别耽误事。想象一下你搭建了一个自动处理电商订单、同步库存到ERP、然后给仓库发通知的复杂工作流。如果负责这个“数字员工”的服务器挂了你的线上业务可能就卡壳了。高可用部署就是为了避免这种单点故障。用Docker和PostgreSQL来搭建是目前最主流也最推荐的方式。Docker负责把N8N本身“打包”让它能在任何地方以相同的方式运行隔离性好部署也快。而PostgreSQL作为数据持久化的后端则确保了你的工作流配置、执行历史、用户凭证这些宝贵资产不会因为容器重启或删除而消失。这两者结合就构成了一个稳定基石。但仅仅能运行还不够。生产环境意味着要面对突发流量、计划内的维护比如给服务器打补丁、甚至硬件故障。所以我们得在这个基石上搭建更稳固的房子。这包括用Docker Compose来编排多个服务让它们能协同工作配置数据库连接池防止海量工作流并发时把数据库拖垮设置负载均衡让多个N8N实例一起干活一个累了另一个顶上最后还得有监控眼睛时刻盯着系统的健康状态。接下来我就带你从零开始一步步搭建这套能扛事的N8N生产环境。2. 搭建基础Docker与PostgreSQL环境准备工欲善其事必先利其器。在开始编排复杂的服务之前我们得先把地基打牢。这里假设你有一台干净的Linux服务器比如Ubuntu 22.04我们从零开始。2.1 安装Docker与Docker Compose现在安装Docker已经非常简单了。我习惯用官方的一键安装脚本比较省心。你登录服务器后直接执行下面这行命令curl -fsSL https://get.docker.com -o get-docker.sh sudo sh get-docker.sh安装完成后把当前用户加入到docker组这样以后就不用每次都敲sudo了sudo usermod -aG docker $USER # 记得退出当前终端重新登录或者执行 newgrp docker 让组生效接下来安装Docker Compose。虽然Docker现在有compose-plugin但我还是喜欢独立的docker-compose命令兼容性好。我们去Github下载最新的稳定版sudo curl -L https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose sudo chmod x /usr/local/bin/docker-compose # 验证安装 docker-compose --version看到版本号输出说明安装成功了。这里有个小坑我踩过如果你的服务器在国内下载Github资源可能会很慢甚至超时。这时候可以换个思路先在自己电脑上下载好再用scp命令传上去或者使用国内的镜像源。2.2 部署独立的PostgreSQL数据库虽然我们可以把数据库和N8N塞在同一个docker-compose.yml文件里但我强烈建议将数据库独立部署。原因很简单数据库是状态服务它的生命周期、备份策略、升级节奏都和N8N这样的应用服务不同。混在一起以后想单独升级或迁移数据库会很麻烦。我们创建一个专门的目录来管理数据库比如/opt/n8n-dbsudo mkdir -p /opt/n8n-db cd /opt/n8n-db然后创建docker-compose.db.yml文件version: 3.8 services: postgres: image: postgres:15-alpine # 使用Alpine版本更轻量 container_name: n8n-postgres restart: unless-stopped # 总是重启除非手动停止 environment: POSTGRES_USER: n8nuser # 建议不要用默认的postgres用户 POSTGRES_PASSWORD: YourStrongPassword123! # 一定要改成一个强密码 POSTGRES_DB: n8n POSTGRES_INITDB_ARGS: --encodingUTF8 --lc-collateC --lc-ctypeC volumes: - postgres_data:/var/lib/postgresql/data # 数据卷持久化 - ./init-scripts:/docker-entrypoint-initdb.d:ro # 可选初始化脚本目录 ports: - 5432:5432 networks: - n8n-network healthcheck: # 健康检查方便编排工具感知数据库状态 test: [CMD-SHELL, pg_isready -U n8nuser] interval: 10s timeout: 5s retries: 5 volumes: postgres_data: # 命名卷数据管理更方便 networks: n8n-network: driver: bridge我来解释几个关键点密码YourStrongPassword123!只是个例子你必须换成自己生成的、包含大小写字母、数字和特殊符号的复杂密码。生产环境安全无小事。数据卷postgres_data这个命名卷会把数据库文件持久化在Docker管理的位置即使容器删除数据也在。你也可以映射到主机特定路径如./data:/var/lib/postgresql/data。网络我们创建了一个自定义网络n8n-network后面N8N服务也会加入这个网络。这样服务间可以通过服务名如postgres直接通信更安全性能也更好。健康检查这个配置非常有用当以后我们编排多个服务时Docker Compose可以等数据库真正“就绪”后再启动N8N。现在启动数据库服务docker-compose -f docker-compose.db.yml up -d用docker logs n8n-postgres看看日志没有报错的话再用客户端连一下试试docker exec -it n8n-postgres psql -U n8nuser -d n8n能成功进入psql命令行说明数据库已经稳稳地跑起来了。按\q退出。3. 核心部署使用Docker Compose编排N8N基础打好主角该登场了。我们将使用Docker Compose来定义和运行N8N服务。Compose的好处是能把应用依赖的所有服务比如N8N本身、Redis缓存等写在一个配置文件里一键启动、统一管理。3.1 编写高可用N8N的Compose文件在服务器上我们为N8N创建一个新目录比如/opt/n8nsudo mkdir -p /opt/n8n cd /opt/n8n然后创建核心的docker-compose.yml文件。这个文件会稍微复杂一点因为它要体现“高可用”的初步思想——即使我们暂时只运行一个实例配置也要为扩展留好接口。version: 3.8 services: n8n: image: n8nio/n8n:latest container_name: n8n restart: unless-stopped ports: - 5678:5678 environment: # 数据库连接配置指向我们独立部署的数据库 DB_TYPE: postgresdb DB_POSTGRESDB_HOST: postgres # 使用服务名因为在一个网络里 DB_POSTGRESDB_PORT: 5432 DB_POSTGRESDB_DATABASE: n8n DB_POSTGRESDB_USER: n8nuser DB_POSTGRESDB_PASSWORD: YourStrongPassword123! # 与数据库配置一致 DB_POSTGRESDB_SSL: false # 内网通信通常不用SSL如需可启用 # 通用配置 N8N_PROTOCOL: http N8N_HOST: localhost N8N_PORT: 5678 N8N_DEFAULT_LOCALE: zh-CN WEBHOOK_URL: http://你的服务器公网IP或域名:5678/ # 重要用于Webhook回调 EXECUTIONS_DATA_PRUNE: true # 自动清理旧的执行数据 EXECUTIONS_DATA_MAX_AGE: 168 # 保留最近168小时7天的数据 # 性能与高可用相关配置 EXECUTIONS_MODE: queue # 使用队列模式处理工作流提升并发能力 QUEUE_BULL_REDIS_HOST: redis # 指向Redis服务下一步会加 GENERIC_TIMEZONE: Asia/Shanghai N8N_METRICS: true # 启用指标收集为监控做准备 volumes: - n8n_data:/home/node/.n8n # 持久化配置、密钥等 - ./local_files:/files # 可选挂载本地文件目录方便工作流读写文件 depends_on: postgres: condition: service_healthy # 等待数据库健康后再启动 networks: - n8n-network # 资源限制防止单个容器吃光资源 deploy: resources: limits: cpus: 1.0 memory: 2G reservations: cpus: 0.5 memory: 1G # 添加一个Redis服务用于队列和缓存 redis: image: redis:7-alpine container_name: n8n-redis restart: unless-stopped command: redis-server --appendonly yes # 开启持久化 volumes: - redis_data:/data networks: - n8n-network healthcheck: test: [CMD, redis-cli, ping] interval: 10s timeout: 5s retries: 5 # 引用外部数据库服务需要先启动 networks: n8n-network: external: true # 使用我们之前创建的网络 name: n8n-db_n8n-network # 注意网络名是目录名_网络名 volumes: n8n_data: redis_data:这个文件有几个关键升级连接数据库DB_POSTGRESDB_HOST写的是postgres这是我们在数据库Compose文件中定义的服务名。因为两个服务都加入了n8n-network所以可以直接通过名字访问。队列模式设置了EXECUTIONS_MODE: queue并连接Redis。这是N8N处理高并发的关键。默认的regular模式是同步执行工作流一个卡住后面都得等。queue模式会把工作流执行任务扔到Redis队列里由后台Worker异步处理吞吐量大大提升。数据清理生产环境运行久了execution表会巨大无比。EXECUTIONS_DATA_PRUNE和EXECUTIONS_DATA_MAX_AGE配置可以自动清理老旧数据避免数据库被撑爆。资源限制通过deploy.resources.limits给容器设了CPU和内存上限。这是个好习惯能防止某个服务失控拖垮整个主机。外部网络注意networks这里声明使用外部网络n8n-network。我们需要先确保这个网络存在。3.2 启动服务与初始化验证首先因为N8N的Compose文件依赖外部网络我们需要先确保数据库服务启动并创建了网络。进入数据库目录启动它cd /opt/n8n-db docker-compose -f docker-compose.db.yml up -d用docker network ls看看应该能看到一个名为n8n-db_n8n-network的网络名字是目录名_网络名。记住这个名字我们回到N8N目录修改Compose文件中的网络名确保一致。或者更简单的方法在数据库的Compose文件里把网络名显式声明为n8n-network# 在 /opt/n8n-db/docker-compose.db.yml 中 networks: n8n-network: name: n8n-network # 指定网络名避免自动生成带前缀的名字改完后重启数据库服务docker-compose -f docker-compose.db.yml down docker-compose -f docker-compose.db.yml up -d。现在进入N8N目录启动服务cd /opt/n8n docker-compose up -d用docker-compose logs -f n8n查看启动日志。当你看到类似“N8N started on port 5678”的日志时就说明启动成功了。打开浏览器访问http://你的服务器IP:5678应该能看到N8N的登录界面。第一次使用需要创建管理员账户之后就可以正常使用了。注意这里有一个非常重要的点WEBHOOK_URL环境变量。很多人在配置Webhook触发器比如GitHub仓库推送、表单提交时发现N8N收不到外部通知八成是这个没设对。它必须是你外部能访问到的N8N地址。如果你有域名最好配成https://你的域名/。4. 向高可用演进负载均衡与水平扩展单个N8N实例能承受的负载是有限的。当你的工作流数量成百上千或者有大量并发触发时单个实例可能成为瓶颈。高可用的核心思想就是别把鸡蛋放在一个篮子里。我们通过运行多个N8N实例并在前面加一个负载均衡器来分散压力和避免单点故障。4.1 配置Nginx作为反向代理与负载均衡器我们不直接暴露N8N的5678端口而是在前面用Nginx做一层反向代理。这样做有几个好处1) 可以配置SSL证书实现HTTPS2) 可以做负载均衡3) 可以统一管理访问日志和安全策略。首先在N8N的目录下创建一个nginx子目录和配置文件mkdir -p nginx/conf.d cd 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 { include /etc/nginx/mime.types; default_type application/octet-stream; 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; # 上游N8N服务器组 upstream n8n_backend { # 这里配置多个N8N实例目前我们先写一个后面扩展 server n8n:5678; # 可以添加更多如 server n8n2:5678; server n8n3:5678; # 负载均衡策略默认是轮询(round-robin) least_conn; # 改为最少连接数更均衡 } # 包含具体的站点配置 include /etc/nginx/conf.d/*.conf; }然后创建站点配置conf.d/n8n.confserver { listen 80; server_name 你的域名或服务器IP; # 例如 n8n.yourcompany.com # 重定向所有HTTP流量到HTTPS如果你配置了SSL # return 301 https://$server_name$request_uri; location / { proxy_pass http://n8n_backend; 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_set_header Upgrade $http_upgrade; proxy_set_header Connection upgrade; # 支持WebSocketN8N编辑器需要 proxy_read_timeout 300s; # 长工作流可能需要更长时间 proxy_send_timeout 300s; client_max_body_size 50M; # 允许上传较大文件 } # 健康检查端点 location /healthz { proxy_pass http://n8n_backend/healthz; access_log off; } }4.2 修改Compose文件以支持多实例现在我们更新/opt/n8n/docker-compose.yml把Nginx加进去并修改N8N服务定义使其支持水平扩展。首先去掉N8N服务的ports映射因为我们不再直接暴露它。然后给它添加一个scale标签或者用deploy.replicas取决于你的Compose版本。同时把Nginx服务加进来。更新后的docker-compose.yml部分如下version: 3.8 services: n8n: image: n8nio/n8n:latest # 移除 container_name因为多个实例不能同名 restart: unless-stopped environment: # ... 环境变量保持不变但注意WEBHOOK_URL要指向负载均衡器地址 WEBHOOK_URL: http://你的域名或IP/ # 现在指向Nginx N8N_HOST: n8n # 内部通信可以用服务名 N8N_PORT: 5678 volumes: - n8n_data:/home/node/.n8n networks: - n8n-network # 关键使用deploy模式指定副本数或者用 scale 命令 deploy: replicas: 2 # 启动2个N8N实例 resources: limits: cpus: 1.0 memory: 2G # 健康检查让负载均衡器知道实例是否健康 healthcheck: test: [CMD, curl, -f, http://localhost:5678/healthz] interval: 30s timeout: 10s retries: 3 start_period: 40s nginx: image: nginx:alpine container_name: n8n-nginx restart: unless-stopped ports: - 80:80 - 443:443 # 为HTTPS预留 volumes: - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro - ./nginx/conf.d:/etc/nginx/conf.d:ro - ./ssl_certs:/etc/nginx/ssl:ro # 存放SSL证书的目录 depends_on: - n8n networks: - n8n-network redis: # ... redis配置保持不变 # ... 网络和卷配置保持不变这里最重要的变化是deploy.replicas: 2它告诉Docker Compose启动两个N8N容器实例。同时我们为N8N服务添加了healthcheckNginx或其他负载均衡器可以根据这个检查来剔除不健康的实例。现在更新Nginx的上游配置upstream n8n_backend让它指向这两个实例。由于我们使用了Docker Compose的服务名并且启动了多个副本Docker内置的DNS会提供负载均衡。但更常见的做法是让Nginx直接做负载均衡。修改nginx/conf.d/n8n.conf中的upstream块upstream n8n_backend { # 使用Docker Compose的服务名和内部端口 # Docker Compose的服务发现会自动解析到多个容器IP server n8n:5678 max_fails3 fail_timeout30s; # 理论上写一个入口Docker网络会做负载均衡。 # 但为了更精确的控制我们可以用动态DNS解析或直接指定IP不推荐。 # 另一种方案在Compose中为每个实例指定独立的主机名但这更复杂。 }实际上在Docker Swarm或Kubernetes中服务发现和负载均衡更成熟。在单机Docker Compose环境下实现完美的多实例负载均衡有点“杀鸡用牛刀”。一个更简单实用的生产级方案是使用traefik或haproxy作为负载均衡器它们对Docker集成的更好。或者如果你用的是云服务直接使用云负载均衡器如AWS ALB、GCP Load Balancer是更省心的选择。考虑到教程的实用性和复杂度我建议在单机环境下可以先用一个N8N实例配合队列模式这已经能处理相当高的并发。当你真的需要横向扩展时再考虑引入更专业的服务网格或编排工具。5. 数据库优化与监控让系统更健壮部署好了能跑了接下来我们要让它跑得更快、更稳。数据库往往是性能瓶颈所在而监控则是我们的“眼睛”。5.1 PostgreSQL连接池与性能调优N8N每个工作流执行、每个Webhook请求都可能产生数据库查询。默认情况下每个N8N实例会直接创建一些数据库连接。当实例增多、并发量变大时可能会把数据库连接数耗尽出现“抱歉已经有太多客户端”的错误。使用PgBouncer连接池这是PostgreSQL生态中解决连接数问题的标准答案。它是一个轻量级的连接池中间件应用连接到PgBouncerPgBouncer再管理到PostgreSQL的实际连接可以复用连接极大减少数据库的压力。我们可以在数据库那台服务器上或者单独一台用Docker快速部署一个PgBouncer。创建一个docker-compose.pgbouncer.ymlversion: 3.8 services: pgbouncer: image: edoburu/pgbouncer:latest container_name: pgbouncer-for-n8n restart: unless-stopped environment: DATABASE_URL: postgres://n8nuser:YourStrongPassword123!postgres:5432/n8n # PgBouncer 配置 POOL_MODE: transaction # 事务模式最常用 MAX_CLIENT_CONN: 1000 # 允许的最大客户端连接数 DEFAULT_POOL_SIZE: 20 # 每个数据库的默认连接池大小 RESERVE_POOL_SIZE: 5 # 保留连接池大小 ports: - 6432:6432 # PgBouncer默认端口 networks: - n8n-network depends_on: - postgres然后修改N8N的环境变量把数据库主机和端口指向PgBouncerenvironment: DB_TYPE: postgresdb DB_POSTGRESDB_HOST: pgbouncer # 改为PgBouncer的服务名或IP DB_POSTGRESDB_PORT: 6432 # PgBouncer的端口 # ... 其他配置不变PostgreSQL自身调优对于postgresql.conf即使你不精通调整几个关键参数也能带来立竿见影的效果。通过docker exec -it n8n-postgres bash进入容器编辑/var/lib/postgresql/data/postgresql.conf或者修改你挂载的配置文件。重点看shared_buffers设置为系统内存的25%。如果你的服务器有8G内存可以设2GB。effective_cache_size设置为系统内存的50%-75%例如4GB。work_mem处理排序和哈希的内存可以设16MB或32MB根据并发调整。maintenance_work_mem维护操作如VACUUM的内存设大点如256MB。max_connections最大连接数结合PgBouncer可以设得比应用总连接数大一些比如200。修改后需要重启PostgreSQL容器生效。5.2 搭建基础监控Prometheus Grafana看不见的系统是危险的。我们需要知道N8N和数据库的运行状态CPU内存使用率、请求延迟、错误率、队列长度等等。1. 启用N8N指标暴露我们在环境变量里已经设置了N8N_METRICS: true。这会让N8N在/metrics端点暴露Prometheus格式的指标。你可以访问http://你的N8N地址:5678/metrics看看会有一大堆数据。2. 部署Prometheus在/opt/n8n目录下创建prometheus.yml配置文件global: scrape_interval: 15s evaluation_interval: 15s scrape_configs: - job_name: n8n static_configs: - targets: [n8n:5678] # 监控N8N如果有多个实例都列出来 labels: group: n8n-app - job_name: postgres static_configs: - targets: [postgres-exporter:9187] # 需要Postgres Exporter # 如果你也监控Redis和Node Exporter监控主机也可以加在这里然后在docker-compose.yml中添加Prometheus和Grafana服务services: # ... 已有的 n8n, nginx, redis 服务 prometheus: image: prom/prometheus:latest container_name: n8n-prometheus restart: unless-stopped volumes: - ./prometheus.yml:/etc/prometheus/prometheus.yml:ro - prometheus_data:/prometheus command: - --config.file/etc/prometheus/prometheus.yml - --storage.tsdb.path/prometheus - --web.console.libraries/etc/prometheus/console_libraries - --web.console.templates/etc/prometheus/consoles - --storage.tsdb.retention.time30d ports: - 9090:9090 networks: - n8n-network grafana: image: grafana/grafana-oss:latest container_name: n8n-grafana restart: unless-stopped environment: - GF_SECURITY_ADMIN_PASSWORDadmin123 # 首次登录密码务必修改 volumes: - grafana_data:/var/lib/grafana - ./grafana/provisioning:/etc/grafana/provisioning # 预配置仪表盘和数据源 ports: - 3000:3000 networks: - n8n-network volumes: # ... 已有的卷 prometheus_data: grafana_data:3. 配置与查看启动所有服务后访问http://你的服务器IP:3000登录Grafana默认用户admin密码是你设置的。添加数据源选择PrometheusURL填http://prometheus:9090。然后就可以导入或创建仪表盘了。你可以在Grafana官网找到现成的Node.js应用或PostgreSQL监控仪表盘模板导入后稍作修改就能看到一个漂亮的监控面板实时显示你的N8N系统状态。监控不仅能帮你发现问题还能在做性能优化时提供数据支撑。比如你调整了PostgreSQL参数后可以观察grafana上数据库的缓存命中率、连接数是否有改善。6. 备份、恢复与日常维护指南系统跑起来只是开始如何让它长期稳定运行不出乱子出了乱子能快速恢复这才是运维的真功夫。6.1 数据备份策略你的核心资产就两块PostgreSQL数据库和N8N的配置卷里面存了加密的凭证、静态数据等。数据库备份最简单有效的方法就是用pg_dump定时备份。写一个脚本/opt/n8n-db/backup.sh#!/bin/bash BACKUP_DIR/opt/n8n-db/backups DATE$(date %Y%m%d_%H%M%S) DOCKER_CONTAINERn8n-postgres # 创建备份目录 mkdir -p $BACKUP_DIR # 执行备份 docker exec $DOCKER_CONTAINER pg_dump -U n8nuser -d n8n -F c -b -v -f /tmp/backup_$DATE.dump # 将备份文件从容器复制到主机 docker cp $DOCKER_CONTAINER:/tmp/backup_$DATE.dump $BACKUP_DIR/ # 清理容器内的临时文件 docker exec $DOCKER_CONTAINER rm /tmp/backup_$DATE.dump # 可选删除7天前的旧备份 find $BACKUP_DIR -name *.dump -mtime 7 -delete echo Backup completed: $BACKUP_DIR/backup_$DATE.dump给脚本加执行权限chmod x backup.sh然后加到crontab里每天凌晨3点执行0 3 * * * /opt/n8n-db/backup.sh /var/log/n8n-backup.log 21。N8N卷备份N8N的Docker卷n8n_data包含了用户配置、静态文件等。备份它就是备份整个卷目录。你可以用docker run命令临时启动一个容器来打包# 找出卷在主机上的实际路径 docker volume inspect n8n_n8n_data --format {{ .Mountpoint }} # 假设路径是 /var/lib/docker/volumes/n8n_n8n_data/_data # 然后直接用tar备份这个目录 tar -czf /opt/backups/n8n_data_$(date %Y%m%d).tar.gz -C /var/lib/docker/volumes/n8n_n8n_data/_data .同样把这条命令加到定时任务里。6.2 版本升级与回滚N8N更新比较频繁修复Bug和增加新功能。升级需要谨慎。1. 升级前必做备份数据库和N8N卷这是你的安全绳。2. 升级步骤修改docker-compose.yml中N8N的镜像标签比如从latest改为具体的版本号n8nio/n8n:1.40.0建议用固定版本避免latest的不确定性。然后执行cd /opt/n8n docker-compose pull n8n # 拉取新镜像 docker-compose up -d n8n # 重启服务会使用新镜像创建容器3. 观察与回滚升级后密切监控日志docker-compose logs -f n8n和Grafana仪表盘。如果发现工作流报错、功能异常需要立即回滚。回滚很简单把镜像标签改回旧版本再执行docker-compose up -d n8n即可。因为你的数据和配置都在独立的卷里所以应用版本切换是很快的。6.3 日常健康检查清单养成每天花几分钟看一眼的习惯能避免很多小问题酿成大祸日志docker-compose logs --tail 50 n8n看看有没有持续的错误或警告。容器状态docker-compose ps确保所有容器都是Up状态。资源使用docker stats或看GrafanaCPU、内存是否在正常范围。队列积压如果用了Redis队列可以连上Redis看看bull:n8n:queue相关的key数量积压太多说明处理不过来可能需要增加Worker或优化工作流。数据库连接数在Grafana或连上数据库执行SELECT count(*) FROM pg_stat_activity;确保连接数没有持续高位。这套从单实例到具备高可用雏形的部署方案我是在多个内部自动化平台和客户项目上实践总结出来的。一开始可能会觉得步骤繁琐但一旦搭建完成它带来的稳定性和可维护性提升是巨大的。尤其是当你的业务越来越依赖这些自动化工作流时你会庆幸当初在架构上多花了这点时间。记住好的运维不是等出了问题再去救火而是让问题根本没有机会发生。