启动现象:
项目启动之后,会停留在连接kafka的地方,大约停留2分钟左右,然后报错:Topic(s) [operationLog, userAuthLog] is/are not present and missingTopicsFatal is true
19:37:49.266 [main] ERROR o.springframework.boot.SpringApplication - Application run failed
org.springframework.context.ApplicationContextException: Failed to start bean 'org.springframework.kafka.config.internalKafkaListenerEndpointRegistry'; nested exception is java.lang.IllegalStateException: Topic(s) [operationLog, userAuthLog] is/are not present and missingTopicsFatal is true
at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:185)
...省略部分异常信息...
Caused by: java.lang.IllegalStateException: Topic(s) [operationLog, userAuthLog] is/are not present and missingTopicsFatal is true
at org.springframework.kafka.listener.AbstractMessageListenerContainer.checkTopics(AbstractMessageListenerContainer.java:383)
at org.springframework.kafka.listener.ConcurrentMessageListenerContainer.doStart(ConcurrentMessageListenerContainer.java:144)
at org.springframework.kafka.listener.AbstractMessageListenerContainer.start(AbstractMessageListenerContainer.java:340)
at org.springframework.kafka.config.KafkaListenerEndpointRegistry.startIfNecessary(KafkaListenerEndpointRegistry.java:312)
at org.springframework.kafka.config.KafkaListenerEndpointRegistry.start(KafkaListenerEndpointRegistry.java:257)
at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:182)
... 14 common frames omitted
出现问题的原因:
(1)项目SpringBoot版本最近做了一次升级,用的是SpringBoot2.2.6,Kafka-client的版本比以往高,导致跟Kafka-Server不太兼容;
(2)Topic真的不存在,需要手动创建;
(3)网络端口不通;
(4)Kafka配置文件server.properties配置的对外绑定设置不对;
解决办法:
(1)升级kafka的版本,建议使用kafka-2.12_2.5.0版本;
以下是Spring官方给的说明,及版本对应关系:
Spring for Apache Kafka is based on the pure java
kafka-clients
jar. The following is the compatibility matrix:
Spring for Apache Kafka Version | Spring Integration for Apache Kafka Version | kafka-clients | Spring Boot |
---|---|---|---|
2.5.x | 3.3.x | 2.5.0 | 2.3.x |
2.4.x | 3.2.x | 2.4.1 | 2.2.x |
2.3.x | 3.2.x | 2.3.1 | 2.2.x |
2.2.x | 3.1.x | 2.0.1, 2.1.x, 2.2.x | 2.1.x |
1.3.x | 2.3.x | 0.11.0.x, 1.0.x | 1.5.x (EOL) |
IMPORTANT: This matrix is client compatibility; in most cases (since 0.10.2.0) newer clients can communicate with older brokers. All users with brokers >= 0.10.x.x (and all spring boot 1.5.x users) are recommended to use spring-kafka version 1.3.x or higher due to its simpler threading model thanks to KIP-62. For a complete discussion about client/broker compatibility, see the Kafka Compatibility Matrix
(2)手动将userAuthLog和operationLog创建出来,或者参考官方文档配置自动创建;
(3)端口检查系统防火墙,阿里云服务器检查阿里云网关开放配置;
我在这个地方可劲栽跟头了,我在定位问题的时候,直接连的一台阿里云服务器上的kafka,因为没有开阿里云端口,网络不通,就想着利用Xshell的端口转发来打通环境,事实证明,启动依然会报错,kafka不认。
(4)修改server.properties的绑定配置,其中涉及两个配置如下:
# 这个可能是默认配置
listeners=PLAINTEXT://:9092
# 另外一个配置
advertised.listeners=PLAINTEXT://hostname:9092
listeners=PLAINTEXT://:9092
- 这个参数的配置如果设置为PLAINTEXT://:9092的时候,会默认采用hostname来进行绑定,那么客户端调用的时候就会以机器的hostname来调用,这个时候就需要配置客户端和服务端的hostname了.否则可能出现下面这种报错(见最后)。
- 可以设置成0.0.0.0来支持所有的接口
advertised.listeners=PLAINTEXT://hostname:9092
- 这个就是给客户端使用的,默认是被注掉的,如果该项没有配置,那么就会采取跟listeners一样的配置。 所以如果你的kafka的连接ip假设是120.78.165.93,那么,该参数就应该设置成PLAINTEXT://120.78.165.93:9092。
- 注意,即使你的ifconfig命令查询到的ip是172.18.140.0这种,也不能写这个,要跟客户端的配置ip一致。
- 这项参数如果设置成0.0.0.0是无效的,不支持这种写法
综上,推荐的设置应该为:
listeners=PLAINTEXT://:9092
advertised.listeners=PLAINTEXT://api_ip:9092
当然很多为了方便管理,采用hostname也可以,只不过这样,服务端和客户端都得配hostname.
附hostname未正确配置时的错误:
19:30:57.164 [kafka-admin-client-thread | adminclient-1] WARN org.apache.kafka.clients.NetworkClient - [AdminClient clientId=adminclient-1] Error connecting to node xiaweifeng:9092 (id: 0 rack: null)
java.net.UnknownHostException: xiaweifeng
at java.base/java.net.InetAddress$CachedAddresses.get(InetAddress.java:797)
at java.base/java.net.InetAddress.getAllByName0(InetAddress.java:1505)
at java.base/java.net.InetAddress.getAllByName(InetAddress.java:1364)
at java.base/java.net.InetAddress.getAllByName(InetAddress.java:1298)
at org.apache.kafka.clients.ClientUtils.resolve(ClientUtils.java:104)
at org.apache.kafka.clients.ClusterConnectionStates$NodeConnectionState.currentAddress(ClusterConnectionStates.java:403)
at org.apache.kafka.clients.ClusterConnectionStates$NodeConnectionState.access$200(ClusterConnectionStates.java:363)
at org.apache.kafka.clients.ClusterConnectionStates.currentAddress(ClusterConnectionStates.java:151)
at org.apache.kafka.clients.NetworkClient.initiateConnect(NetworkClient.java:943)
at org.apache.kafka.clients.NetworkClient.ready(NetworkClient.java:288)
at org.apache.kafka.clients.admin.KafkaAdminClient$AdminClientRunnable.sendEligibleCalls(KafkaAdminClient.java:925)
at org.apache.kafka.clients.admin.KafkaAdminClient$AdminClientRunnable.run(KafkaAdminClient.java:1140)
at java.base/java.lang.Thread.run(Thread.java:834)
关注公众号[ Bug洞洞 ],一起记录学习,跳坑生活