美文网首页
记一个Nginx线上问题

记一个Nginx线上问题

作者: 诺之林 | 来源:发表于2020-07-20 22:00 被阅读0次

目录

问题

  • 通过监控ELK日志 线上出现如下错误
414 Request-URI Too Large
  • 怀疑是GET参数太大导致URL过长
image.png
  • 于是尝试在本地环境复现上述问题

复现

Java

sudo apt install -y openjdk-8-jdk

curl -s get.sdkman.io | bash

source "$HOME/.sdkman/bin/sdkman-init.sh"

sdk install springboot 2.1.13.RELEASE

spring init -b 2.1.13.RELEASE -dweb --build gradle HelloSpring && cd HelloSpring

./gradlew bootrun

curl localhost:8080
# {"timestamp":"2020-07-28T11:22:33.995+0000","status":404,"error":"Not Found","message":"No message available","path":"/"}

Nginx

sudo apt install -y nginx

sudo vim /etc/nginx/sites-enabled/java.conf
server {
    listen 80;
    server_name 192.168.56.150.xip.io;

    location / {
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_pass http://127.0.0.1:8080;
        proxy_read_timeout 90;
    }
}
sudo nginx -t

sudo nginx -s reload
  • 测试脚本
vim request.sh
#!/bin/bash

url="http://192.168.56.150.xip.io?ids=1"

for i in {1000..3000}
do
    url="${url},$i"
done

echo ${url}
curl ${url}
bash request.sh
<html>

<head>
    <title>414 Request-URI Too Large</title>
</head>

<body bgcolor="white">
    <center>
        <h1>414 Request-URI Too Large</h1>
    </center>
    <hr>
    <center>nginx/1.10.3 (Ubuntu)</center>
</body>

</html>

解决

Nginx

sudo vim /etc/nginx/nginx.conf
# large_client_header_buffers 4 512k;

sudo nginx -t

sudo nginx -s reload
bash request.sh
# java.lang.IllegalArgumentException: Request header is too large
<!doctype html>
<html lang="en">

<head>
    <title>HTTP Status 400 – Bad Request</title>
</head>

<body>
    <h1>HTTP Status 400 – Bad Request</h1>
</body>

</html>

Java

vim src/main/resources/application.properties
server.max-http-header-size=500000
./gradlew bootrun
bash request.sh
# {"timestamp":"2020-07-28T11:22:33.692+0000","status":404,"error":"Not Found","message":"No message available","path":"/"}

原理

Nginx

  • 首先根据client_header_buffer_size分配Request Header的Buffer (默认1K bytes)

  • 如果分配的Buffer无法容纳Request Header (通常都会小于1K bytes)

  • 那么根据large_client_header_buffers分配新的Buffer (默认1K bytes)

  • 如果分配的Buffer仍然无法容纳Request Header

  • 那么就会返回错误 414 Request-URI 太长 / 400 请求出错

因此可以得到这两个影响Request Header Buffer的配置修改策略如下

  • 如果请求中的Header都很大 那么应该增大client_header_buffer_size 因为能减少一次内存分配

  • 如果请求中只有少量请求Header很大 那么应该增大large_client_header_buffers 因为能减少无谓的内存开销

Java

Key Default Value Description
server.max-http-header-size 8KB Maximum size of the HTTP message header.

优化

  • 方法1 拆分GET接口 参数分批并行访问
# 过去
GET params 1000
 
# 优化
[GET params 500, GET params 500] <= 并行
  • 方法2 使用POST接口 参数放至Body传递
# 过去
GET params 1000

# 优化
POST params 1000 (body)
  • 方法3 欢迎您的经验和留言

参考

相关文章

网友评论

      本文标题:记一个Nginx线上问题

      本文链接:https://www.haomeiwen.com/subject/dhhykktx.html