kafka-manager介绍
kafka-manager是目前最受欢迎的kafka集群管理工具,最早由雅虎开源,用户可以在Web界面执行一些简单的集群管理操作。
之前叫kafka-manager,现在改名叫CMAK(Cluster Manager for Apache Kafka)了。
具体支持以下内容:
- 管理多个集群
- 轻松检查群集状态(主题,消费者,偏移,代理,副本分发,分区分发)
- 运行首选副本选举
- 使用选项生成分区分配以选择要使用的代理
- 运行分区重新分配(基于生成的分配)
- 使用可选主题配置创建主题(0.8.1.1具有与0.8.2+不同的配置)
- 删除主题(仅支持0.8.2+并记住在代理配置中设置delete.topic.enable = true)
- 主题列表现在指示标记为删除的主题(仅支持0.8.2+)
- 批量生成多个主题的分区分配,并可选择要使用的代理
- 批量运行重新分配多个主题的分区
- 将分区添加到现有主题
- 更新现有主题的配置
kafka-manager安装
kafka-manager 3.0.0.2 以下版本官方只支持源码编译安装。
kafka-manager 3.0.0.2 及以上版本官方提供给了编译包,但要求环境为 jdk11及以上。
本文将以 3.0.0.2 以下的最高版本 3.0.0.1 介绍编译安装方式,3.0.0.2 及以上使用编译包直接部署即可。
组件安装操作步骤参考 组件安装部署手册模板,根据不同组件的安装目标,部分操作可以省略。
本文将按照该参考步骤执行。
一、获取组件可执行程序库,包括主程序,此为组件的基本文件
1.官网下载 kafka-manager源码
创建目录 /usr/local/kafka-manager,将源码包下载到该目录下,支持wget获取。
特别关注:官方release分支只有3.0.0.2及以上版本,所以需要在 tag 分支下载。
2.安装依赖组件
kafka-manager依赖sbt编译,需要先安装sbt。
其中,kafka-manager源码路径中,已经集成了sbt程序,所以无需单独安装。
如果确实需要安装特定版本sbt,则可以参考 sbt组件安装(CentOS7)
3.sbt编译
特别关注:sbt编译过程中需要下载很多依赖包,官方仓库下载效率很低,建议修改sbt仓库地址
3.1 修改仓库地址,以阿里云仓库为例
[root@localhost kafka-manager]# vim ~/.sbt/repositories #内容如下 [repositories] #local public: http://maven.aliyun.com/nexus/content/groups/public/ typesafe:http://dl.bintray.com/typesafe/ivy-releases/ , [organization]/[module]/(scala_[scalaVersion]/)(sbt_[sbtVersion]/)[revision]/[type]s/[artifact](-[classifier]).[ext], bootOnly ivy-sbt-plugin:http://dl.bintray.com/sbt/sbt-plugin-releases/, [organization]/[module]/(scala_[scalaVersion]/)(sbt_[sbtVersion]/)[revision]/[type]s/[artifact](-[classifier]).[ext] sonatype-oss-releases sonatype-oss-snapshots
3.2 编译
[root@localhost kafka-manager]# tar -zxvf CMAK-3.0.0.1.tar.gz [root@localhost kafka-manager]# cd CMAK-3.0.0.1/ [root@localhost CMAK-3.0.0.1]# ll 总用量 56 drwxrwxr-x 9 root root 109 2月 20 2020 app -rw-rw-r-- 1 root root 4373 2月 20 2020 build.sbt drwxrwxr-x 2 root root 108 2月 20 2020 conf drwxrwxr-x 2 root root 156 2月 20 2020 img -rw-rw-r-- 1 root root 11307 2月 20 2020 LICENSE drwxrwxr-x 2 root root 49 2月 20 2020 project drwxrwxr-x 5 root root 54 2月 20 2020 public -rw-rw-r-- 1 root root 9572 2月 20 2020 README.md -rwxrwxr-x 1 root root 20971 2月 20 2020 sbt drwxrwxr-x 4 root root 37 2月 20 2020 src drwxrwxr-x 5 root root 51 2月 20 2020 test #自带sbt环境 [root@localhost CMAK-3.0.0.1]# ./sbt clean dist #独立安装sbt环境 [root@localhost CMAK-3.0.0.1]# sbt clean dist
编译过程很长,因为要下载很多依赖包,成功后会在 target/universal/ 目录下生成一个可用于部署的 zip文件,解压到指定目录即可,如 /usr/local/kafka-manager/3.0.0.1。
特别关注:由于sbt编译过程非常耗时,建议大家下载编译好的安装包来运行
- 官方安装包,3.0.0.2及以上版本,需要jdk11支持
- 网络资源,即网友编译好的安装包,请自行查找,附较低版本 2.0.0.2:链接:https://pan.baidu.com/s/1fiQvM1rbt5cwtEtl45vwMA 提取码:hh4w
特别关注:经验证,2022年开始,国内sbt环境编译成功率几乎为0,强烈建议下载编译好的安装包,否则浪费太多时间和精力。
二、安装系统服务
kafka-manager默认没有安装系统服务,通过主程序运行。
三、主程序加入到环境变量
根据实际需要评估是否需要加入环境变量
[root@localhost ~]# vim /etc/profile #kafka-manager env export KAFKA_MANAGER_HOME=/usr/local/kafka-manager/3.0.0.1 export PATH=$PATH:$KAFKA_MANAGER_HOME/bin [root@localhost ~]# source /etc/profile
四、配置文件
配置kafka-manager连接的zk集群地址
[root@localhost 3.0.0.1]# vim conf/application.conf 修改内容如下,注释其他zk配置项,如kafka-manager.zkhosts cmak.zkhosts="192.168.11.63:8181,192.168.11.66:8181,192.168.11.72:8181"
五、运行用户
默认使用root运行即可。
六、开机启动
请参考教程 Linux开机启动方案
七、服务启动运行
以主程序运行为例(已经将主目录添加环境变量)
1.启动
kafka-manager默认使用9000端口,可以使用-Dhttp.port指定端口
[root@localhost 3.0.0.1]# nohup bin/cmak -Dconfig.file=conf/application.conf -Dhttp.port=9002 >/dev/null 2>&1 &
2.验证
访问本机9002端口
3.kafka-manager详细使用,请参考教程 详细解析 kafka manager 的使用
4.停止kafka-manager
停止kafka-manager可以使用停止进程的方式 kill -9 pid,但是停止进程后,需要删除安装目录下的 RUNNING_PID 文件,其中记录着上次运行的进程号,如果不删除,下次启动时会首先检测是否存在 RUNNING_PID 文件,存在则继续提示启动异常
#定位进程,可以通过进程名称,也可以通过监听端口号 [root@localhost cmak-3.0.0.1]# ps -ef | grep kafka-manager [root@localhost cmak-3.0.0.1]# ps -ef | grep cmak [root@localhost cmak-3.0.0.1]# netstat -lntup | grep 9002 tcp6 0 0 :::9002 :::* LISTEN 3051/java #停止进程 [root@localhost cmak-3.0.0.1]# kill -9 3051 #删除PID文件 [root@localhost cmak-3.0.0.1]# rm -f RUNNING_PID
特别关注:关于kafka 与 kafka-manager
kafka-manager监控问题
如果kafka部署的是集群(多于一台),则可能会遇到kafka-manager监控kafka broker数据异常问题,比如只有一台broker显示有数据,其他broker无数据,如下
正常情况下应该是如下效果
问题分析
kafka-manager监控流程
kafka-manager通过jmx + rmi技术实现kafka监控,大致流程如下
根据以上流程,第4步操作可能会有如下问题
- kafka broker默认通过localhost解析 rmi ip 地址,所以会返回127.0.0.1,所以如果kafka broker与kafka-manager不在同一台服务器上,则无法连接
- kafka broker默认返回随机 rmi 端口,如果需要配置防火墙,则无法预测随机端口范围
所以,解决以上问题,就需要实现kafka broker返回指定的rmi ip与端口。
解决方案方案探讨
尝试一
首先,可能大家会想到通过修改服务器 /etc/hosts文件,将127.0.0.1改为本机ip地址,这样在broker解析localhost时,将返回实际ip地址。此方案确实可以解决rmi ip的问题,同时配合关闭防火墙,经验证可以实现kafka-manager正常监控kafka。只是需要考虑以下注意事项
- 将本机localhost解析改为实际ip地址,需要评估同服务器上其他应用服务或组件是否受影响,有些服务可能需要使用127.0.0.1
- hosts无法解决rmi端口随机的问题,如果运维环境要求开启防火墙,将无法满足要求
尝试二
接下来我们从kafka自身运行原理分析解决方案。
kafka启动过程中,通过 kafka-server-start.sh 调用 kafka-run-class.sh。
1.分析kafka启动脚本 kafka-server-start.sh
可以在此处设置相关参数的值,并在启动 kafka-run-class.sh 时传入
...省略其他配置... if [ "x$KAFKA_LOG4J_OPTS" = "x" ]; then export KAFKA_LOG4J_OPTS="-Dlog4j.configuration=file:$base_dir/../config/log4j.properties" fi if [ "x$KAFKA_HEAP_OPTS" = "x" ]; then export KAFKA_HEAP_OPTS="-Xmx1G -Xms1G" fi ...省略其他配置... exec $base_dir/kafka-run-class.sh $EXTRA_ARGS kafka.Kafka "$@"
2.分析kafka启动脚本kafka-run-class.sh
kafka在 kafka-run-class.sh 中设置了 $JMX_PORT 参数,允许在kafka启动前配置,最后在启动kafka程序时,将拼接好的参数作为java启动参数传入。
其中,参数可以通过多种途径配置,如下
- 环境变量 /etc/profile
- kafka启动脚本 kafka-server-start.sh内部
- kafka启动时动态指定 JMX_PORT=9999 bin/kafka-server-start.sh -daemon config/server.properties
...省略其他配置... # JMX settings if [ -z "$KAFKA_JMX_OPTS" ]; then KAFKA_JMX_OPTS="-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false " fi # JMX port to use if [ $JMX_PORT ]; then KAFKA_JMX_OPTS="$KAFKA_JMX_OPTS -Dcom.sun.management.jmxremote.port=$JMX_PORT " fi ...省略其他配置... # Launch mode if [ "x$DAEMON_MODE" = "xtrue" ]; then nohup "$JAVA" $KAFKA_HEAP_OPTS $KAFKA_JVM_PERFORMANCE_OPTS $KAFKA_GC_LOG_OPTS $KAFKA_JMX_OPTS $KAFKA_LOG4J_OPTS -cp "$CLASSPATH" $KAFKA_OPTS "$@" > "$CONSOLE_OUTPUT_FILE" 2>&1 < /dev/null & else exec "$JAVA" $KAFKA_HEAP_OPTS $KAFKA_JVM_PERFORMANCE_OPTS $KAFKA_GC_LOG_OPTS $KAFKA_JMX_OPTS $KAFKA_LOG4J_OPTS -cp "$CLASSPATH" $KAFKA_OPTS "$@" fi
3.kafka-run-class.sh并未设置关于 rmi 的相关参数
解决方案总结
总结以上分析,考虑到jmx端口、rmi ip、rmi 端口需要同时支持配置,推荐使用kafka启动脚本调整的方案。
具体方案参考如下
方案一:调整kafka-run-class.sh
1.在kafka-run-class.sh中增加rmi参数,如下
...省略其他配置... # JMX settings if [ -z "$KAFKA_JMX_OPTS" ]; then KAFKA_JMX_OPTS="-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false " fi # JMX port to use if [ $JMX_PORT ]; then KAFKA_JMX_OPTS="$KAFKA_JMX_OPTS -Dcom.sun.management.jmxremote.port=$JMX_PORT " fi # RMI host to use # RMI与JMX原则上属于不同技术,应该重新设计参数变量,如KAFKA_RMI_OPTS,此处共用KAFKA_JMX_OPTS,避免修改最终Java执行参数 if [ $RMI_HOST ]; then KAFKA_JMX_OPTS="$KAFKA_JMX_OPTS -Djava.rmi.server.hostname=$RMI_HOST " fi # RMI port to use # RMI与JMX原则上属于不同技术,应该重新设计参数变量,如KAFKA_RMI_OPTS,此处共用KAFKA_JMX_OPTS,避免修改最终Java执行参数 if [ $RMI_PORT ]; then KAFKA_JMX_OPTS="$KAFKA_JMX_OPTS -Dcom.sun.management.jmxremote.rmi.port=$RMI_PORT " fi ...省略其他配置...
2.参数可以通过多种途径配置,如下
- 环境变量 /etc/profile
- kafka启动脚本 kafka-server-start.sh内部
- kafka启动时动态指定
方案二:不调整kafka-run-class.sh
1.保持kafka-server-start.sh与kafka-run-class.sh默认
2.通过多种途径配置完整的KAFKA_JMX_OPTS,如下
- 环境变量 /etc/profile
- kafka启动脚本 kafka-server-start.sh内部
- kafka启动时动态指定
其中,KAFKA_JMX_OPTS完整参数集合为
export KAFKA_JMX_OPTS="-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.port=9999 -Djava.rmi.server.hostname=192.168.11.72 -Dcom.sun.management.jmxremote.rmi.port=9998"
特别关注:需要根据实际运维环境确认选择何种方案,没有最好的方案,只有最合适的方案。
特别关注:
如果没有配置 -Dcom.sun.management.jmxremote.authenticate=false,则启动kafka时会提示jmx权限问题,启动失败
错误: 找不到口令文件: /usr/local/jdk_8/jdk1.8.0_201/jre/lib/management/jmxremote.password
特别关注:
如果使用环境变量(/etc/profile)全局配置方案,会影响控制台生产者(kafka-console-producer.sh)、消费者(kafka-console-consumer.sh)工具的使用,因为在这2个工具的启动脚本中,也会调用 kafka-run-class.sh ,即也会使用全局配置,监听JMX端口、RMI端口,然后报【端口已占用】异常。
以控制台消费者脚本为例,如下
[root@localhost bin]# cat kafka-console-consumer.sh #!/bin/bash if [ "x$KAFKA_HEAP_OPTS" = "x" ]; then export KAFKA_HEAP_OPTS="-Xmx512M" fi exec $(dirname $0)/kafka-run-class.sh kafka.tools.ConsoleConsumer "$@"