Feign 400错误引发的一系列问题

问题介绍

在使用Feign进行远程调用的时候出现非常奇怪的400错误,错误信息大概如下:

feign.FeignException: status 400 reading

并且还带有2个非常奇怪的问题:

  1. 一个前端请求接口,到达后端的时候会发起2次相同的Feign远程调用,但第一次成功,但是第二次会失败,错误信息如上。
  2. 一个前端请求接口,达到后端的时候调用Feign接口的时候会卡死。

问题定位

通过开启debug模式,查看输出日志发现,2个Feign接口都调用成功了,但是第二个接口的数据被第一个接口给截断了,导致第二个接口返回的数据不够完整。

此时,思绪万千,百思不得其解,想到http协议的content-length是用来确定请求体长度的,难道是这个问题导致?

因此,立马查看HTTP协议的content-length头部信息,果然不出我所料,问题就在这里。这里需要介绍2个http头部,就是connection头部和content-length头部,当2这结合起来的时候会有一些意想不到的结果。

Http请求头:connection、content-length

当connection头部为:keep-alive,就是http客户端告知http服务端,我们一直使用保持连接,不要关闭该连接,后面的请求也复用该连接,因为每次建立tcp连接是一件比较耗时的事情。那么,当客户端与服务器协商好了使用keep-alive的时候,就需要一个机制来区分每个http请求了,这个时候content-length就很重要了,这个头部可以确定每个请求体的长度,从而可以确定每个请求的长度,这样http服务端就可以区分每个请求,从而不到引起数据混乱。

问题解决

明白了Http协议中connection和content-length头部的作用,此时来检查feign调用是否存在这个问题。通过排查,缺失存在该问题。因为项目中为了共用页面发送的Authorization头部,用来保持所有远程调用使用统一的认证信息,因此需要在feign中传递该头部。但是实际操作的时候将前端发送过来的所有头部都传递下去了,就导致所有feign接口都共用了前端的头部信息,因此就导致了一系列的问题。因此,在使用feign的时候一定要小心http头部共用,只有共用需要的头部信息,不要无脑的将所有的头部信息都共用给feign接口,否则就会出现很多意想不到的问题。

这里解决了问题1,回过头来想想问题2,为什么有时候会出现卡死的现象呢?

这还需要我们从http协议出发来看待问题,当我们共用了前端发来的keep-alive和content-length请求头后,如果feign实际响应内容的长度达不到content-length的时候,那么此时,feign客户端会一直等待,直到feign服务端的数据达到content-length的长度要求,因此就会出现卡死现象了。

问题总结

这个问题花费了我很长时间定位,因此记录下来并好好总结,防止以后犯类似的问题。解决问题的过程确实可以学到很多,也学会了很多。主要总结下来有如下几点:

  1. 以前很少接触到http协议本身的问题,也不太了解http协议也会受到头部的影响,因此以后也要多多了解http协议,对于解决问题大有帮助;同理,我觉的开发也应该需要了解tcp/ip协议,否则当出现这些问题的时候也会有一定的解决能力。
  2. 以后再使用http头部的时候需要更加谨慎。
  3. 出现问题的时候需要冷静分析,知其然知其所以然,不要被问题表面现象蒙蔽。

不说了,大家国庆节快乐,跟祖国一起过节去了。

2021-10-2 12:18:58

深圳南山

