kafka监控kafka manager(CMAK)部署配置

一、准备工作

1.1、服务器信息梳理

角色 IP 操作系统 安装服务
监控机 10.45.19.20 Linux CentOS 7.9 CMAK3.0.0.5、ZooKeeper3.9.0、JDK11、JDK1.8
被监控机 Kafka broker.id 0 50.50.50.101 Linux CentOS 7.9 Kafka、ZooKeeper(任意版本)
被监控机 Kafka broker.id 1 50.50.50.101 Linux CentOS 7.9 Kafka、ZooKeeper(任意版本)
被监控机 Kafka broker.id 2 50.50.50.101 Linux CentOS 7.9 Kafka、ZooKeeper(任意版本)

1.2、准备以下安装包

复制代码
https://www.oracle.com/java/technologies/downloads/archive

https://archive.apache.org/dist/zookeeper

https://github.com/yahoo/CMAK

jdk-11.0.26_linux-x64_bin.tar.gz
jdk-8u161-linux-x64.tar.gz
apache-zookeeper-3.9.0-bin.tar.gz
cmak-3.0.0.5.zip

1.3、创建安装目录

复制代码
mkdir /usr/local/cmak

二、部署 JDK11 环境

复制代码
jdk-11.0.26_linux-x64_bin.tar.gz
bash 复制代码
tar zxf jdk-11.0.26_linux-x64_bin.tar.gz -C /usr/local/cmak

三、部署 ZooKeeper 存储元数据

3.1、部署 JDK1.8 环境

bash 复制代码
tar zxf jdk-8u161-linux-x64.tar.gz -C /usr/local/cmak
bash 复制代码
vim /etc/etc/profile
bash 复制代码
export PATH=$PATH:/usr/local/cmak/jdk1.8.0_161/bin

3.2、部署 ZooKeeper

3.2.1、解压至安装目录

bash 复制代码
wget https://archive.apache.org/dist/zookeeper/zookeeper-3.9.0/apache-zookeeper-3.9.0-bin.tar.gz
bash 复制代码
tar zxf apache-zookeeper-3.9.0-bin.tar.gz -C /usr/local/cmak
bash 复制代码
mv /usr/local/cmak/apache-zookeeper-3.9.0-bin /usr/local/cmak/zookeeper-3.9.0

3.2.2、创建存储目录

bash 复制代码
mkdir /usr/local/cmak/zookeeper-3.9.0/{data,logs}

3.2.3、编辑配置文件

bash 复制代码
cp /usr/local/cmak/zookeeper-3.9.0/conf/zoo_sample.cfg /usr/local/cmak/zookeeper-3.9.0/conf/zoo.cfg
bash 复制代码
vim /usr/local/cmak/zookeeper-3.9.0/conf/zoo.cfg
c 复制代码
dataDir=/usr/local/cmak/zookeeper-3.9.0/data
dataLogDir=/usr/local/cmak/zookeeper-3.9.0/logs
clientPort=3281
admin.serverPort=3282
tickTime=2000
initLimit=10
syncLimit=5

3.2.4、启动

bash 复制代码
sh /usr/local/cmak/zookeeper-3.9.0/bin/zkServer.sh start

四、部署 CMAK 监控

4.1、解压至安装目录

复制代码
https://github.com/yahoo/CMAK/releases/download/3.0.0.5/cmak-3.0.0.5.zip
bash 复制代码
unzip cmak-3.0.0.6.zip -d /usr/local/cmak

4.2、编写配置文件

bash 复制代码
vim /usr/local/cmak/cmak-3.0.0.6/conf/application.conf
c 复制代码
# -------------------------------------------------------------------
# Application 基础配置
# -------------------------------------------------------------------

# 加密会话和 Cookie 的密钥(生产环境建议使用环境变量覆盖)
# 默认硬编码密钥(注意:硬编码密钥不安全,建议通过环境变量设置)
play.crypto.secret="^<csmm5Fx4d=r2HEX8pelM3iBkFVv?k[mc;IZE<_Qoq8EkX_/7@Zt6dP05Pzea3U"
# 允许通过环境变量 APPLICATION_SECRET 覆盖密钥
play.crypto.secret=${?APPLICATION_SECRET}

# 会话过期时间(1小时)
play.http.session.maxAge="1h"

# 国际化支持的语言列表(当前仅英语)
play.i18n.langs=["en"]

# HTTP 请求处理器和上下文路径
play.http.requestHandler = "play.http.DefaultHttpRequestHandler"
play.http.context = "/"

# 应用加载器类(自定义 Kafka Manager 加载逻辑)
play.application.loader=loader.KafkaManagerLoader


# -------------------------------------------------------------------
# ZooKeeper 配置
# -------------------------------------------------------------------

