thrift无法判断连接失效的原因与解决方案
2017-01-18 18:05
627 查看
公司的软件系统使用thrift来进行系统内部各服务的沟通调用。thrift客户端采用了连接池的方式减少连接频繁创建销毁产生的开销。连接池之前一直存在无法即时判断连接是否有效的问题。今天抽空看了下thrift的源码,分析出原因如下:
我们在程序中判断连接是否有效时,调用的是TTransport类的isOpen()函数
一路调试跟踪查看TTransport的isOpen()源码,得到如下:
即最终调用的是jdk中 Socket类的isConnected()方法
根据源码中的英文注释内容及网上的资料,得出答案:isConnected方法得到的并不是Socket的当前连接状态,而是只要是Socket连接曾经成功过,isConnected始终返回true。
Thrift并没有提供一个可以获取当前连接状态的方法。
之前连接池的解决方案是:在当前远程调用操作失败后,将失败状态写入当前客户端类变量,下次校验时,查看此变量,获取连接状态,销毁重连。这样导致的结果是异常连接总会失败一次,当连接池中缓存的异常连接过多,就会造成过多的业务请求失败,且单独服务的重启操作需要也重启依赖此服务的程序,避免失败,很麻烦。
这次采用的解决方案为:各个服务thrift服务端统一新增一接口函数,名为ping()(或其他名称),ping()函数中什么也不操作。这样连接池在校验连接时,统一调用各服务的ping()即可精确得知连接状态(调用ping()失败即连接异常,调用成功即连接正常)。由于ping()为空,不进行任务业务操作,对服务端造成的压力也会很小。
我们在程序中判断连接是否有效时,调用的是TTransport类的isOpen()函数
一路调试跟踪查看TTransport的isOpen()源码,得到如下:
即最终调用的是jdk中 Socket类的isConnected()方法
根据源码中的英文注释内容及网上的资料,得出答案:isConnected方法得到的并不是Socket的当前连接状态,而是只要是Socket连接曾经成功过,isConnected始终返回true。
Thrift并没有提供一个可以获取当前连接状态的方法。
之前连接池的解决方案是:在当前远程调用操作失败后,将失败状态写入当前客户端类变量,下次校验时,查看此变量,获取连接状态,销毁重连。这样导致的结果是异常连接总会失败一次,当连接池中缓存的异常连接过多,就会造成过多的业务请求失败,且单独服务的重启操作需要也重启依赖此服务的程序,避免失败,很麻烦。
这次采用的解决方案为:各个服务thrift服务端统一新增一接口函数,名为ping()(或其他名称),ping()函数中什么也不操作。这样连接池在校验连接时,统一调用各服务的ping()即可精确得知连接状态(调用ping()失败即连接异常,调用成功即连接正常)。由于ping()为空,不进行任务业务操作,对服务端造成的压力也会很小。
相关文章推荐
- python wsdl connection refused 111
- 常用位操作2
- linux小白 折腾debian8笔记1 --Debian 8 安装与初步配置
- 远程重装mac系统
- 线程死锁例子
- OVER(PARTITION BY)函数介绍
- 并发和并行
- 行者企业家天授唱诗人或是后互联网小鲜肉-2017年1月江西IDC排行榜与发展报告
- Restful架构
- android-activity生命周期学习
- 使用 Angular 2 开发单页应用程序之一
- JavaEE JDBC RowSet行集
- 计算器修正代码
- 教你怎样维修内存条
- 飞塔100D添加地址保留的两种方法
- Android开发工具类--NetUtils
- 进程控制(上):进程创建,进程等待,进程终止
- 反向传导算法 推导
- sql取出商品表每个类别的前3条记录
- JESD79-4 第4章 SDRAM命令描述与操作(4.5-4.7)