在云服务器上安装配置Kafka遇到的问题及解决方案

在学习Kafka,准备在服务器上搭一个使用Kafka的项目。对服务器的使用不是很熟练,在安装使用Kafka的时候遇到了一些问题,记录下来。

服务器情况

腾讯云,标准型S2,1核,1GB,1Mbps,操作系统 CentOS 7.6 64位,坐标香港

其实我之前买过阿里云的服务器,但是当时选的服务器位置在境内,由于工信部要求如果要在境内服务器上部署网站需要备案,现在我在香港,就各种不方便。因此另外买了一台香港的服务器,刚好腾讯十周年活动,腾讯云的香港服务器比其他几家大厂都便宜得多,于是选了腾讯云的。但是毕竟是境外的服务器,比境内的还是要贵,所以选的是1核1G的,想了想穷学生学习应该也够,结果就遇上问题了orz

Kafka运行内存不足问题

在安装好Kafka准备启动的时候,报如下错误

1
2
3
4
5
6
7
8
[root@VM-0-6-centos kafka_2.11-2.4.0]# bin/kafka-server-start.sh config/server.properties &
[1] 5158
[root@VM-0-6-centos kafka_2.11-2.4.0]# Java HotSpot(TM) 64-Bit Server VM warning: INFO: os::commit_memory(0x00000000c0000000, 1073741824, 0) failed; error='Cannot allocate memory' (errno=12)
#
# There is insufficient memory for the Java Runtime Environment to continue.
# Native memory allocation (mmap) failed to map 1073741824 bytes for committing reserved memory.
# An error report file with more information is saved as:
# /opt/install/kafka_2.11-2.4.0/hs_err_pid5158.log

看报错情况应该是内存不足,果然1G还是有点小,但没办法只能修改配置了。

修改启动脚本,Kafka安装目录下:/bin/kafka-server-start.sh

修改 export KAFKA_HEAP_OPTS="-Xmx1G -Xms1G"

export KAFKA_HEAP_OPTS="-Xmx256M -Xms128M"

(也可以修改为其它合适的大小)

ip地址绑定错误问题

启动Kafka的时候报如下错误

kafka.common.KafkaException: Socket server failed to bind to xx:9092: Cannot assign requested address

解决方法参考:https://qii404.me/2018/02/02/kafka-cluster.html

该情况下的虚拟机对外ip(暴露的ip,也就是服务器提供的公网ip)和真实ip(ifconfig显示的ip,也就是服务器提供的内网ip)可能只是映射关系,用户访问对外ip时,OpenStack会转发到对应的真实ip实现访问。但此时如果 server.properties

1
2
3
listeners=PLAINTEXT://xxx.xxx.xxx.xxx:9092  

advertised.listeners=PLAINTEXT://xxx.xxx.xxx.xxx:9092

中的ip配置为(对外ip)的时候无法启动,socket无法绑定监听

解决方法也很简单,将ip改为真实ip(ifconfig中显示的ip,也就是内网ip)即可,其他使用时正常使用对外ip即可,跟真实ip就没有关系了。

上述改完Kafka就能成功启动了,但会出现下一个问题。

Kafka连接服务器出现”Connection to node 1 (localhost/127.0.0.1:9092) could not be established”

在Kafka成功启动后,启动项目项目,会报这个错误。

在本地测试的时候安装运行好Kafka后就能成功运行项目了,但是放到服务器上就报错了。从错误信息可以看到,SpringBoot开启后连接的是127.0.0.1,也就是本地的Kafka broker,但是配置文件中配置的是服务器的IP地址。

先来一点点排查错误。

安全组是否开放&防火墙是否拦截请求

一般数据库或Redis连接不可用,都有可能是安全组没有开放或者防火墙拦截了外来连接导致。登陆腾讯云服务器管理台后发现,9092端口和2181端口都是开放的,说明腾讯云这边并没有关闭了Kafka和Zookeeper的外部连接权限,那么尝试下端口扫描,发现这两个端口依然可以被外部访问。

