上周产品那边反馈说拉取不到2022-01-30的美团第三方账单,于是果断查了下数据库,果然发现数据库中并没有2022-01-30的美团账单记录,分别查了下29号和31号后发现都是有的,就唯独30号的没有。当时我就纳闷了,不就是一个简单的拉取第三方账单的逻辑吗?怎么就会拉取不到呢?为了能够彻底解决我的疑惑,于是我马上去阿里云查了相关拉取日志,不查不知道,一查吓一跳,没想到拉取时还果真出问题了,见下图:
将上文翻译过来不难发现,在完成从scoket中读取数据字节之前,调用InputStream块的read方法时是会阻塞的。从客户端的角度来看,如果服务器需要更长的时间来响应和发送信息,Read timed out的报错可能就会发生;从服务端的角度来看,跟预设的超时时间相比,如果服务器需要更长的时间来读取数据的话,那么Read timed out的报错可能也会发生。
-
搞懂了基本概念之后,紧接着我们需要开始排查这个错误是如何产生的。首先我从在服务端(美团)的角度思考,是不是美团那边在获取30日账单时哪个地方报错导致超时了呢?于是联系了美团的客服沟通发现它那边其实是有返回的,只不过响应时间为7点多秒让我当时感到有点惊讶。再从客户端(我)这边的角度思考,当时我想SocketTimeoutException的产生是不是就跟SocketTimeout的配置值有关呢?为了验证我的想法,于是疯狂找对应代码,居然还真给我找到了,如下图所示:
-
既然都已经把这个报错的来龙去脉都摸透了,那么接下来问题就可以迎刃而解了。我的解决方案就是把socketTimeOut这个属性弄成了nacos的配置,并设定默认值为1000ms(10秒)。这样不但解决了当前的问题,而且还可以很好地避免了以后的账单拉取时间超过了10秒后还需要修改代码重新发版的尴尬情形。相关的代码我都贴出来了,第一个代码就是获取socketTimeOut的nacos配置逻辑,第二个代码就是将获取的nacos配置值放到请求RequestConfig.Builder类中传给美团那边 大家可以看下:
private Integer getMTSocketTimeout() {
return zzNacosReader.getConfigInteger(ZzNacosConfig.THIRDPARTY_MT_SOCKET_TIMEOUT_CONFIG, 10000);
}
private static RequestConfig.Builder handleSocketTimeout(RequestConfig.Builder builder, Integer socketTimeout) {
builder.setSocketTimeout(socketTimeout);
return builder;
}
经过这么一折腾后终于将这个bug修复!希望此篇文章能给你带来启发和帮助!
参考文章: