跳至主要內容

高并发下报错 "java.net.UnknownHostException" 案例分析

Clay原创排障分析Kubernetes约 639 字大约 2 分钟

高并发下报错 "java.net.UnknownHostException" 案例分析

流量走向

错误日志

Client 报错

应用的报错日志为:java.net.UnknownHostException:

代理服务报错

查看 Nginxaccesserror 日志

tail -f xxx_dns_error.log

tail -f stream-test-udp-dns_access.log | awk '$5!=200'
# 无异常

查看操作系统日志

journalctl -f

DNS 服务端报错: 无

分析

错误关键词 Operation not permittednf_conntrack: table full, dropping packet,问题出现在 代理层,conntrack table满了。

查看当前 nf_conntrack_countnf_conntrack_max

sysctl net.netfilter.nf_conntrack_count
sysctl net.netfilter.nf_conntrack_max

确实满了, 调大呗,每次增加50% ,观察一下,直至有空闲

# 在 /etc/sysctl.conf 文件中新增一行
net.netfilter.nf_conntrack_max=[新的值]
# 应用
sysctl -p

调整完后,再次查看相关日志,发现系统日志无新报错,但是 Nginxaccesserror 日志有新的报错,接着盘他,报错如下:

error 日志

access 日志

再分析

错误关键词Resource temporarily unavailable,给的不具体啊,一步步排查吧

检查系统资源限制

# 文件描述符限制
ulimit -n
sysctl fs.file-max
# 查看已使用的文件描述符数量,这个文件显示了三个值:当前打开的文件描述符数、分配的文件描述符数(一般为0),以及系统允许的文件描述符最大值。
cat /proc/sys/fs/file-nr

# 检查进程或线程限制
ulimit -u
cat /etc/security/limits.conf
cat /etc/security/limits.d/20-nproc.conf
cat /proc/sys/kernel/pid_max
cat /proc/sys/kernel/threads-max

# 查看当前线程数
ps -eLf | wc -l

以上检查均正常。

检查网络问题

因为是 UDP 协议,所以 全连接(net.core.somaxconn)、半连接(net.ipv4.tcp_max_syn_backlog)、应用 backlog 可以忽略

查看 本地端口范围限制:

sysctl net.ipv4.ip_local_port_range
# 结果为默认配置:net.ipv4.ip_local_port_range = 32768	60999

查看观察当前 UDP 连接数:

watch -n 0.5 "ss -s | grep -i udp"

观察了一会,发现接近 28232 ,又满了,emo了

再调大呗。

# 在 /etc/sysctl.conf 文件中新增一行
net.ipv4.ip_local_port_range=1024 65535
# 应用
sysctl -p

调整完后,再次观察,应用日志、系统日志,网络均正常, 客户端访问不再报错。

Nice~~

总结:

本次高并发下,调整了两个内核参数: net.netfilter.nf_conntrack_maxnet.ipv4.ip_local_port_range

我是 Clay,下期见 👋


  • 欢迎订阅我的公众号「SRE运维进阶之路」或关注我的 Github https://github.com/clay-wangzhi/SreGuide 查看最新文章

  • 欢迎加我微信sre-k8s-ai,与我讨论云原生、稳定性相关内容

weixin