Kafka + 使用 prometheus 与 kafka cli 命令有冲突

Posted

技术标签:

【中文标题】Kafka + 使用 prometheus 与 kafka cli 命令有冲突【英文标题】:Kafka + using prometheus have confilcts with kafka cli commands 【发布时间】:2019-12-31 15:37:07 【问题描述】:

我们使用 Prometheus 已经有一段时间了,真的很享受。

关于什么是jmx-exporter

jmx-exporter 是一个程序,它从基于 JVM 的应用程序(例如 Java 和 Scala)中读取 JMX 数据,并通过 HTTP 以 Prometheus 理解和可以抓取的简单文本格式将其公开。

那么让我们开始处理我的问题吧……

我们使用 jmx exporter 配置 kafka 如下

export KAFKA_OPTS="-javaagent:/home/jmx_prometheus_javaagent-0.11.0.jar=7071:/home/kafka-2_0_0.yml"

这个配置设置在 ambari 下 kakfa config

设置配置后,我们重新启动所有 3 个 kafka 代理

我们检查 jmx-exporter HTTP 服务器是否正在监听:

netstat -tlnp | grep 7071
tcp6       0      0 :::7071                 :::*                    LISTEN      63872/java

并抓取指标!

curl -s localhost:7071 | grep -i kafka | head
# HELP kafka_log_logcleanermanager_max_dirty_percent Attribute exposed for management (kafka.log<type=LogCleanerManager, name=max-dirty-percent><>Value)
# TYPE kafka_log_logcleanermanager_max_dirty_percent gauge
kafka_log_logcleanermanager_max_dirty_percent 0.0

直到现在一切都很酷

但是当我们开始使用 kafka 命令时,例如打印我们得到的主题列表:

/usr/hdp/current/kafka-broker/bin/kafka-topics.sh –zookeeper $zookeeper_server:2181 –list

Exception in thread "main" java.lang.reflect.InvocationTargetException
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at sun.instrument.InstrumentationImpl.loadClassAndStartAgent(InstrumentationImpl.java:386)
        at sun.instrument.InstrumentationImpl.loadClassAndCallPremain(InstrumentationImpl.java:401)
Caused by: java.net.BindException: Address already in use
        at sun.nio.ch.Net.bind0(Native Method)
        at sun.nio.ch.Net.bind(Net.java:433)
        at sun.nio.ch.Net.bind(Net.java:425)
        at sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:223)
        at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:74)
        at sun.net.httpserver.ServerImpl.bind(ServerImpl.java:133)
        at sun.net.httpserver.HttpServerImpl.bind(HttpServerImpl.java:54)
        at io.prometheus.jmx.shaded.io.prometheus.client.exporter.HTTPServer.<init>(HTTPServer.java:145)
        at io.prometheus.jmx.shaded.io.prometheus.jmx.JavaAgent.premain(JavaAgent.java:49)
        ... 6 more
FATAL ERROR in native method: processing of -javaagent failed

注意——在我们添加以下行之前:

export KAFKA_OPTS="-javaagent:/home/jmx_prometheus_javaagent-0.11.0.jar=7071:/home/kafka-2_0_0.yml "

一切正常

任何建议 – 如何从这一点开始解决这个问题?

更多参考 -

https://alex.dzyoba.com/blog/jmx-exporter

https://medium.com/@mousavi310/monitor-apache-kafka-using-grafana-and-prometheus-873c7a0005e2

【问题讨论】:

【参考方案1】:

在我找到的所有解决方案中,它帮助我将 KAFKA_OPTS 变量更改为 EXTRA_ARGS。但我仍然不明白冲突的原因。 Kafka 在一个端口上运行,javaagent 在另一个端口上运行。但是,尽管如此,在创建主题时,还是会出现错误。我用来传递 Prometheus 指标的 Javaagent

【讨论】:

【参考方案2】:

参考:https://github.com/wurstmeister/kafka-docker/wiki#why-do-kafka-tools-fail-when-jmx-is-enabled

启用 JMX 时,kafka-topics.sh 和 kafka-console-producer.sh 等工具会失败。这是由于 JMX_PORT 环境变量引起的。 Kafka 帮助程序脚本 /opt/kafka/bin/kafka-run-class.sh 将尝试在 JMX 绑定到指定端口的新 JVM 中调用所需的命令。由于已经在容器中运行的 broker JVM 绑定了这个端口,所以进程失败并退出并报错。

解决方案是在您的命令前加上 JMX_PORT= 或取消设置环境变量,即取消设置 JMX_PORT

【讨论】:

from example ( Ref ) 我可以看到 - JMX_PORT= ./kafka-console-producer.sh --broker-list localhost:9092 --topic test ,不清楚这是什么意思,例如当我们以 - /usr/hdp/current/kafka-broker/bin/kafka-topics.sh –zookeeper $zookeeper_server:2181 –list 运行 kafka cli 时,是否意味着 kafka cli 必须在 JMX_PORT 内?很奇怪,因为我们有 1000 个命令场景【参考方案3】:

您的 Kafka 实例正在侦听端口 7071 上的舞会刮擦,这似乎很好。当您发出 Kafka 命令时,您添加到 KAFKA_OPTS 的 javaagent 似乎也在尝试侦听端口 7071。不知道为什么您需要那里的 javaagent 但尝试在那里尝试不同的端口。

【讨论】:

我们也在不同的端口号上尝试过 7100 或 7101 ,但同样的问题 还有其他想法吗?【参考方案4】:

Kafka CLI 脚本使用代理正在使用的相同环境变量(特别是 KAFKA_OPTSJMX_PORT)。 这就是他们发生冲突的原因。 我正在使用融合容器(confluentinc/cp-server:5.5.1):

JMX_PORT: 9991
KAFKA_OPTS: "-javaagent:/usr/local/bin/jmx_prometheus_javaagent-0.13.0.jar=7071:/etc/jmx-exporter/kafka-2_0_0.yml"
volumes:
  - ./jmx_exporter/kafka-2_0_0.yml:/etc/jmx-exporter/kafka-2_0_0.yml
  - ./jmx_exporter/jmx_prometheus_javaagent-0.13.0.jar:/usr/local/bin/jmx_prometheus_javaagent-0.13.0.jar

很多线程只指向JMX_PORT,但这对我没有帮助。在能够运行 CLI 命令之前,我必须从容器内部取消设置两个 env var。它的工作原理如下:

unset JMX_PORT
unset KAFKA_OPTS
kafka-run-class kafka.tools.GetOffsetShell --broker-list localhost:9092 --topic your_topic

它不会破坏您的代理,因为这些变量是按会话设置的。

【讨论】:

以上是关于Kafka + 使用 prometheus 与 kafka cli 命令有冲突的主要内容,如果未能解决你的问题,请参考以下文章

与 Redis 和 Prometheus 集成

在 Rancher 上向 Prometheus 和 Grafana 公开 Kafka 指标

有没有办法配置要使用 jmx_exporter/prometheus 捕获的 kafka-connect jmx 指标?

使用 Jmx Exporter for Prometheus 缺少 Kafka Connect 指标

Prometheus 如何刮取 Kafka 主题?

读取 kafka 主题并通过 Rest API 公开数据以供 prometheus 抓取(Nodejs)