# ZooKeeper 连接地址(默认值)
cmak.zkhosts="10.45.19.20:3281"
# 允许通过环境变量 ZK_HOSTS 覆盖 ZooKeeper 地址
cmak.zkhosts=${?ZK_HOSTS}


# -------------------------------------------------------------------
# 线程调度配置
# -------------------------------------------------------------------

# 固定调度器配置(确保每个 Actor 独占线程池)
pinned-dispatcher.type="PinnedDispatcher"
pinned-dispatcher.executor="thread-pool-executor"


# -------------------------------------------------------------------
# 应用功能特性开关
# -------------------------------------------------------------------
# 启用的 Kafka 管理功能列表:
# - 集群管理
# - Topic 管理
# - 首选副本选举
# - 分区重分配
# - 计划 Leader 选举
application.features=[
  "KMClusterManagerFeature",
#  "KMTopicManagerFeature",
#  "KMPreferredReplicaElectionFeature",
#  "KMReassignPartitionsFeature",
#  "KMScheduleLeaderElectionFeature"
]


# -------------------------------------------------------------------
# Akka 配置
# -------------------------------------------------------------------
akka {
  # 使用 SLF4J 作为日志记录器
  loggers = ["akka.event.slf4j.Slf4jLogger"]
  # 日志级别(INFO | DEBUG | WARN | ERROR)
#  loglevel = "INFO"
  loglevel = "WARN"
}

# Akka 日志系统启动超时时间
akka.logger-startup-timeout = 60s


# -------------------------------------------------------------------
# 基础认证配置
# -------------------------------------------------------------------

# 是否启用基础认证(默认禁用)
basicAuthentication.enabled=true
# 允许通过环境变量 KAFKA_MANAGER_AUTH_ENABLED 覆盖
basicAuthentication.enabled=${?KAFKA_MANAGER_AUTH_ENABLED}

# LDAP 认证配置 -----------------------------------------------------
# 是否启用 LDAP 认证(默认禁用)
basicAuthentication.ldap.enabled=false
basicAuthentication.ldap.enabled=${?KAFKA_MANAGER_LDAP_ENABLED}

# LDAP 服务器地址(示例:ldap://hostname)
basicAuthentication.ldap.server=""
basicAuthentication.ldap.server=${?KAFKA_MANAGER_LDAP_SERVER}

# LDAP 端口(默认 389,SSL 通常为 636)
basicAuthentication.ldap.port=389
basicAuthentication.ldap.port=${?KAFKA_MANAGER_LDAP_PORT}

# 连接 LDAP 的用户名和密码
basicAuthentication.ldap.username=""
basicAuthentication.ldap.username=${?KAFKA_MANAGER_LDAP_USERNAME}
basicAuthentication.ldap.password=""
basicAuthentication.ldap.password=${?KAFKA_MANAGER_LDAP_PASSWORD}

# LDAP 搜索配置
basicAuthentication.ldap.search-base-dn=""
basicAuthentication.ldap.search-base-dn=${?KAFKA_MANAGER_LDAP_SEARCH_BASE_DN}
basicAuthentication.ldap.search-filter="(uid=$capturedLogin$)"
basicAuthentication.ldap.search-filter=${?KAFKA_MANAGER_LDAP_SEARCH_FILTER}

# LDAP 组过滤配置
basicAuthentication.ldap.group-filter=""
basicAuthentication.ldap.group-filter=${?KAFKA_MANAGER_LDAP_GROUP_FILTER}

# 连接池配置
basicAuthentication.ldap.connection-pool-size=10
basicAuthentication.ldap.connection-pool-size=${?KAFKA_MANAGER_LDAP_CONNECTION_POOL_SIZE}

# SSL 配置
basicAuthentication.ldap.ssl=false
basicAuthentication.ldap.ssl=${?KAFKA_MANAGER_LDAP_SSL}
basicAuthentication.ldap.ssl-trust-all=false
basicAuthentication.ldap.ssl-trust-all=${?KAFKA_MANAGER_LDAP_SSL_TRUST_ALL}

# 基础认证凭据(仅在启用基础认证且未启用 LDAP 时生效)
basicAuthentication.username="admin"
basicAuthentication.username=${?KAFKA_MANAGER_USERNAME}
basicAuthentication.password="Quk@EL!4xMyj3hnD"
basicAuthentication.password=${?KAFKA_MANAGER_PASSWORD}

# 认证领域名称和免认证路径(/api/health 用于健康检查)
basicAuthentication.realm="Kafka-Manager"
basicAuthentication.excluded=["/api/health"]


# -------------------------------------------------------------------
# Kafka 消费者配置
# -------------------------------------------------------------------