登陆服务器查看Kafka broker是否可用

1
2
3
4
5
[root@VM-0-6-centos wechat_template]# lsof -i:9092
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
java 26077 root 123u IPv6 501530 0t0 TCP VM-0-6-centos:XmlIpcRegSvc (LISTEN)
java 26077 root 139u IPv6 501545 0t0 TCP VM-0-6-centos:43702->VM-0-6-centos:XmlIpcRegSvc (ESTABLISHED)
java 26077 root 140u IPv6 501546 0t0 TCP VM-0-6-centos:XmlIpcRegSvc->VM-0-6-centos:43702 (ESTABLISHED)

通过查询Kafka broker默认端口9092发现,服务运行状态良好,排除掉服务下线的可能性。

查看Kafka运行日志

1
2
3
4
5
6
7
8
9
10
11
[root@VM-0-6-centos kafka_2.11-2.4.0]# tail -f logs/server.log
[2020-08-26 14:47:04,804] INFO [TransactionCoordinator id=0] Starting up. (kafka.coordinator.transaction.TransactionCoordinator)
[2020-08-26 14:47:04,876] INFO [TransactionCoordinator id=0] Startup complete. (kafka.coordinator.transaction.TransactionCoordinator)
[2020-08-26 14:47:04,930] INFO [Transaction Marker Channel Manager 0]: Starting (kafka.coordinator.transaction.TransactionMarkerChannelManager)
[2020-08-26 14:47:04,998] INFO [ExpirationReaper-0-AlterAcls]: Starting (kafka.server.DelayedOperationPurgatory$ExpiredOperationReaper)
[2020-08-26 14:47:05,046] INFO [/config/changes-event-process-thread]: Starting (kafka.common.ZkNodeChangeNotificationListener$ChangeEventProcessThread)
[2020-08-26 14:47:05,093] INFO [SocketServer brokerId=0] Started data-plane processors for 1 acceptors (kafka.network.SocketServer)
[2020-08-26 14:47:05,095] INFO Kafka version: 2.4.0 (org.apache.kafka.common.utils.AppInfoParser)
[2020-08-26 14:47:05,095] INFO Kafka commitId: 77a89fcf8d7fa018 (org.apache.kafka.common.utils.AppInfoParser)
[2020-08-26 14:47:05,095] INFO Kafka startTimeMs: 1598424425093 (org.apache.kafka.common.utils.AppInfoParser)
[2020-08-26 14:47:05,096] INFO [KafkaServer id=0] started (kafka.server.KafkaServer)

运行状态良好,没有出现WARNERROR信息,从日志看不出问题。

网上找资料

没能力找到问题所在,那么问问google,总有一些解决问题的方式,虽然并不一定能直接解决问题,但是在查找问题的过程中还是能学到很多,例如这篇博客也提到了Kafka外网连接问题,但按照这个方式修改后并不能解决我的问题:

kafka连接问题

这里面提到了一个很重要的概念:

kafka启动后会在zookeeper的/brokers/ids下注册监听协议,包括IP和端口号,客户端连接的时候,会取得这个IP和端口号。
后来查看了kafka的配置,原来我忽视了listeners和advertised.listeners的区别,advertised.listeners才是真正暴露给外部使用的连接地址,会写入到zookeeper节点中的。于是再次进行修改,把IP配置到advertised.listeners中,问题再一次解决。

advertised.listeners才是真正的对外代理地址!
那么listeners的作用就不是对外提供服务代理,而是监听!

解决问题

修改server.properties的两行默认配置:

1
2
3
4
# 允许外部端口连接                                            
listeners=PLAINTEXT://0.0.0.0:9092
# 外部代理地址(如已修改为真实ip,也就是服务器的内网ip,则不变)
advertised.listeners=PLAINTEXT://xxx.xxx.xxx.xxx:9092

评论