前情提要:

      我们是一个2B服务的O2O家装平台,大部分安装订单来自于天猫等在线交易平台,即通过和天猫对接接口获取商家安装需求订单。

    技术方案:

      由于天猫的接口限制,这类企业级的接口api都只能在天猫的聚石塔内部调用,不允许外部机器调用,所以我们采用从聚石塔实时获取数据(本地有备份记录,同时有纠错重试机制),将数据异步同步到订单调度系统, 通过订单调度程序生成真正的服务单。

     这样做的目的主要是为了流量削峰,聚石塔只承担一个数据透传的职责,真正的逻辑处理通过订单调度服务端完成计算。

1、如果聚石塔大量订单涌入,可以通过扩展订单调度服务端来完成扩展,就类似三峡大坝,据说能抗洪!

2、如果未来加入其他的在线平台,也统一走订单调度服务端。

3、订单调度服务端做了持久存储,所以只要接口有透传数据过来,通过重试补偿等机制能保证数据不丢失。

   问题现象:

     2017年9月27日 15:00分后,订单调度服务器再也没有收到聚石塔的透传订单(在订单的处理节点我们做了监控,如果连续多次处理来源订单为0,会告警并邮件通知到干系人)。

    排查过程:

   1、确保订单调度服务器能正常接收订单,通过模拟注入订单测试——正常。

    2、确保聚石塔服务器能正常处理api接口,并透传订单. 我通过阿里云的控制台登录服务器,通过监控画面能正常看到消费订单,并产生了来源订单记录,看起来一切正常。

 翻看聚石塔日志,远程通讯记录没有,问题就在这里了。

       通过聚石塔curl 模拟提交数据到订单调度服务器,居然一切正常。

       查看tomcat应用,能正常响应数据处理,也一切正常。

       登录数据库,查看来源订单产生记录,也一些正常。

   到这里我逐渐觉得这个问题优点诡异了,那只能出在了网络上,即每次都发出了请求,但是因为网络问题,某个程序肯定直接将这个请求给KIll掉了,这能解释,出口进口均正常,但是通讯却没有错误信息。

     如果当时直接通过ssh客户端工具直接登录聚石塔,也许这个问题会发现的更早。没错,

通过ssh工具远程到聚石塔,开始一切正常,比如输入 cd,ls等命令都可以执行,并且响应很快,‘

但是我通过ps -ef查看进程的时候,打印信息却卡住了,其实整个客户端都卡住了。

     多次尝试均是这个结果。

    于是又在聚石塔上面通过curl模拟传输一个数据量较大的包,发现出现了如下错误:

    

java.net.SocketTimeoutException: Read timed out

at java.net.SocketInputStream.socketRead0(Native Method)

at java.net.SocketInputStream.read(SocketInputStream.java:129)

at java.io.BufferedInputStream.fill(BufferedInputStream.java:218)

at java.io.BufferedInputStream.read1(BufferedInputStream.java:258)

at java.io.BufferedInputStream.read(BufferedInputStream.java:317)

at sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:698)

at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:641)

at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1218)


     可以断定,阿里云的网络出现了bug,即请求响应数据超过了某个临界值,会被阻挡。

          

      虽然开始发现确实有很多 Read timed out错误,但是一直认为是接收端的问题,所以没有在意!


     问题找到了,但是解决不了,只能联系阿里云的客服了。



      通过沟通 于2017年9月27日 16:00:00恢复!







本文版权归作者,欢迎转载,但未经作者同意必须在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。