# 外部消费者配置文件路径(可选)
kafka-manager.consumer.properties.file=${?CONSUMER_PROPERTIES_FILE}
bash 复制代码
vim /usr/local/cmak/cmak-3.0.0.6/conf/logback.xml
xml 复制代码
<!-- 修改后的配置(重点关注 encoder 部分的 regex 过滤) -->
<configuration>

    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${application.home}/logs/application.log</file>
        <encoder>
           <!-- 添加敏感信息过滤 -->
           <pattern>%date - [%level] - from %logger in %thread %n%replace(%message){'SASL JAAS config=.*', 'SASL JAAS config=******'}%n%xException%n</pattern>
        </encoder>

        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${application.home}/logs/application.%d{yyyy-MM-dd}.log</fileNamePattern>
            <maxHistory>5</maxHistory>
            <totalSizeCap>5GB</totalSizeCap>
        </rollingPolicy>
    </appender>

    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <!-- 添加敏感信息过滤 -->
            <pattern>%date - [%level] %logger{15} - %replace(%message){'SASL JAAS config=.*', 'SASL JAAS config=******'}%n%xException{10}</pattern>
        </encoder>
    </appender>

    <!-- 其他部分保持不变 -->
    <appender name="ASYNCFILE" class="ch.qos.logback.classic.AsyncAppender">
        <appender-ref ref="FILE" />
    </appender>

    <appender name="ASYNCSTDOUT" class="ch.qos.logback.classic.AsyncAppender">
        <appender-ref ref="STDOUT" />
    </appender>

    <logger name="play" level="INFO" />
    <logger name="application" level="INFO" />
    <logger name="kafka.manager" level="INFO" />

    <!-- Off these ones as they are annoying, and anyway we manage configuration ourself -->
    <logger name="com.avaje.ebean.config.PropertyMapLoader" level="OFF" />
    <logger name="com.avaje.ebeaninternal.server.core.XmlConfigLoader" level="OFF" />
    <logger name="com.avaje.ebeaninternal.server.lib.BackgroundThread" level="OFF" />
    <logger name="com.gargoylesoftware.htmlunit.javascript" level="OFF" />
    <logger name="org.apache.zookeeper" level="INFO"/>

    <root level="WARN">
        <appender-ref ref="ASYNCFILE" />
        <appender-ref ref="ASYNCSTDOUT" />
    </root>

</configuration>

4.3、编写启停脚本

bash 复制代码
vim /usr/local/cmak/cmak-3.0.0.6/start.sh
bash 复制代码
#!/bin/bash

JDK11_PATH="/usr/local/cmak/jdk-11.0.26"
CMAK_PATH="/usr/local/cmak/cmak-3.0.0.6"
CMAK_PORT="3283"
$CMAK_PATH/bin/cmak \
  -Dconfig.file=$CMAK_PATH/conf/application.conf \
  -java-home $JDK11_PATH \
  -Dhttp.port=$CMAK_PORT > /dev/null &
bash 复制代码
vim /usr/local/cmak/cmak-3.0.0.6/stop.sh
bash 复制代码
#!/bin/bash

CMAK_PATH="/usr/local/cmak/cmak-3.0.0.6"
ps aux | grep 'java' | grep 'cmak-3.0.0.6' | awk '{print $2}' | xargs -r kill -9
[[ -f "$CMAK_PATH/RUNNING_PID" ]] && rm -f $CMAK_PATH/RUNNING_PID
bash 复制代码
chmod +x /usr/local/cmak/cmak-3.0.0.6/{start.sh,stop.sh}

4.4、启动

bash 复制代码
sh /usr/local/cmak/cmak-3.0.0.6/start.sh

五、添加集群监控

  • 注意!是添加 zookeeper 集群

    10.73.251.66:2261,10.73.251.67:2261,10.73.251.68:2261

  • 认证配置格式

    org.apache.kafka.common.security.plain.PlainLoginModule required username="admin" password="2332***JA";

六、Kafka 启用 JMX

6.1、添加认证文件

bash 复制代码
vim /usr/local/kafka_2.13-2.8.2/config/jmxremote.access
bash 复制代码
monitorRole readonly
controlRole readwrite
bash 复制代码
vim /usr/local/kafka_2.13-2.8.2/config/jmxremote.password
bash 复制代码
monitorRole password123
controlRole password456
bash 复制代码
chmod 600 /usr/local/kafka_2.13-2.8.2/config/jmxremote.password

6.2、配置文件解释

6.2.1、jmxremote.access 文件

jmxremote.access 文件定义了哪些角色可以访问 JMX,及其访问级别。

每个角色对应不同的权限。

通过此文件,可以设置不同的角色及其对 JMX 连接的权限。

格式:

