出现问题:
1.Too many open files
2.java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread
3.Attempting to send response via channel for which there is no open connection, connection id
把ulimit 调成 1024 后 发起大量消费者/生产者请求后重现现此两个问题。
WRNING:Attempting tosendresponse via channelforwhich there isnoopenconnection, connection id ERROR Errorwhileaccepting connection (kafka.network.Acceptor)java.io.IOException: Too manyopenfiles
可以确定如果有大量的连接被创建,可能会发生此种情况。
谷歌搜索大概解释如下:
1.每次连接会创建一定数据量的句柄(具体未知),大量连接被创建,因连接未释放,将产生大量的占用的文件句柄,超过ulimit 限制后会产生错误:java.io.IOException: Too many open files
2.如果太快重新连接, 响应未完成时重新连接,broker将未完成的响应发送到具有重用端口的新连接。新连接将以相关标识(connection id )不匹配结束,会出现WRNING:Attempting to send response via channel for which there is no open connection
在保证测试程序仍然一直尝试不断连接的前提下:
手动修改
ulimit-SHn 65535
重启 kafka,
broker 出现报错并shutdown.
FATAL Fatal error during KafkaServerStartable startup.Preparetoshutdown(kafka.server.KafkaServerStartable)org.I0Itec.zkclient.exception.ZkTimeoutException: Unabletoconnecttozookeeperserver'localhost:2181'withtimeoutof6000ms
查看 zookeeper 进程存在并且已启动。
将zookeeper 的JVM分配内存修改为1G。
kafka成功启动
但出现如下错误:
Errorinfetch kafka.server.ReplicaFetcherThread$FetchRequest@34ba0f3f (kafka.server.ReplicaFetcherThread)java.io.IOException: Connection to172.16.2.85:9093(id:0rack:null) failed
以及
WRNING:Attempting tosendresponse via channelforwhich there isnoopenconnection
其他程序依然无法连接kafka
lsof -n|awk'{print $2}'|sort|uniq -c|sort-nr |grep19652
查看kafka进程 占用句柄在不断增加, 即 尝试重连的测试程序在不断发起连接请求。
等待几分钟后,日志恢复正常,但依然无法连接.
把其他python 程序 中的socket超时配置
socket_timeout_ms=1000,offsets_channel_socket_timeout_ms=1000
去掉,
使用默认的超时时间。
其他程序 在一次连接失败后,第二次有几秒的缓慢后连接上了kafka ,并正常使用。
由此可以得知,在测试程序继续不断发起大量请求的情况下, 将影响后续程序的连接。
杀掉测试程序后,其他程序即可迅速连上kafka。
修改 测试程序中的socket超时配置,使用默认超时时间。
重新启动 测试程序,4个消费者程序和1和生产者程序(400消费者线程/100生产者线程)。
100 生产者均可迅速启动,前200消费着也是迅速启动,后200启动有几秒的缓慢并有部分连接失败后尝试重新连接,但最终全部都正常启动,生产和消费数据。
kafka日志正常,偶然会出现 两个WARNING:
Attempting tosendresponse via channelforwhich there isnoopenconnection
以及
FailedtosendSSLClosemessage(org.apache.kafka.common.network.SslTransportLayer)
但不影响程序运行。
关闭测试程序和kafka, 重新启动kafka, 从日志看出 kafka进程正在处理 由于 被杀死进程 后尚未处理关闭的 连接。
重新启动测试程序,Attempting to send response via channel for which there is no open connection 的警告不再出现。
偶然仍出出现 Failed to send SSL Close message (org.apache.kafka.common.network.SslTransportLayer) 的警告。
Exception: java.lang.OutOfMemoryError thrownfromthe UncaughtExceptionHandlerinthread"kafka-network-thread-0-ListenerName(PLAINTEXT)-PLAINTEXT-8"
这个告警在测试过程中未能复现, 谷歌搜索 是由于 JVM 分配内存问题, 修改 启动 zookeeper 和kafka-server(broker) 的脚本,zookeeper 分配1G, broker 分配 2G。
重新启动kafka进程。
在杀掉并启动的过程中出现WARNING :
WARN Session 0x0 for server null, unexpected error, closing socket connection and attempting reconnect
kafka-server(broker) 启动失败。
出现 ZkTimeoutException 错误,kafka-server(broker)连接 zookeeper 超时,
修改 配置文件 zookeeper.connection.timeout.ms=60000(默认为6000)
即在大量请求连接发送到kafka时,broker 和 zookeeper 之间的连接会变慢。(少量连接的情况下可以正常杀掉并重启)。
在杀掉进程后, 删除/tmp下的临时文件(也可以不删), 则可以在 有大量尝试发送重连请求的时候 重启 kafka.
启动脚本:
ps aux |grep'kafka_2.11-0.10.2.0'|grep-vgrep| awk'{print $2}'| xargskill-9sleep5nohup /usr/local/bluedon/kafka_2.11-0.10.2.0/bin/zookeeper-server-start.sh /usr/local/bluedon/kafka_2.11-0.10.2.0/config/zookeeper.properties >/usr/local/bluedon/kafka_2.11-0.10.2.0/logs/zookeeper_run.log &sleep5nohup /usr/local/bluedon/kafka_2.11-0.10.2.0/bin/kafka-server-start.sh /usr/local/bluedon/kafka_2.11-0.10.2.0/config/server.properties >/usr/local/bluedon/kafka_2.11-0.10.2.0/logs/server_run.log &sleep5nohup /usr/local/bluedon/kafka_2.11-0.10.2.0/bin/kafka-server-start.sh /usr/local/bluedon/kafka_2.11-0.10.2.0/config/server-1.properties >/usr/local/bluedon/kafka_2.11-0.10.2.0/logs/server-1_run.log &sleep5nohup /usr/local/bluedon/kafka_2.11-0.10.2.0/bin/kafka-server-start.sh /usr/local/bluedon/kafka_2.11-0.10.2.0/config/server-2.properties >/usr/local/bluedon/kafka_2.11-0.10.2.0/logs/server-2_run.log &
总结:
这次kafka无法连接是由于程序连接时,指定的socket 超时时间太短(1s),程序在1s内无法连接kafka或者无法生产消费即尝试重新连接, 在连接的过程中可能会再次出现1s内无法连接的情况,因此产生大量的连接/关闭请求, 每次连接会产生一定数量的文件句柄, 系统ulimit值太低(1024),请求不断积压后最终产生 Too many open files错误,由于太多以及太快重新连接, 响应未完成时重新连接,broker将未完成的响应发送到具有重用端口的新连接,最终产生 Attempting to send response via channel警告。
修改:
1.修改 系统 ulimit 值:
ulimit -SHn 65535
修改linux的软硬件限制文件/etc/security/limits.conf.
在文件尾部添加如下代码:
soft nofile 102400
hard nofile 102400
4)经过以上修改,在有些系统中,用一般用户再登陆,仍然没有修改过来,那么需要检查是否有如下文件,如果没有,则要添加如下内容:
#vim /etc/pam.d/sshd[Add the line]session required /lib/security/pam_limits.so# service sshd restart
2.修改python 程序 中 consumer 的socket 超时时间
client= KafkaClient(hosts=kafka_config['bootstrap_servers'], ssl_config=ssl_config, socket_timeout_ms=1000, offsets_channel_socket_timeout_ms=1000)修改为 client = KafkaClient(hosts=kafka_config['bootstrap_servers'], ssl_config=ssl_config)即使用默认的3分钟
修改 在程序启动 的时候指定 ulimit 值,不受系统设置限制
ps aux |grep'kafka_2.11-0.10.2.0'|grep-vgrep| awk'{print $2}'| xargskill-9sleep5nohup sh -c"ulimit -SHn 65535 && /usr/local/bluedon/kafka_2.11-0.10.2.0/bin/zookeeper-server-start.sh /usr/local/bluedon/kafka_2.11-0.10.2.0/config/zookeeper.properties">/usr/local/bluedon/kafka_2.11-0.10.2.0/logs/zookeeper_run.log &sleep5nohup sh -c"ulimit -SHn 65535 && /usr/local/bluedon/kafka_2.11-0.10.2.0/bin/kafka-server-start.sh /usr/local/bluedon/kafka_2.11-0.10.2.0/config/server.properties">/usr/local/bluedon/kafka_2.11-0.10.2.0/logs/server_run.log &sleep5nohup sh -c"ulimit -SHn 65535 && /usr/local/bluedon/kafka_2.11-0.10.2.0/bin/kafka-server-start.sh /usr/local/bluedon/kafka_2.11-0.10.2.0/config/server-1.properties">/usr/local/bluedon/kafka_2.11-0.10.2.0/logs/server-1_run.log &sleep5nohup sh -c"ulimit -SHn 65535 && /usr/local/bluedon/kafka_2.11-0.10.2.0/bin/kafka-server-start.sh /usr/local/bluedon/kafka_2.11-0.10.2.0/config/server-2.properties">/usr/local/bluedon/kafka_2.11-0.10.2.0/logs/server-2_run.log &
其他:
ps aux |grepkafka |grep-vgrep| awk'{print $2}
进程所占句柄数
lsof-n|awk'{print$2}'|sort|uniq -c|sort -nr
取出占用端口的进程号
netstat-tnlp | grep2181| awk'{print$7}'| awk -F'/''{print$1}'