Thrift常见问题以及定位

Aache Thrift最常见的报错信息

Aache Thrift最常见的报错信息为:
No more data to read.
Called write on non-open socket.
Connection refused.
Thrfit_EAGAIN (timed out).
Interrupted system call.

借助简单的工具或者命令定位网络问题

当出现RPC报错时,可以使用ping,netstat,nc,telnet等工具或命令快速判断节点的网络状态。
netstat -anp | grep “port”可以查看到当前进程是否对指定的端口号成功监听,同时查看当前的RPC连接情况。
出现RPC报错时也可以使用nc或者telnet尝试向出现RPC报错的目的节点建立连接的方式判断,但是nc和telnet需要安装,因此还是建议使用ping和netstat。

问题定位

问题定位:No more data to read.

“No more data to read.”是最常见的Apache Thrift报错,该报错的根本原因是“连接被对端关闭”。
原因可能是:
1、列如为了降低反复开链接的开销,客户端使用了连接池,连接池里会缓存若干的空闲连接,如果连接池的连接闲置时间超过服务端的接收超时,则服务端就会将连接关闭,此后再使用该连接发送RPC则会出现“No more data to read.”的报错。
2、并发压力比较大的时候,client端connect成功,但server端由于并发压力过大并没有真正的accept,client端此时再使用这个连接进行通信,同样会出现“No more data to read.”的报错 或者 connection reset by peer。
根因分析
TCP在三次握手过程中内核会维护两个队列:
半连接队列,即SYN队列
全连接队列,即ACCEPT队列
在这里插入图片描述TCP三次握手过程中,第一次握手server收到client的syn后,内核会把该连接存储到半连接队列中,同时回复syn+ack给client(第二次握手),第三次握手时server收到client的ack,如果此时全连接队列未满,内核会把连接从半连接队列移除,并将其添加到 accept 队列,等待应用进程调用 accept 函数取出连接,如果全连接队列已满,内核的行为取决于内核参数
tcp_abort_on_overflow=0,server会丢弃client的ack。
tcp_abort_on_overflow=1,server 会发送 reset 包给 client。

可以通过调整图中内核参数规避。

问题定位:Connection refused.

“Connection refused.”出现的原因通常是RPC的服务端的进程崩溃产生。需要检查服务端的日志,确认报错的时间段服务端的进程是否为启动状态。如果长期报Connection refused且目标节点的进程状态正常的话,则需要确认如下几点:
1.确认hostname和IP映射是否正确,查看/etc/hosts文件,如果配置错误及时修改;
2.查看端口是否正确。

问题定位:No route to host.

出现No route to host报错通常意味着目标节点服务器发生了重启。但是如果在目标节点的进程已经重启正常后,仍然持续出现No route to host。
另外一种出现No route to host报错的原因是由于/etc/hosts主机名映射出错导致,此时需要细心检查全部节点的主机名映射。集群增加节点应格外注意检查,容易忘记对原有节点添加新节点的主机名映射。

问题定位:Called write on non-open socket.

出现这个报错的原因是socket连接打开失败,使用无效的连接进行send操作造成的,这种报错通过RPC的重试一般就可规避,如果持续出现此类报错,还是需要检查目标节点的进程状态、端口监听情况和主机名映射。可以充分参考“Connection refused.”的定位方法。

问题定位:Thrfit_EAGAIN (timed out)。

出现这个报错的原因是客户端接收超时,可能是由于server端的线程池任务过多造成的,需要通过grep日志查看线程池的负载情况。可以采用pstack线程ID和gcore 进程ID的方式查看堆栈。

问题定位:socket open() error:没有到主机的路由

查看目标节点和本地节点防火墙是否运行,保证防火墙关闭
CentOS 7下查看防火墙状态命令:firewall-cmd --state(可能需要root权限)
关闭防火墙:systemctl stop firewalld.service。

问题定位:write() send(): Broken pipe

原因是对端关闭了socket,client还在写,可能是因为nonblocking模式限制发送数据最大为256MB,如果超过这个数据server会报错,关闭socket。这个可以设置。

本博客是博主个人学习时的一些记录,不保证是为原创,如有侵权请与我联系。

留言即可,我会立即删除。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值