接口访问报错414,413排查解决记录

项目场景:

报错的场景是公司的一个服务系统A 跳转到公司的另一个服务系统B,但是不同服务系统之间是需要登录的,公司使用的是单点登录来实现的。


问题描述

我们都知道,登录请求的url相对而言都是要长一些的,某天现场反馈说,这个跳转时出发的单点登录报错了 【414 Request-URl Too Large】


原因分析:

看到414报错,首先想到的就是nginx配置相关的
众所周知,在nginx中可以通过一下几个配置来限制请求头,以及请求体的大小
 

#客户端预设允许的请求头大小
client_header_buffer_size 1k;  
  
#设立4个缓冲区当请求头超过预设值时会先放入缓冲区,当请求头大小预设加上超过所有缓冲区之和时会报错414
large_client_header_buffers 4 8k; 

#客户端允许的最大请求体大小,当请求体超过该值时会报错413
client_max_body_size 1m;

#客户端请求主体的缓冲区大小,分块存储的单位
client_body_buffer_size  8k;


解决方案:
 

问题调整一:
ok,那我们联系现场调整对应的nginx配置,直接在http层添加对应的

client_header_buffer_size 8k;  
  
large_client_header_buffers 4 16k;

现场的请求头我复制到txt中完整的看过,看大小的话大概在9.8k,向上面这样调整怎么着都该够了,麻溜完成后开始测试
结果不尽如人意,报错依旧没有改变。


问题调整二:
上面的配置,在nginx中是可以放在几种不同的作用域中,
从大到小依次是http层,server层,location层,如果下层有配置,则上层的配置不会生效
好的,我再看看,但是却发现现场的下层全都没有任何相关配置,那我http层的配置没有理由不生效啊
因为暂时也没有更好的办法,于是我就开始在各个层里面都添加,准备试一试
发现之前是有一个误解的,上面的那两行配置是不能再location层中添加的,不然nginx无法启动,
各种层级都试过之后还是报错,我开始怀疑,现场的实施是不是改错地方了,于是我找他们视频会议确认。
一确认果然发现问题,上面的背景里提到,是从服务系统A跳转到服务系统B的,但是现场一直更改的是A的配置,这怎么可能有用嘞,勒令现场去找找服务系统B的nginx配置,结果实施却说现场只有一个nginx,我又仔细看了一遍,那些个端口其实也不对照,肯定还有其他的nginx啊,可能会在其他服务器上,实施多方询问,终于找到了服务系统B的nginx配置,好了直接按上面的操作如法炮制一遍,这样总没问题啦吧
结果 双 不尽如人意,【414】 Request-URl Too Large虽然解决了,
但是出现了新的问题,【413】  Request Entity Too Large。

问题调整三:
好的,起码是证明我们改对地方了,413的话是对请求体的限制,还是更改对应的nginx配置吧
client_max_body_size 1m;
client_body_buffer_size  8k;
再次如法炮制,在http层添加对应配置并且检查了下层,确保没有被覆盖

结果 叒 不尽如人意,413报错依旧存在,没有解决。

问题调整四:

期间也尝试过对于请求体限制配置的数值往大了调整,但是都没有用。
只是个get请求,上面的大小按理说应该够用
所以我觉得可能就不是nginx的问题了,配置中nginx的请求会被转发到gateway网关服务,会不会是网关服务中的限制导致这个413问题呢,说干就干,我查看了一些资料并做了以下更改
1.在gateway配置文件当中添加了这样一行
 server.max-initial-line-length=10485760
并且添加了一个配置类

@Component
public class NettyConfiguration implements WebServerFactoryCustomizer<NettyReactiveWebServerFactory> {

    @Value("${server.max-initial-line-length:10485760}")
    private int maxInitialLingLength;

    @Override
    public void customize(NettyReactiveWebServerFactory container) {
        container.addServerCustomizers(
                httpServer -> httpServer.httpRequestDecoder(
                        httpRequestDecoderSpec -> httpRequestDecoderSpec.maxInitialLineLength(maxInitialLingLength)
                )
        );
    }

}

这段代码的作用呢,是自定义Netty服务器的配置。
实现WebServerFactoryCustomizer<NettyReactiveWebServerFactory>接口,
并重写了customize方法。在这个方法中,设置了maxInitialLineLength的值,
这个值表示HTTP请求的最大初始行长度。默认值为10485760字节(10MB)
好的,将修改后的gateway服务打包,发给现场更换,然后再次测试
结果不尽如人意,不过还算是有进展吧,413的错误解决了,但是出现了400 bad request的错误。

问题调整五
400这个报错大家应该都熟悉吧,集中可能导致出现他的原因有:

1.参数错误
缺少必要参数:客户端未提供必要的参数,导致服务器无法处理请求。
参数格式不正确:客户端提供的参数格式不符合服务器的要求。
参数超出范围:客户端提供的参数超出了服务器允许的范围。
2.请求格式错误
错误的请求头:客户端发送的请求头不符合HTTP协议规范。
错误的请求方法:客户端使用了服务器不支持的请求方法。
错误的请求体格式:客户端发送的请求体格式不符合服务器的要求。
3.请求长度超过限制
服务器限制请求长度的原因:服务器为了防止恶意请求或保证服务器性能,设置了请求长度的限制。
如何解决请求长度超过限制的问题:客户端需要根据服务器的要求,合理控制请求长度。
4.URL格式错误
缺少或错误的协议头:客户端未指定请求的协议头,或者指定了错误的协议头。
缺少或错误的域名:客户端未提供请求的域名,或者提供了错误的域名。
缺少或错误的路径:客户端未提供请求的路径,或者提供了错误的路径。

很明显,这是因为请求长度超过限制导致的400报错,那就好办了,直接对应的服务系统B的配置文件中添加对应配置
server.max-http-header-size=102400
然后再通知现场更新测试

结果又又又又又不尽如人意,开玩笑的
结果终于尽人意了,错误完美解决,收工!
总结
其实本次问题排查修改还有很多可以优化的地方, 比如设置的那些配置参数有些随意,只是找了个足够大的值配置上了,
比如server.max-http-header-size=102400 可以适当缩小以减少内存的浪费。
另外还有一种更加简洁,更加有效的方式,那就是缩短这个单点登录的url,但是我并没有这个相关功能的开发权限,这是公司的老老员工写的,所以只能采取这种外层的调整了。
总的来说还算是有所收获记录一下哈哈哈哈

参考链接
spring cloud gateway 413Request Entity Too Large - 抽象工作室upup - 博客园 (cnblogs.com)
Nginx 414 Request-URI Too Large报错解决方法-CSDN博客
解决 413 Request Entity Too Large(请求实体太大)-CSDN博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值