大纲 前言 本文将介绍使用 Docker-Compose 部署 Kafka-Eagle(EFAK)的单机服务,实现对 Kafka 集群的管理和监控。
Kafka Eagle(EFAK)的介绍
Kafka Eagle (现已改名为 EFAK,Eagle For Apache Kafka)是一款国产开源 Kafka 集群监控系统,可以用来监视 Kafka 集群的 Broker 状态、Topic 信息、IO、内存、Consumer 线程、偏移量等信息,并进行可视化图表展示。独特的 KQL 还可以通过 SQL 在线查询 Kafka 中的数据。Kafka Eagle 自身支持单机和集群两种方式进行部署,在企业的生产环境中使用得比较多,尤其是大规模 Kafka 集群环境。
官方资源 部署规划 组件 版本 部署方式 说明 ZooKeeper 3.8.4
Docker-Compose 集群(三节点) Kafka 3.9.0
Docker-Compose 集群(三节点) MySQL 8.4.2
Docker-Compose 单机 Kafka Eagle(EFAK) 3.0.1
Docker-Compose 单机
准备工作 在部署 Kafka Eagle 之前,需要将 Kafka 集群和 MySQL 提前部署好。值得一提的是,如果项目中已有 Kafka 集群和 MySQL 服务正在运行,则可以忽略跳过二者的部署操作。
MySQL 部署 提示
Kafka Eagle(EFAK)需要一个数据库来存储其配置数据,如用户数据、Kafka 集群的监控指标数据等。 在默认情况下,Kafka Eagle(EFAK)使用的是 SQLite,而 SQLite 是存储在 EFAK 安装位置的嵌入式数据库。 Kafka 集群部署 提示
本文使用的 Kafka 集群是依赖于 Zookeeper 集群的,因此需要将 Zookeeper 集群提前搭建起来。 值得一提的是,从 Kafka 2.8.0
版本开始,Kafka 自身实现了 Raft
分布式一致性机制,这意味着 Kafka 集群是可以脱离 ZooKeeper 独立运行的。 完整的 YML 配置 特别注意
下述 docker-compose.yml
配置文件的内容可以直接复用,只需要简单更改数据卷(volumes
)的配置,并将 192.168.56.112
更改为你自己宿主机的 IP 地址即可。
严格按照上述教程,通过 Docker-Compose 成功部署 Kafka 集群和 MySQL 后,docker-compose.yml
配置文件的完整内容如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 version: '3.5' services: mysql: image: mysql:8.4.2 container_name: mysql command: ["mysqld" , "--mysql-native-password=ON" ] restart: always ports: - 3306 :3306 environment: TZ: Asia/Shanghai MYSQL_ROOT_PASSWORD: 123456 volumes: - /usr/local/mysql:/var/lib/mysql healthcheck: test: ["CMD-SHELL" , "mysqladmin ping -h localhost" ] interval: 10s timeout: 5s retries: 5 start_period: 30s networks: - distributed-network zookeeper01: image: zookeeper:3.8.4 container_name: zookeeper01 restart: always hostname: zookeeper01 ports: - 2181 :2181 environment: TZ: Asia/Shanghai ZOO_MY_ID: 1 ZOO_PORT: 2181 ZOO_4LW_COMMANDS_WHITELIST: ruok ZOO_SERVERS: server.1=zookeeper01:2888:3888;2181 server.2=zookeeper02:2888:3888;2181 server.3=zookeeper03:2888:3888;2181 healthcheck: test: ["CMD" , "sh" , "-c" , "echo ruok | nc localhost 2181 | grep imok" ] interval: 30s timeout: 10s retries: 5 start_period: 20s volumes: - /usr/local/zookeeper/zookeeper01/data:/data - /usr/local/zookeeper/zookeeper01/datalog:/datalog networks: - distributed-network zookeeper02: image: zookeeper:3.8.4 container_name: zookeeper02 restart: always hostname: zookeeper02 ports: - 2182 :2181 environment: TZ: Asia/Shanghai ZOO_MY_ID: 2 ZOO_PORT: 2181 ZOO_4LW_COMMANDS_WHITELIST: ruok ZOO_SERVERS: server.1=zookeeper01:2888:3888;2181 server.2=zookeeper02:2888:3888;2181 server.3=zookeeper03:2888:3888;2181 healthcheck: test: ["CMD" , "sh" , "-c" , "echo ruok | nc localhost 2181 | grep imok" ] interval: 30s timeout: 10s retries: 5 start_period: 20s volumes: - /usr/local/zookeeper/zookeeper02/data:/data - /usr/local/zookeeper/zookeeper02/datalog:/datalog networks: - distributed-network zookeeper03: image: zookeeper:3.8.4 container_name: zookeeper03 restart: always hostname: zookeeper03 ports: - 2183 :2181 environment: TZ: Asia/Shanghai ZOO_MY_ID: 3 ZOO_PORT: 2181 ZOO_4LW_COMMANDS_WHITELIST: ruok ZOO_SERVERS: server.1=zookeeper01:2888:3888;2181 server.2=zookeeper02:2888:3888;2181 server.3=zookeeper03:2888:3888;2181 healthcheck: test: ["CMD" , "sh" , "-c" , "echo ruok | nc localhost 2181 | grep imok" ] interval: 30s timeout: 10s retries: 5 start_period: 20s volumes: - /usr/local/zookeeper/zookeeper03/data:/data - /usr/local/zookeeper/zookeeper03/datalog:/datalog networks: - distributed-network kafka01: image: bitnami/kafka:3.9.0 container_name: kafka01 restart: always hostname: kafka01 ports: - 9093 :9093 environment: TZ: Asia/Shanghai KAFKA_CFG_NODE_ID: 1 KAFKA_CFG_LISTENERS: PLAINTEXT://:9093 KAFKA_CFG_ADVERTISED_LISTENERS: PLAINTEXT://192.168.56.112:9093 KAFKA_CFG_ZOOKEEPER_CONNECT: zookeeper01:2181,zookeeper02:2181,zookeeper03:2181/kafka ALLOW_PLAINTEXT_LISTENER: yes healthcheck: test: ["CMD" , "kafka-topics.sh" , "--bootstrap-server" , "kafka01:9093,kafka02:9094,kafka03:9095" , "--list" ] interval: 30s timeout: 15s retries: 5 start_period: 30s volumes: - /usr/local/kafka/kafka01:/bitnami/kafka depends_on: zookeeper01: condition: service_healthy zookeeper02: condition: service_healthy zookeeper03: condition: service_healthy networks: - distributed-network kafka02: image: bitnami/kafka:3.9.0 container_name: kafka02 restart: always hostname: kafka02 ports: - 9094 :9094 environment: TZ: Asia/Shanghai KAFKA_CFG_NODE_ID: 2 KAFKA_CFG_LISTENERS: PLAINTEXT://:9094 KAFKA_CFG_ADVERTISED_LISTENERS: PLAINTEXT://192.168.56.112:9094 KAFKA_CFG_ZOOKEEPER_CONNECT: zookeeper01:2181,zookeeper02:2181,zookeeper03:2181/kafka ALLOW_PLAINTEXT_LISTENER: yes healthcheck: test: ["CMD" , "kafka-topics.sh" , "--bootstrap-server" , "kafka01:9093,kafka02:9094,kafka03:9095" , "--list" ] interval: 30s timeout: 15s retries: 5 start_period: 30s volumes: - /usr/local/kafka/kafka02:/bitnami/kafka depends_on: zookeeper01: condition: service_healthy zookeeper02: condition: service_healthy zookeeper03: condition: service_healthy networks: - distributed-network kafka03: image: bitnami/kafka:3.9.0 container_name: kafka03 restart: always hostname: kafka03 ports: - 9095 :9095 environment: TZ: Asia/Shanghai KAFKA_CFG_NODE_ID: 3 KAFKA_CFG_LISTENERS: PLAINTEXT://:9095 KAFKA_CFG_ADVERTISED_LISTENERS: PLAINTEXT://192.168.56.112:9095 KAFKA_CFG_ZOOKEEPER_CONNECT: zookeeper01:2181,zookeeper02:2181,zookeeper03:2181/kafka ALLOW_PLAINTEXT_LISTENER: yes healthcheck: test: ["CMD" , "kafka-topics.sh" , "--bootstrap-server" , "kafka01:9093,kafka02:9094,kafka03:9095" , "--list" ] interval: 30s timeout: 15s retries: 5 start_period: 30s volumes: - /usr/local/kafka/kafka03:/bitnami/kafka depends_on: zookeeper01: condition: service_healthy zookeeper02: condition: service_healthy zookeeper03: condition: service_healthy networks: - distributed-network networks: distributed-network: driver: bridge
Kafka Eagle 单机部署 初始化数据库 创建数据库,用于 Kafka Eagle(EFAK)存储 Kafka 的监控指标数据 1 2 -- 创建数据库 CREATE DATABASE efak DEFAULT CHARACTER SET utf8mb4;
创建数据库用户并授权访问,用于 Kafka Eagle(EFAK)连接 MySQL 1 2 3 4 5 6 7 8 -- 创建用户 CREATE USER 'efak' @'%' IDENTIFIED WITH mysql_native_password BY '123456' ; -- 用户授权 GRANT ALL PRIVILEGES ON efak.* TO 'efak' @'%' ; -- 刷新权限 FLUSH PRIVILEGES;
提示
(1) 在初始化 MySQL 数据库时,只需要创建数据库,而不需要手动创建数据库表。这是因为 Kafka Eagle(EFAK)会在启动的时候自动创建所需的数据库表 ,前提是 Kafka Eagle(EFAK)用于连接 MySQL 的用户有对应的数据库操作权限。 (2) 值得一提的是,当不使用 MySQL 来存储 Kafka 的监控指标数据时,Kafka Eagle(EFAK)默认会使用 SQlite 作为数据库。 创建容器 特别注意
下述配置内容是在上面用于部署 Kafka 集群和 MySQL 的 docker-compose.yml
配置文件的基础上更改而来的,其主要变化有以下几点: (1) 新增 Kafka Eagle(EFAK)的配置 (2) Kafka 容器新增 JMX 服务的配置 (3) 去掉 Kafka 容器启动时的健康检测配置(healthcheck
) (4) 更改 ZooKeeper 容器的 "四字命令" 配置为 mntr,conf,ruok,stat
为什么要去掉 Kafka 容器启动时的健康检测
这是因为 Kafka Eagle(EFAK)需要依赖 Kafka 的 JMX 服务来对 Kafaka 实现监控,可是一旦启用 JMX,在 Kafka 容器内部不能再执行类似 kafka-topics.sh --bootstrap-server xxx --list
这样的命令,否则会抛出 JMX 端口占用冲突的异常。 为什么要更改 ZooKeeper 容器的四字命令配置
这是因为 Kafka Eagle(EFAK)需要依赖 ZooKeeper 的 "四字命令" 来对 ZooKeeper 实现监控。在默认情况下,ZooKeeper 会禁用 "四字命令",这样会导致 Kafka Eagle(EFAK)无法正常监控 ZooKeeper 的运行状态,所以需要启用下面这几个 "四字命令"。 ruok
:用于检查 Zookeeper 服务是否正常运行。conf
:返回当前 Zookeeper 集群的配置,例如节点配置、数据目录等。stat
:返回 Zookeeper 节点的状态,包括当前连接数、Zookeeper 节点的版本、日志文件信息等。mntr
:返回 Zookeeper 的监控信息,包括各个节点的状态、同步信息等,通常用于健康检测和性能监控。更改上面用于部署 Kafka 集群和 MySQL 的 docker-compose.yml
配置文件,并添加 Kafka Eagle(EFAK)的配置,完整的配置内容如下所示: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 version: '3.5' services: mysql: image: mysql:8.4.2 container_name: mysql command: ["mysqld" , "--mysql-native-password=ON" ] restart: always ports: - 3306 :3306 environment: TZ: Asia/Shanghai MYSQL_ROOT_PASSWORD: 123456 volumes: - /usr/local/mysql:/var/lib/mysql healthcheck: test: ["CMD-SHELL" , "mysqladmin ping -h localhost" ] interval: 10s timeout: 5s retries: 5 start_period: 30s networks: - distributed-network zookeeper01: image: zookeeper:3.8.4 container_name: zookeeper01 restart: always hostname: zookeeper01 ports: - 2181 :2181 environment: TZ: Asia/Shanghai ZOO_MY_ID: 1 ZOO_PORT: 2181 ZOO_4LW_COMMANDS_WHITELIST: mntr,conf,ruok,stat ZOO_SERVERS: server.1=zookeeper01:2888:3888;2181 server.2=zookeeper02:2888:3888;2181 server.3=zookeeper03:2888:3888;2181 healthcheck: test: ["CMD" , "sh" , "-c" , "echo ruok | nc localhost 2181 | grep imok" ] interval: 30s timeout: 10s retries: 5 start_period: 20s volumes: - /usr/local/zookeeper/zookeeper01/data:/data - /usr/local/zookeeper/zookeeper01/datalog:/datalog networks: - distributed-network zookeeper02: image: zookeeper:3.8.4 container_name: zookeeper02 restart: always hostname: zookeeper02 ports: - 2182 :2181 environment: TZ: Asia/Shanghai ZOO_MY_ID: 2 ZOO_PORT: 2181 ZOO_4LW_COMMANDS_WHITELIST: mntr,conf,ruok,stat ZOO_SERVERS: server.1=zookeeper01:2888:3888;2181 server.2=zookeeper02:2888:3888;2181 server.3=zookeeper03:2888:3888;2181 healthcheck: test: ["CMD" , "sh" , "-c" , "echo ruok | nc localhost 2181 | grep imok" ] interval: 30s timeout: 10s retries: 5 start_period: 20s volumes: - /usr/local/zookeeper/zookeeper02/data:/data - /usr/local/zookeeper/zookeeper02/datalog:/datalog networks: - distributed-network zookeeper03: image: zookeeper:3.8.4 container_name: zookeeper03 restart: always hostname: zookeeper03 ports: - 2183 :2181 environment: TZ: Asia/Shanghai ZOO_MY_ID: 3 ZOO_PORT: 2181 ZOO_4LW_COMMANDS_WHITELIST: mntr,conf,ruok,stat ZOO_SERVERS: server.1=zookeeper01:2888:3888;2181 server.2=zookeeper02:2888:3888;2181 server.3=zookeeper03:2888:3888;2181 healthcheck: test: ["CMD" , "sh" , "-c" , "echo ruok | nc localhost 2181 | grep imok" ] interval: 30s timeout: 10s retries: 5 start_period: 20s volumes: - /usr/local/zookeeper/zookeeper03/data:/data - /usr/local/zookeeper/zookeeper03/datalog:/datalog networks: - distributed-network kafka01: image: bitnami/kafka:3.9.0 container_name: kafka01 restart: always hostname: kafka01 ports: - 9093 :9093 - 19999 :19999 environment: TZ: Asia/Shanghai KAFKA_CFG_NODE_ID: 1 KAFKA_CFG_LISTENERS: PLAINTEXT://:9093 KAFKA_CFG_ADVERTISED_LISTENERS: PLAINTEXT://192.168.56.112:9093 KAFKA_CFG_ZOOKEEPER_CONNECT: zookeeper01:2181,zookeeper02:2181,zookeeper03:2181/kafka ALLOW_PLAINTEXT_LISTENER: yes KAFKA_JMX_PORT: 19999 KAFKA_JMX_OPTS: '-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djava.rmi.server.hostname=kafka01 -Dcom.sun.management.jmxremote.port=19999' volumes: - /usr/local/kafka/kafka01:/bitnami/kafka depends_on: zookeeper01: condition: service_healthy zookeeper02: condition: service_healthy zookeeper03: condition: service_healthy networks: - distributed-network kafka02: image: bitnami/kafka:3.9.0 container_name: kafka02 restart: always hostname: kafka02 ports: - 9094 :9094 - 29999 :29999 environment: TZ: Asia/Shanghai KAFKA_CFG_NODE_ID: 2 KAFKA_CFG_LISTENERS: PLAINTEXT://:9094 KAFKA_CFG_ADVERTISED_LISTENERS: PLAINTEXT://192.168.56.112:9094 KAFKA_CFG_ZOOKEEPER_CONNECT: zookeeper01:2181,zookeeper02:2181,zookeeper03:2181/kafka ALLOW_PLAINTEXT_LISTENER: yes KAFKA_JMX_PORT: 29999 KAFKA_JMX_OPTS: '-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djava.rmi.server.hostname=kafka02 -Dcom.sun.management.jmxremote.port=29999' volumes: - /usr/local/kafka/kafka02:/bitnami/kafka depends_on: zookeeper01: condition: service_healthy zookeeper02: condition: service_healthy zookeeper03: condition: service_healthy networks: - distributed-network kafka03: image: bitnami/kafka:3.9.0 container_name: kafka03 restart: always hostname: kafka03 ports: - 9095 :9095 - 39999 :39999 environment: TZ: Asia/Shanghai KAFKA_CFG_NODE_ID: 3 KAFKA_CFG_LISTENERS: PLAINTEXT://:9095 KAFKA_CFG_ADVERTISED_LISTENERS: PLAINTEXT://192.168.56.112:9095 KAFKA_CFG_ZOOKEEPER_CONNECT: zookeeper01:2181,zookeeper02:2181,zookeeper03:2181/kafka ALLOW_PLAINTEXT_LISTENER: yes KAFKA_JMX_PORT: 39999 KAFKA_JMX_OPTS: '-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djava.rmi.server.hostname=kafka03 -Dcom.sun.management.jmxremote.port=39999' volumes: - /usr/local/kafka/kafka03:/bitnami/kafka depends_on: zookeeper01: condition: service_healthy zookeeper02: condition: service_healthy zookeeper03: condition: service_healthy networks: - distributed-network efak: image: nickzurich/efak:3.0.1 container_name: efak restart: always ports: - 8048 :8048 environment: TZ: Asia/Shanghai EFAK_CLUSTER_ZK_LIST: zookeeper01:2181,zookeeper02:2181,zookeeper03:2181/kafka EFAK_CLUSTER_KAFKA_EAGLE_OFFSET_STORAGE: kafka EFAK_DB_USERNAME: efak EFAK_DB_PASSWORD: 123456 EFAK_DB_DRIVER: com.mysql.cj.jdbc.Driver EFAK_DB_URL: jdbc:mysql://mysql:3306/efak?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull depends_on: - mysql - kafka01 - kafka02 - kafka03 networks: - distributed-network networks: distributed-network: driver: bridge
重要参数说明
EFAK_CLUSTER_ZK_LIST
:指定 ZooKeeper 集群的节点列表。EFAK_CLUSTER_KAFKA_EAGLE_OFFSET_STORAGE
:指定 Kafka 集群存储 Offset 的位置。EFAK_DB_USERNAME
:指定 Kafka Eagle(EFAK)连接数据库的用户名。EFAK_DB_PASSWORD
:指定 Kafka Eagle(EFAK)连接数据库的密码。EFAK_DB_DRIVER
:指定 Kafka Eagle(EFAK)连接数据库的驱动。EFAK_DB_URL
:指定 Kafka Eagle(EFAK)连接数据库的 URL。KAFKA_JMX_PORT
:指定 Kafka 使用的 JMX 监听端口。KAFKA_JMX_OPTS
:通过 Java 的系统属性配置 JMX 的详细选项,比如是否启用 JMX、RMI 主机名、RMI 端口、JMX 的身份认证、JMX 的 SSL 证书 等。KAFKA_CFG_ADVERTISED_LISTENERS: PLAINTEXT://192.168.56.112:9095
:这里的 192.168.56.112
是宿主机的 IP 地址或者公网 IP 地址。如果配置错误,会导致外部 Kafka 客户端无法正常连接 Docker 容器内的 Kafka 服务器 。创建并启动 Kafka Eagle(EFAK) 容器(请必须保证操作系统有 2G 空闲内存,否则容器会启动失败 ) 1 sudo sudo docker-compose up -d
特别注意
当不使用 MySQL 来存储 Kafka 的监控指标数据时,Kafka Eagle(EFAK)默认会使用 SQlite 作为数据库;此时如果希望持久化容器内的 SQlite 数据文件,可以通过数据卷挂载 Kafka Eagle(EFAK)容器内的 /hadoop/efak/db/ke.db
文件到宿主机内。 在停止 Kafka 集群时,一定要等 Kafka 所有节点进程全部停止后,再停止 Zookeeper 集群。因为 Zookeeper 集群当中记录着 Kafka 集群的相关信息,Zookeeper 集群一旦先停止,Kafka 集群就没有办法再获取停止进程的信息,最后只能手动杀死 Kafka 进程了。 验证容器 查看容器状态 查看所有 Kafka Eagle(EFAK) 容器的运行状态 1 2 3 4 5 6 7 8 ebc5136d2afb nickzurich/efak:3.0.1 "entrypoint.sh" 44 seconds ago Up 42 seconds 0.0.0.0:8048->8048/tcp, :::8048->8048/tcp, 8080/tcp efak ed37bf8c8eac bitnami/kafka:3.9.0 "/opt/bitnami/script…" 17 minutes ago Up 16 minutes 9092/tcp, 0.0.0.0:9093->9093/tcp, :::9093->9093/tcp kafka01 c09ca638d783 bitnami/kafka:3.9.0 "/opt/bitnami/script…" 17 minutes ago Up 16 minutes 9092/tcp, 0.0.0.0:9095->9095/tcp, :::9095->9095/tcp kafka03 9f2636e03ad3 bitnami/kafka:3.9.0 "/opt/bitnami/script…" 17 minutes ago Up 16 minutes 9092/tcp, 0.0.0.0:9094->9094/tcp, :::9094->9094/tcp kafka02 d82f6b11979c zookeeper:3.8.4 "/docker-entrypoint.…" 17 minutes ago Up 17 minutes (healthy) 2888/tcp, 3888/tcp, 8080/tcp, 0.0.0.0:2182->2181/tcp, :::2182->2181/tcp zookeeper02 639310a6bdd2 zookeeper:3.8.4 "/docker-entrypoint.…" 17 minutes ago Up 17 minutes (healthy) 2888/tcp, 3888/tcp, 0.0.0.0:2181->2181/tcp, :::2181->2181/tcp, 8080/tcp zookeeper01 9d255997e30e zookeeper:3.8.4 "/docker-entrypoint.…" 17 minutes ago Up 17 minutes (healthy) 2888/tcp, 3888/tcp, 8080/tcp, 0.0.0.0:2183->2181/tcp, :::2183->2181/tcp zookeeper03 3361ac6e2d10 mysql:8.4.2 "docker-entrypoint.s…" 17 minutes ago Up 17 minutes (healthy) 33060/tcp, 0.0.0.0:3309->3306/tcp, :::3309->3306/tcp mysql
若 Kafka Eagle(EFAK)容器启动失败,可以通过以下命令查看容器的启动日志来排查问题 1 2 sudo docker logs -f --tail 100 efak
访问管理页面 (1) 浏览器通过 http://192.168.56.112:8048
访问 Kafka Eagle(EFAK)的控制台管理页面(如下所示),默认的登录账号和密码是 admin/123456
,请记得将 192.168.56.112
更改为你自己宿主机的 IP 地址。
(2) 登录 Kafka Eagle(EFAK)的控制台后,浏览器通过 http://192.168.56.112:8048/tv
就可以访问监控数据大屏的页面(如下所示),请记得将 192.168.56.112
更改为你自己宿主机的 IP 地址。
特别注意
在默认情况下,Kafka Eagle(EFAK)的监控数据大屏页面不会实时更新显示 Kafka 集群的监控指标图表,比如 CPU 与内存的使用率、生产速率、消费速率等。 如果需要在 Kafka Eagle(EFAK)的 UI 中实时显示 Kafka 集群的监控指标图表,可以通过给 Kafka Eagle(EFAK)容器添加环境变量 EFAK_METRICS_CHARTS: true
来开启该功能。 值得一提的是,Kafka 集群监控指标图表的渲染和数据获取会消耗一定的资源,如果 Kafka 的集群规模较大或者系统资源有限,建议通过禁用 EFAK_METRICS_CHARTS
选项(默认禁用)来减少系统负载。 (3) 当 Kafka 的 JMX 服务配置正确后,浏览器通过 http://192.168.56.112:8048/cluster/kafka
就可以访问 Kafka 的监控页面(如下所示),请记得将 192.168.56.112
更改为你自己宿主机的 IP 地址。
(4) 当 ZooKeeper 的 “四字命令” 配置正确后,浏览器通过 http://192.168.56.112:8048/cluster/zookeeper
就可以访问 ZooKeeper 的监控页面(如下所示),请记得将 192.168.56.112
更改为你自己宿主机的 IP 地址。
Kafka Eagle 部署问题 JMX 端口占用冲突 当 Kafka 容器新增 JMX 服务的配置后,在 Kafka 容器内部执行类似 kafka-console-producer.sh --broker-list xxx --topic test
这样的命令,会抛出 JMX 端口占用冲突的异常(如下所示)。解决方法是只在 Kafka 容器外执行管理命令。
1 2 3 4 5 6 7 8 9 10 11 12 Caused by: java.rmi.server.ExportException: Port already in use: 19999; nested exception is: java.net.BindException: Address already in use at java.rmi/sun.rmi.transport.tcp.TCPTransport.listen(TCPTransport.java:346) at java.rmi/sun.rmi.transport.tcp.TCPTransport.exportObject(TCPTransport.java:243) at java.rmi/sun.rmi.transport.tcp.TCPEndpoint.exportObject(TCPEndpoint.java:415) at java.rmi/sun.rmi.transport.LiveRef.exportObject(LiveRef.java:147) at java.rmi/sun.rmi.server.UnicastServerRef.exportObject(UnicastServerRef.java:235) at java.rmi/sun.rmi.registry.RegistryImpl.setup(RegistryImpl.java:223) at java.rmi/sun.rmi.registry.RegistryImpl.<init>(RegistryImpl.java:182) at jdk.management.agent/sun.management.jmxremote.SingleEntryRegistry.<init>(SingleEntryRegistry.java:49) at jdk.management.agent/sun.management.jmxremote.ConnectorBootstrap.exportMBeanServer(ConnectorBootstrap.java:859) at jdk.management.agent/sun.management.jmxremote.ConnectorBootstrap.startRemoteConnectorServer(ConnectorBootstrap.java:480)
Kafka Eagle 集群部署 在生产环境中,往往都需要部署多个 Kafka Eagle(EFAK) 实例,以此实现高可用。Kafka Eagle(EFAK)是天生支持集群(分布式)部署的,但由于 Kafka Eagle(EFAK)官方目前构建的 Docker 镜像并不支持集群部署功能。因此,如果需要部署 Kafka Eagle(EFAK)集群,只能是手动进行部署或者自行构建 Docker 镜像来实现,其中手动部署的教程请参考 官方文档 或者 本站教程 。
挂载 Kafka Eagle 配置文件无效 当使用的 Kafka Eagle(EFAK)镜像是 3.0.1
版本时,不能再通过数据卷挂载配置文件到容器内的方式(如下所示)来指定 system-config.properties
配置文件。因为 Kafka Eagle(EFAK)容器在每次启动时,都会拷贝默认的 system-config.properties
配置文件进行覆盖,导致外部挂载的配置文件也被 “重置”,详见这里 的脚本代码。解决办法是,在 Docker-Compose 中通过环境变量来指定 Kafka Eagle(EFAK)的配置参数。值得一提的是,Kafka Eagle(EFAK)镜像支持的所有环境变量可以从 这里 获取得到。
1 2 3 4 5 6 7 8 9 10 11 12 13 version: '3.5' services: efak: image: nickzurich/efak:3.0.1 container_name: efak restart: always ports: - 8048 :8048 environment: - TZ: Asia/Shanghai volumes: - /usr/local/efak/system-config.properties:/opt/efak/conf/system-config.properties
内存不足导致容器启动失败 在 Kafka Eagle(EFAK)的项目源码中,有一个 ke.sh
启动脚本 ,该脚本里面有以下一行代码:
1 export KE_JAVA_OPTS="-server -Xmx2g -Xms2g -XX:MaxGCPauseMillis=20 -XX:+UseG1GC -XX:MetaspaceSize=128m -XX:InitiatingHeapOccupancyPercent=35 -XX:G1HeapRegionSize=16M -XX:MinMetaspaceFreeRatio=50 -XX:MaxMetaspaceFreeRatio=80"
其中 JVM 参数 -Xms2g
指定了初始堆内存为 2G
,因此当操作系统的空闲内存不足 2G
时,会导致 Kafka Eagle(EFAK)容器启动失败。解决办法是,更改 Shell 脚本代码并重新构建 Kafka Eagle(EFAK)镜像,或者增加机器的物理内存(强烈推荐)。
监控大屏无法实时更新显示 在 Kafka Eagle(EFAK)的控制台中访问监控大屏页面时,发现即使有生产者正在发送消息和消费者正在消费消息,Kafka 集群的监控指标图表也无法实时更新显示或者没有任何监控数据显示(如下图所示)。这是因为 Kafka Eagle(EFAK)默认禁用了 Kafka 集群的监控指标图表实时更新。
解决办法是,通过给 Kafka Eagle(EFAK)容器添加环境变量 EFAK_METRICS_CHARTS: true
来开启 Kafka 集群的监控指标图表实时更新。
1 2 3 4 5 6 7 version: '3.5' services: efak: image: nickzurich/efak:3.0.1 environment: EFAK_METRICS_CHARTS: true
特别注意
在 Kafka Eagle(EFAK)的控制台中,Kafka 集群监控指标图表的渲染和数据获取会消耗一定的资源。如果 Kafka 的集群规模较大或者系统资源有限,建议通过禁用 EFAK_METRICS_CHARTS
选项(默认禁用)来减少系统负载。
Kafka Eagle 无法监控自己 在 Kafka Eagle(EFAK)的控制台中访问 EfakServer 的监控页面时,发现无法正常显示 EfakServer 的运行状态,监控页面一直显示提示信息 Processing
或者节点状态显示为 Offline
,如下图所示:
这个问题可以忽略不解决,猜测(待验证)只有当 Kafka Eagle(EFAK)以集群(分布式)模式部署时,EfakServer 的监控页面才会正常显示相关监控信息,详细说明请看 这里 。
无法监控 ZooKeeper 集群 在 Kafka Eagle(EFAK)的控制台中访问 ZooKeeper 的监控页面时,发现无法正常显示 ZooKeeper 的运行状态,如下图所示:
这通常是由于 ZooKeeper 容器没有配置 “四字命令” 或者 “四字命令” 配置不正确导致的,因为 Kafka Eagle(EFAK)是基于 ZooKeeper 的 “四字命令” 来实现 ZooKeeper 运行状态的监控。解决办法是,为 ZooKeeper 容器添加对应的 “四字命令” 配置,如下所示:
1 2 3 4 5 6 zookeeper: image: zookeeper:3.8.4 ports: - 2181 :2181 environment: ZOO_4LW_COMMANDS_WHITELIST: mntr,conf,ruok,stat
无法监控 Kafka 集群 在 Kafka Eagle(EFAK)的控制台中访问 Kafka 的监控页面时,发现无法正常显示 Kafka 的运行状态,如下图所示:
这通常是由于 Kafka 容器没有配置 JMX 服务或者 JMX 服务配置不正确导致的,因为 Kafka Eagle(EFAK)是基于 JMX 服务来实现 Kafka 运行状态的监控。解决办法是,为 Kafka 容器添加对应的 JMX 配置,如下所示:
1 2 3 4 5 6 7 8 9 10 11 version: '3.5' services: kafka: image: bitnami/kafka:3.9.0 ports: - 9092 :9092 - 19999 :19999 environment: KAFKA_JMX_PORT: 19999 KAFKA_JMX_OPTS: '-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djava.rmi.server.hostname=kafka -Dcom.sun.management.jmxremote.port=19999'
参考教程