# 监控页面数据缺失排查
# 1、容器化部署,ESB Server集群环境下资源监控仅显示一台服务器
# 问题现象
在容器化部署的ESB Server集群环境中,存在以下异常现象:
环境配置:
- 使用相同镜像
192.168.16.18/esb-pro/ipassesbserver:9.1.0部署了两台ESB Server - 通过docker run命令分别启动两个容器实例
- iPaaS Portal(Governor)地址为
http://esbGovernor:9099/
- 使用相同镜像
具体表现:
- 两台ESB Server容器均成功启动,无异常报错
- 但登录iPaaS Portal监控界面后,仅显示一台服务器的资源信息(CPU、内存、磁盘等)
- 另一台服务器在监控界面中不可见,无法进行监控和管理
# 问题分析
# 启动命令分析
两台服务器启动命令:
docker run -d --name esbServer \
-e DB_TYPE=mysql \
-e DB_URL=jdbc:mysql://192.168.xx.xx:3306/esb910 \
-e DB_USER=root \
-e DB_PASSWD=********* \
-e ES_HOST=192.168.xx.48 \
-e ES_PORT=9200 \
-e ES_NAME=elastic \
-e ES_PW=******** \
-e ES_CER=/opt/server/http_ca.crt \
-e NOTIFICATION_PATH=http://esbGovernor:9099/ \
-e ESB_SERVER_ID=esbServer1 \
-p 6200:6200 -p 10001:10001 -p 10002:10002 -p 10003:10003 -p 10004:10004 -p 10005:10005 \
192.168.XX.18/esb-pro/ipassesbserver:9.1.0
# 关键参数说明
在ESB Server的容器化部署中,以下两个环境参数对集群监控起决定性作用:
| 参数 | 说明 | 重要性 | 配置要求 |
|---|---|---|---|
NOTIFICATION_PATH | ESB Server与iPaaS Portal的通信地址,用于服务器注册和心跳维护 | ⚠️ 高 | 必须正确指向Portal的实际访问地址,否则服务器无法注册 |
ESB_SERVER_ID | ESB Server的唯一标识,用于在Portal中区分不同的服务器实例 | 🔴 核心 | 必须唯一,且与Portal中添加的服务器名称完全一致 |
# 参数详解
NOTIFICATION_PATH
- 作用:建立ESB Server与iPaaS Portal之间的通信通道
- 工作机制:Server启动后通过该地址向Portal注册,并定期发送心跳
- 错误影响:配置错误将导致服务器无法被Portal发现和管理
- 示例:
http://esbGovernor:9099/
ESB_SERVER_ID
- 作用:作为服务器的唯一身份标识
- 工作机制:Portal通过该ID识别、区分和监控不同的Server实例
- 错误影响:ID重复会导致实例被覆盖,监控数据丢失
- 示例:
ESBServer1、ESBServer2、PROD-ESB-01
# 根本原因分析
# 核心问题定位
经过深入排查,确定问题的根本原因为:两台ESB Server实例使用了完全相同的ESB_SERVER_ID环境变量值。
# 解决方案
# 方案概述
# 核心设计原则
本方案遵循容器化部署的最佳实践,通过以下核心原则解决问题:
| 原则 | 说明 | 实现方式 |
|---|---|---|
| 镜像统一 | 所有实例使用同一个镜像,避免镜像碎片化 | 使用 192.168.xx.18/esb-pro/ipassesbserver:9.1.0 |
| 标识唯一 | 通过环境变量为每个实例分配唯一标识 | 设置不同的 ESB_SERVER_ID 值 |
| 配置一致 | 确保环境变量与Portal配置完全匹配 | ESB_SERVER_ID 与Portal服务器名称一致 |
| 资源隔离 | 合理规划端口映射,避免资源冲突 | 每个实例使用独立的主机端口 |
# 手动部署方案
适用场景:测试环境、快速验证、临时部署
# 前置准备
# 1. 创建自定义网络(如未创建)
docker network create esb-network
# 2. 确认镜像存在
docker image inspect 192.168.16.18/esb-pro/ipassesbserver:9.1.0 || \
docker pull 192.168.16.18/esb-pro/ipassesbserver:9.1.0
# 启动第一个实例(ESBServer1)
docker run -d \
--name esbServer1 \
--hostname esbServer1 \
-e DB_TYPE=mysql \
-e DB_URL=jdbc:mysql://192.168.xx.xx:3306/esb910 \
-e DB_USER=root \
-e DB_PASSWD=****** \
-e ES_HOST=192.168.xx.48 \
-e ES_PORT=9200 \
-e ES_NAME=elastic \
-e ES_PW=******* \
-e ES_CER=/opt/server/http_ca.crt \
-e NOTIFICATION_PATH=http://esbGovernor:9099/ \
-e ESB_SERVER_ID=ESBServer1 \ # ⚠️ 必须唯一
-p 6201:6200 \
-p 10011:10001 \
-p 10012:10002 \
-p 10013:10003 \
-p 10014:10004 \
-p 10015:10005 \
--restart unless-stopped \
--network esb-network \
--log-opt max-size=10m \
--log-opt max-file=3 \
192.168.xx.18/esb-pro/ipassesbserver:9.1.0
# 启动第二个实例(ESBServer2)
docker run -d \
--name esbServer2 \
--hostname esbServer2 \
-e DB_TYPE=mysql \
-e DB_URL=jdbc:mysql://192.168.xx.xx:3306/esb910 \
-e DB_USER=root \
-e DB_PASSWD= ******* \
-e ES_HOST=192.168.xx.48 \
-e ES_PORT=9200 \
-e ES_NAME=elastic \
-e ES_PW= ****** \
-e ES_CER=/opt/server/http_ca.crt \
-e NOTIFICATION_PATH=http://esbGovernor:9099/ \
-e ESB_SERVER_ID=ESBServer2 \ # ⚠️ 必须唯一
-p 6202:6200 \
-p 10021:10001 \
-p 10022:10002 \
-p 10023:10003 \
-p 10024:10004 \
-p 10025:10005 \
--restart unless-stopped \
--network esb-network \
--log-opt max-size=10m \
--log-opt max-file=3 \
192.168.xx.18/esb-pro/ipassesbserver:9.1.0
# 标准化部署方案(推荐)
适用场景:生产环境、长期运维、集群管理
方案优势:配置即代码、版本可控、一键部署、易于扩展
# 创建Docker Compose配置文件
创建 docker-compose-esb-cluster.yml 文件,内容如下:
version: '3.8'
# 自定义网络配置
networks:
esb-network:
name: esb-network # 指定网络名称
driver: bridge # 使用bridge驱动
ipam:
config:
- subnet: 172.20.0.0/16 # 指定子网范围,避免IP冲突
- gateway: 172.20.0.1
services:
# ============================================
# ESB Server 实例1
# ============================================
esb-server1:
image: 192.168.xx.18/esb-pro/ipassesbserver:9.1.0
container_name: esbServer1 # 容器名称
hostname: esbServer1 # 容器主机名
environment:
# ---------- 数据库连接配置 ----------
DB_TYPE: mysql
DB_URL: jdbc:mysql://192.168.xx.xx:3306/esb910
DB_USER: root
DB_PASSWD: *******
# ---------- Elasticsearch 配置 ----------
ES_HOST: 192.168.xx.xx
ES_PORT: 9200
ES_NAME: elastic
ES_PW: *******
ES_CER: /opt/server/http_ca.crt # ES证书路径
# ---------- ESB Server 核心配置 ----------
NOTIFICATION_PATH: http://esbGovernor:9099/ # Portal地址
ESB_SERVER_ID: ESBServer1 # ⚠️ 唯一标识(必须与Portal一致)
ports:
# 主机端口:容器端口(使用不同主机端口避免冲突)
- "6201:6200" # 主服务端口
- "10011:10001" # 辅助端口1
- "10012:10002" # 辅助端口2
- "10013:10003" # 辅助端口3
- "10014:10004" # 辅助端口4
- "10015:10005" # 辅助端口5
networks:
esb-network:
ipv4_address: 172.20.0.10 # 固定IP,便于管理
restart: unless-stopped # 容器退出时自动重启
logging: # 日志配置
driver: "json-file"
options:
max-size: "10m" # 单个日志文件最大大小
max-file: "3" # 保留的日志文件个数
# ============================================
# ESB Server 实例2
# ============================================
esb-server2:
image: 192.168.xx.18/esb-pro/ipassesbserver:9.1.0
container_name: esbServer2
hostname: esbServer2
environment:
# ---------- 数据库连接配置(与实例1相同)----------
DB_TYPE: mysql
DB_URL: jdbc:mysql://192.168.xx.xx:3306/esb910
DB_USER: root
DB_PASSWD: ******
# ---------- Elasticsearch 配置 ----------
ES_HOST: 192.168.xx.48
ES_PORT: 9200
ES_NAME: elastic
ES_PW: *******
ES_CER: /opt/server/http_ca.crt
# ---------- ESB Server 核心配置 ----------
NOTIFICATION_PATH: http://esbGovernor:9099/
ESB_SERVER_ID: ESBServer2 # ⚠️ 唯一标识(与实例1不同)
ports:
- "6202:6200"
- "10021:10001"
- "10022:10002"
- "10023:10003"
- "10024:10004"
- "10025:10005"
networks:
esb-network:
ipv4_address: 172.20.0.11
restart: unless-stopped
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
# 服务管理命令
命令说明:所有命令均基于
docker-compose工具,需在docker-compose-esb-cluster.yml文件所在目录执行。
# 📋 基础操作命令
| 命令 | 说明 | 使用场景 |
|---|---|---|
up -d | 启动集群 | 首次部署或重启整个集群 |
ps | 查看状态 | 日常巡检、问题排查 |
logs | 查看日志 | 监控运行、故障诊断 |
# 启动集群(-d 表示后台运行)
docker-compose -f docker-compose-esb-cluster.yml up -d
# 查看服务运行状态(显示容器ID、状态、端口映射等)
docker-compose -f docker-compose-esb-cluster.yml ps
# 查看所有实例的实时日志(类似tail -f)
docker-compose -f docker-compose-esb-cluster.yml logs -f
# 查看特定实例的日志(esb-server1为服务名称)
docker-compose -f docker-compose-esb-cluster.yml logs -f esb-server1
# 查看最近100行日志(避免日志量过大)
docker-compose -f docker-compose-esb-cluster.yml logs --tail=100 -f esb-server2
# 查看带时间戳的日志(便于问题定位)
docker-compose -f docker-compose-esb-cluster.yml logs -f --timestamps
# 2、es中存在调用数据,调用日志的索引也是存在的,状态正常,但是在监控页面看不到数据,也查不到调用日志
# 问题现象
- Elasticsearch 中存在调用数据,且对应的调用日志索引存在。
- 但在监控页面无法看到数据,也无法查询到调用日志。
# 分析过程
- 确认数据是否真实存在于 ES 中:索引存在且包含数据。
- 对比监控页面查询请求与数据时间范围:
- 打开浏览器开发者工具(F12),查看监控页面发起的查询请求参数。
- 发现查询请求中的时间区间为 2017年。
- 进一步检查数据时间:
- ES 中实际数据的时间戳为当前时间(2020年代),与查询时间区间不符。
- 导致查询结果为空。
- 根本原因:
- 客户环境跳板机(Bastion Host)的系统时间不正确,被设置为 2017 年。
- 监控页面依赖浏览器(或前端)时间生成默认查询时间区间,由于跳板机时间错误,生成了错误的时间范围。
# 解决方案
- 校正跳板机的系统时间为当前正确时间。
- 刷新监控页面,验证查询时间区间恢复正常,数据正常显示。
# 总结
此类问题通常由客户端(如跳板机、用户本地PC)系统时间不准确引起,导致前端生成的时间范围与后端数据时间不匹配。排查时可优先检查:
- 数据是否存在,可以参考:ES中无数据或数据不完整 (opens new window);
- 查询请求的时间范围;
- 客户端系统时间是否正确。
# 3、调用日志总量分页查询无数据
# 问题现象
- 在查看调用日志总量时,当调用量较多的情况下,点击页码较大的页面(如第 100 页以后)无法查询出结果。
- 页面显示为空,但索引存在且数据正常写入。
# 分析过程
- 确认问题触发条件:
- 数据总量较大(超过 10000 条)。
- 翻页到较深页码时出现无数据现象,前几页查询正常。
- 检查 Elasticsearch 分页机制:
- Elasticsearch 默认使用
from + size方式进行分页查询。 - 默认限制:
from + size不能超过index.max_result_window参数值,该参数默认为 10000。 - 例如:查询第 100 页(每页 100 条),
from = 9900,size = 100,总和为 10000,仍在限制内;但查询第 101 页时,from = 10000,size = 100,总和 10100 超过限制,此时查询不会返回结果。
- Elasticsearch 默认使用
# 解决方案
- 按时间范围筛选查询:避免深度翻页,通过缩小时间窗口或其他条件分批查询,将数据量控制在 10000 条以内。
# 总结
Elasticsearch 默认的 10000 条查询限制是导致深度分页无数据的常见原因。解决方案应优先考虑业务层面的优化:
- 避免深度分页,通过时间范围、过滤条件等减少单次查询数据量。
- 不能调整默认参数,会影响产品性能。