Feign 400错误引发的一系列问题的更多相关文章

  1. 记一次400错误引发的血案(URL中特殊符号的转义/400 bad request错误)

    django+nginx+uwsgi部署的站点访问某个URL时发生了400 bad request的错误,而使用django自带的开发版的web server时没有遇到此问题.初步判断是nginx或u ...

  2. 记一次全站升级https引发的一系列问题

    中秋假期,闲来无事.花了一下午折腾了下https,说实话这年头还有网站不上https显然是折腾精神不够啊~ 1.SSL证书评估 看了市面上各种类型的证书,有收费的也有免费的,但是最终还是选择了腾讯云提 ...

  3. 在使用 HttpWebRequest Post数据时候返回 400错误

    笔者有一个项目中用到了上传zip并解压的功能.开始觉得很简单,因为之前曾经做过之类的上传文件的功能,所以并不为意,于是使用copy大法.正如你所料,如果一切很正常的能运行的话就不会有这篇笔记了. 整个 ...

  4. Yii框架 400 错误

    YII  400错误 在YII框架中400错误是csrf校验失败的意思 csrf是什么? CSRF(Cross-site request forgery跨站请求伪造,也被称为"One Cli ...

  5. 解决YII提交POST表单出现400错误,以及ajax post请求时出现400问题

    POST表单400错误: 正确做法: Add this in the head section of your layout: <?= Html::csrfMetaTags() ?> -- ...

  6. request.GetResponse 400错误处理方法

    问题描述:在使用request.GetResponse时,如果是400错误,将抛出异常信息,而获取不到返回内容,所以返回的内容只能在catch上面获取,转载于 http://blog.csdn.net ...

  7. Yii2请求,报400错误

    出现400错误是yii2.0的csrf防范策略导致 在components里面添加request配置如下: 'request' => [ // !!! insert a secret key i ...

  8. 访问本机的WEB API 报400错误

    当时用的IP是127.0.0.1 报400错误,换成 localhost 后正常.

  9. SpringMVC + Spring + MyBatis 学习笔记:提交数据遭遇基础类型和日期类型报400错误解决方法

    系统:WIN8.1 数据库:Oracle 11GR2 开发工具:MyEclipse 8.6 框架:Spring3.2.9.SpringMVC3.2.9.MyBatis3.2.8 使用SpringMVC ...

随机推荐

  1. 【VLC开发】libvlc_new函数参数

    项目中有视频监控的需求,找了vlc这个开源视频工具,在获取实例参数时遇到了问题, 要得到VLC的全部参数有两种方法, 1 只要在创建时加上"--longhelp"和"-- ...

  2. Python的dict

    dict把key和value关联起来,可以通过 key来查找 value. 花括号 {} 表示这是一个dict,然后按照 key: value, 写出来即可.最后一个 key: value 的逗号可以 ...

  3. 在vue中实现扫描二维码跳转页面

    文字少的博文不允许发布到网站首页.文字少的博文不允许发布到网站首页.文字少的博文不允许发布到网站首页.文字少的博文不允许发布到网站首页.文字少的博文不允许发布到网站首页.文字少的博文不允许发布到网站首 ...

  4. centos 搭建jenkins+git+maven

      git+maven+jenkins持续集成搭建 发布人:[李源]  2017-12-08 04:33:37   一.搭建说明 系统:centos 6.5 jdk:1.8.0_144 jenkins ...

  5. mysql 8.0 1405的坑

    因版本差异:password  可能对应:authentication_string字段 不行的话再尝试一下,并且修改下密码类型 ALTER USER 'root'@'%' IDENTIFIED WI ...

  6. MySQL binlog 自动清理脚本

    # vim /data/scripts/delete_mysql_binlog.sh 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 ...

  7. css文本溢出省略号大总结,如你所愿

    一行: white-space: nowrap; text-overflow: ellipsis; overflow: hidden; word-break: break-all; 两行: width ...

  8. 20201219 u,v,w

    开考前刚起床,所以一边考一边吃饭,然后整场都很迷... A. u 考场 半天才搞懂"下三角区域"指哪个区域,手模样例确认后打了 \(O(qn^2)\) 的裸暴力,然后就不会做了. ...

  9. Linux常用命令 - 五种创建文件命令详解

    21篇测试必备的Linux常用命令,每天敲一篇,每次敲三遍,每月一循环,全都可记住!! https://www.cnblogs.com/poloyy/category/1672457.html 创建文 ...

  10. uniapp 获取用户手机号

    参考资料: 微信小程序官方文档 uniapp开发微信小程序获取用户手机号 页面增加一个按钮 <button open-type="getPhoneNumber" @getph ...