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. 梯度下降做做优化(batch gd、sgd、adagrad )

    首先说明公式的写法 上标代表了一个样本,下标代表了一个维度: 然后梯度的维度是和定义域的维度是一样的大小: 1.batch gradient descent: 假设样本个数是m个,目标函数就是J(th ...

  2. Mysql慢查询explain

    转自:https://www.toutiao.com/i6776461352522220036/?tt_from=weixin&utm_campaign=client_share&wx ...

  3. springcloud超时重试机制的先后顺序

    https://blog.csdn.net/zzzgd_666/article/details/83314833

  4. Mysql时间戳转Java时间戳

    MySQL 时间戳和Java返回的时间戳是不一样的 例如: 当前时间是 2014-08-04 10:42:55.204000 使用mysql时间戳函数UNIX_TIMESTAMP 返回的结果为: 14 ...

  5. vue-cli3.x中的webpack配置,优化及多页面应用开发

    官方文档 vue-cli3以下版本中,关于webpack的一些配置都在config目录文件中,可是vue-cli3以上版本中,没有了config目录,那该怎么配置webpack呢? 3.x初始化项目后 ...

  6. Nginx对代理HTTP资源的限制访问

    为了限制连接的数量,首先,使用指令来定义密钥并设置共享内存区域的参数(工作进程将使用该区域来共享键值的计数器).作为第一个参数,指定作为关键字计算的表达式.在第二个参数区域中,指定区域的名称及其大小. ...

  7. Android kotlin http url request

    kotlin.concurrent.thread{ val url = "https://hangj.cnblogs.com/" val res = try { java.net. ...

  8. Kubernetes-Pod介绍(-)

    前言 本篇是Kubernetes第四篇,大家一定要把环境搭建起来,看是解决不了问题的,必须实战.从现在开始都是重要的核心概念,此篇偏一些Pod的概念介绍,后续每篇都会有实战. Kubernetes系列 ...

  9. openwrt开发笔记二:树莓派刷openwrt

    前言及准备 本笔记适用于第一次给树莓派刷openwrt系统的玩家,对刷机过程及注意事项进行了记录,刷机之后对openwrt进行一些简单配置. 使用openwrt源码制作固件需要花费一点时间. 平台环境 ...

  10. Appium问题解决方案(2)- AttributeError:module 'appium.webdriver' has no attribute 'Remote'

    背景 运行脚本的时候,就直接报这个错误了,然后去看了下 appium.webdriver 库 结果发现啥都没有,就知道有问题了,然后一步步排查 步骤一 检查Appium-Python-Client 和 ...