网站首页 > 技术文章 正文
使用一些类库进行http请求时,比如使用Apache HttpComponents 库。默认的, HttpClient 尝试自动从 I/O 异常恢复。这种自动恢复机制仅限于一些被认为是安全的异常,比如套接字被重置或者套接字被关闭。但是有些场景重试会造成重复请求风险。
一般来讲,重复请求比网络异常直接返回失败对用户是更差的体验。因为重复请求,实际造成了影响,但是给上游返回是成功,这样实际结果和给上游的返回结果不一致,自身系统从准确性上来说是不准确的。如果网络异常就返回失败,上游有自主处理的权利,某些场景他们可以自己发起重试,有些可以通过查询、核对等手段获取正确的结果。
以下三种场景重试会导致重复提交。
场景一:读超时 Read timeout
在发HTTP请求时,建立连接后:请求方会先进行请求数据写操作,对方才能收到请求;对方处理完成之后会返回结果,请求方要读取请求结果,这时候是读操作。
所以如果遇到网络数据读超时,会重复提交。
场景二:套接字异常 Unexpected end of file from server
这个异常说明数据已经发送成功。有可能服务端是防火墙的原因,没有处理客户端发来的数据。也有可能是客户端的数据不符合要求,服务端没有做出响应。数据不符合要求可能是传送的数据含有奇怪的字符。也有可能是两边编码不一致导致。客户端将字符串变成字节数据传送时需要指定编码格式,如str.getBytes(“UTF-8”);如不指定,可能导致上面的错误。当URL过长时也会发生此错误。
返回数据为空或者499的HTTP状态码与上面情况产生原因类似,也很有可能数据已经发送成功,重试需谨慎。
场景三:连接被重置
在Java的httpClient组件中,默认是会对套接字被重置做重试的。可是我就实际遇到过套接字被重置,实际上是数据已经发送成功的场景。详见:《connection reset案例的穿越之旅》。简而言之,就是A调用B,B系统前面有一层网络设备。实际上A是和B的网络设备建立长连接。一旦B系统出现错误抛出异常,前面那层网络设备作为客户端感知到了B系统的异常,主动断开连接关闭了自己与A系统的异常。A得到的结果就是连接被重置。所以httpClient等常用组件的默认重试策略也并不可靠。
猜你喜欢
- 2024-10-20 高效访问海量地图数据--GeoServer手动发布本地Shapefile地图
- 2024-10-20 详解grafana常见报错internal server error如何解决
- 2024-10-20 python教程之FTP相关操作(python2 ftp)
- 2024-10-20 僵尸毁灭工程联机教程 僵尸毁灭工程联机服务器设置
- 2024-10-20 tftp为何timeout?为何server error:(1)File not found
- 2024-10-20 MySQL server PID file could not be found!失败
- 2024-10-20 esp8266_server 的 streamFile 方法
- 2024-10-20 Java IO之字节流详解,文件字节输出流,文件字节输入流
- 2024-10-20 SQL server 2008 R2 图文安装教程(附资源)
- 2024-10-20 GET!无法连接数据库,SOLIDWORKS Electrical解决方法
- 最近发表
- 标签列表
-
- cmd/c (90)
- c++中::是什么意思 (84)
- 标签用于 (71)
- 主键只能有一个吗 (77)
- c#console.writeline不显示 (95)
- pythoncase语句 (88)
- es6includes (74)
- sqlset (76)
- apt-getinstall-y (100)
- node_modules怎么生成 (87)
- chromepost (71)
- flexdirection (73)
- c++int转char (80)
- mysqlany_value (79)
- static函数和普通函数 (84)
- el-date-picker开始日期早于结束日期 (76)
- js判断是否是json字符串 (75)
- c语言min函数头文件 (77)
- asynccallback (87)
- localstorage.removeitem (74)
- vector线程安全吗 (70)
- java (73)
- js数组插入 (83)
- mac安装java (72)
- 无效的列索引 (74)