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. Dom4j(解析property)

    Dom4j(解析property) public class XpathTest { /** * XPath 使用路径表达式来选取 XML 文档中的节点或节点集 * * 经常使用到的路径表达式,如下 ...

  2. SpringBoot快速入门(必知必会)

    是什么?能做什么 SpringBoot必知必会 是什么?能做什么 SpringBoot是一个快速开发脚手架 快速创建独立的.生产级的基于Spring的应用程序 SpringBoot必知必会 快速创建应 ...

  3. python编程指南

    1.python文件引入同一个模块的python文件, 在命令行执行的时候需要定位到模块内部,加入参数PYTHONPATH=../ 在pycharm中  import package一般都是按照绝对路 ...

  4. js之window对象(慕课网学习笔记)

    javaScript定义了一个变量一个函数都会变成window中的一个成员 var a=1; alert(window.a) //会输出a的值 window基础 创建窗口.调整窗口.移动窗口.关闭窗口 ...

  5. 30 道 Vue 面试题,内含详细讲解(涵盖入门到精通,自测 Vue 掌握程度)

    前言 本文以前端面试官的角度出发,对 Vue 框架中一些重要的特性.框架的原理以问题的形式进行整理汇总,意在帮助作者及读者自测下 Vue 掌握的程度.本文章节结构以从易到难进行组织,建议读者按章节顺序 ...

  6. 恶意软件开发——编写第一个Loader加载器

    一.什么是shellcode loader? 上一篇文章说了,我们说到了什么是shellcode,为了使我们的shellcode加载到内存并执行,我们需要shellcode加载器,也就是我们的shel ...

  7. os.read

    #-*-coding:utf-8-*-__author__ = "logan.xu"import oscmd_res=os.popen("ls").read() ...

  8. noip模拟46

    A. 数数 排好序从两头贪心即可 B. 数树 首先很容易想到容斥 如果选择的边集的相关点集有点的度数大于 \(1\) 是不合法的 也就是说一定形成若干条长度不一的链 要给这些链上的点安排排列中的数,方 ...

  9. Robot Framework(9)- 使用变量文件

    如果你还想从头学起Robot Framework,可以看看这个系列的文章哦! https://www.cnblogs.com/poloyy/category/1770899.html 啥是变量文件 变 ...

  10. javascript对象——基本对象

    1.array对象 2.Boolean包装类对象和Date对象   3.Math对象 1到100随机数 4.RegExp对象 4.1 正则规则 如: 4.2 两种创建正则对象方式 /正则表达式/    ...