复制代码
<role> <permission>
  • role:角色名称(如 monitorRole,controlRole)。

  • permission:该角色的权限,可以是以下值之一:

  • readonly:只读权限,允许查看监控数据,但不能进行任何操作。

  • readwrite:读写权限,允许查看监控数据并执行管理操作。

示例:

复制代码
monitorRole readonly
controlRole readwrite

上面的示例表示:

  • monitorRole 角色具有只读权限,用户可以连接 JMX 进行监控,但不能进行修改或控制。

  • controlRole 角色具有读写权限,用户不仅可以进行监控,还可以修改或控制应用程序的行为(例如重启服务等)。

6.2.2、jmxremote.password 文件

jmxremote.password 文件存储了每个角色的密码。

这个文件与 jmxremote.access 文件配合使用,确保只有具有正确密码的用户才能连接到 JMX 服务。

格式:

复制代码
<role> <password>
  • role:与 jmxremote.access 文件中角色匹配。

  • password:该角色对应的密码。

示例:

复制代码
monitorRole password123
controlRole password456

上面的示例表示:

  • monitorRole 角色的密码是 password123。

  • controlRole 角色的密码是 password456。

6.2.3、配置与权限的关系

这两个文件的配合使得 JMX 访问可以进行基于角色的控制和认证:

jmxremote.access 文件用于定义权限:哪些角色能做什么操作。

jmxremote.password 文件用于定义认证:哪些角色有权访问,并提供密码来验证身份。

6.3、修改启动脚本

bash 复制代码
vim /usr/local/kafka_2.13-2.8.2/kafka_start.sh
bash 复制代码
#!/bin/bash
kafka_path="/usr/local/kafka_2.13-2.8.2"
export KAFKA_OPTS=" -Djava.security.auth.login.config=$kafka_path/config/kafka_server_jaas.conf "
$kafka_path/bin/kafka-server-start.sh $kafka_path/config/server.properties > $kafka_path/kafka_nohup.out &

改为:

  • 注意!!!注意!!!环境变量中参数前后的空格是必须的!!!
bash 复制代码
#!/bin/bash
kafka_path="/usr/local/kafka_2.13-2.8.2"

# 设置 JMX 端口和认证
export JMX_PORT=9999
export KAFKA_JMX_OPTS=" -Dcom.sun.management.jmxremote \
  -Dcom.sun.management.jmxremote.port=$JMX_PORT \
  -Dcom.sun.management.jmxremote.rmi.port=$JMX_PORT \
  -Dcom.sun.management.jmxremote.authenticate=true \
  -Dcom.sun.management.jmxremote.ssl=false \
  -Djava.rmi.server.hostname=127.0.0.1 \
  -Dcom.sun.management.jmxremote.access.file=$kafka_path/config/jmxremote.access \
  -Dcom.sun.management.jmxremote.password.file=$kafka_path/config/jmxremote.password "

export KAFKA_OPTS=" $KAFKA_JMX_OPTS -Djava.security.auth.login.config=$kafka_path/config/kafka_server_jaas.conf "

# 启动 Kafka 并将日志重定向
$kafka_path/bin/kafka-server-start.sh $kafka_path/config/server.properties >> $kafka_path/kafka_nohup.out &

6.4、重启 Kafka

bash 复制代码
netstat -lntpu | grep java | grep 9002 | awk -F '[ /]+' '{print $7}' | xargs -r kill -9
bash 复制代码
netstat -lntpu | grep java | grep 9999

七、集群监控启用 JMX

相关推荐
梦想养猫开书店16 分钟前
34、Spark实现读取XLS文件
大数据·分布式·spark
Eugene__Chen20 分钟前
java IO/NIO/AIO
java·python·nio
xixixin_34 分钟前
【uniapp】uni.setClipboardData 方法失效 bug 解决方案
java·前端·uni-app
工业互联网专业38 分钟前
基于springboot+vue的校园二手物品交易平台
java·vue.js·spring boot·毕业设计·源码·课程设计·校园二手物品交易平台
isfox1 小时前
一文拆解 Java CAS:从原理到避坑全攻略
java
JPC客栈1 小时前
LeetCode面试经典 150 题(Java题解)
java·leetcode·面试
HyperAI超神经1 小时前
【vLLM 学习】Aqlm 示例
java·开发语言·数据库·人工智能·学习·教程·vllm
异常驯兽师1 小时前
IntelliJ IDEA 项目导入后 Java 文件图标显示为红色小写 j 的解决方法
java·路径配置
纪元A梦1 小时前
华为OD机试真题——数据分类(2025A卷:100分)Java/python/JavaScript/C++/C语言/GO六种最佳实现
java·javascript·c++·python·华为od·go·华为od机试题
常年游走在bug的边缘1 小时前
基于spring boot 集成 deepseek 流式输出 的vue3使用指南
java·spring boot·后端·ai