[Nginx/Go/OpenGemini] API请求体过大时,报:413 Request Entity Too Large
目录
1 问题描述
CASE/20231226 : Nginx Web Server
-
此问题(通过方法1)已解决,但整体的解决思路,参考自网友,故著名为【转载】文章
-
昨晚压测时,通过API请求10000个设备的若干信号(5个)状态时,Postman返回Nginx的如下错误
API 整个请求有 1.37MB
413 Request Entity Too Large
CASE/20250106: Go/OpenGemini(ts-sql) Http Server
如果是 go server ,则可能报此类错误日志:
// opengemini : tail -f 100 /usr/local/opengemini/gemini-log/logs/ts-sql-8086/sql.log
{"level":"error","time":"2025-01-06T11:58:16.998985255+08:00","msg":"serveWrite","hostname":"10.45.32.2:8086","ContentLength":32398789,"error":"write error:StatusRequestEntityTooLarge","db":"xxx_db","errno":"11116413","location":"httpd/handler.go:1214","repeated":1}
2 问题分析
针对 Nginx Web Server
- 通过字面意思,即可知悉:
nginx
的client_max_body_size
指令的默认值为 1 MiB 导致的。
- 这一指令可以被设置在
http
,server
和location
语境。在大多数情况下,该指令在嵌套块优先于祖先块相同的指令。
client_max_body_size
- client_max_body_size 默认 1M,表示 客户端请求服务器最大允许大小,在“Content-Length”请求头中指定。
- 如果请求的正文数据大于client_max_body_size,HTTP协议会报错 413 Request Entity Too Large。
- 就是说如果请求的正文大于client_max_body_size,一定是失败的。如果需要上传大文件,一定要修改该值。
- client_body_buffer_size
- Nginx分配给请求数据的Buffer大小,如果请求的数据小于client_body_buffer_size直接将数据先在内存中存储。
- 如果请求的值大于client_body_buffer_size小于client_max_body_size,就会将数据先存储到临时文件中,在哪个临时文件中呢?
- client_body_temp 指定的路径中,默认该路径值是/tmp/.所以配置的client_body_temp地址,一定让执行的Nginx的用户组有读写权限。
否则,当传输的数据大于client_body_buffer_size,写进临时文件失败会报错。
- 设置客户端请求正文的最大允许大小,在“
Content-Length
”请求标头字段中指定。
如果请求中的大小超过配置的值,则会将413(请求实体太大)错误返回给客户端。
请注意,浏览器无法正确显示此错误。将大小设置为0将禁用检查客户端请求正文大小。
针对 Go/OpenGemini(ts-sql) Http Server
https://github.com/openGemini/openGemini/blob/v1.2.0/lib/util/lifted/influx/httpd/handler.go#L1214
handler.go#serveWrite
3 解决方法
针对 Nginx Web Server
-
方法1:如果仅仅是调试目标微服务时,可以尝试避开
nginx
,直接请求 k8s 的 目标 pod。(仅适用于调试目标微服务) -
方法2:压缩请求内容
-
方法3:调整 nginx 的 参数
- 打开
nginx
主配置文件nginx.conf
,,找到http {}
段,修改或者添加:client_max_body_size / client_body_buffer_size
配置项一般在
/usr/local/nginx/conf/nginx.conf
这个位置。
vim /usr/local/nginx/conf/nginx.conf
client_max_body_size 20m;
client_body_buffer_size 20m;
//include mime.types;
//default_type application/octet-stream;
- 重启nginx
/usr/local/nginx/sbin/nginx -s reload
针对 Go/OpenGemini(ts-sql) Http Server
- 更新 ts-sql 服务进程的配置,再重启之
解决写入失败,ts-sql报 error:StatusRequestEntityTooLarge 的问题(默认:23.8MB)
默认值 = 25E6 Bytes = 25*10^6 Bytes = 25000000 Bytes = 23.8 MB
# vim /usr/local/opengemini/gemini-deploy-prod/ts-sql-8086/conf/ts-sql.toml
[http]
# 60MB = 62914560 Bytes
max-body-size = 62914560
关联问题: HTTP请求报请求头过大 414:Request-URI Too Large
异常
- 参考文献
原因分析
- 客户端的HTTP请求
URL
太长,超过了Web服务器的限制,导致服务器拒绝处理请求,返回414异常。
特别注意,与
413 Request Entity Too Large
不同,413
是指请求体太大,414
是指请求 URL 太长。
- 对于
Nginx Web
服务器:
- 当请求头过大,超过
large_client_header_buffer
所设定的值时,Nginx
可能返回“request uri too large”(414)或“bad-request”(400)错误。- 不仅如此,请求行中的最长一行也必须在
large_client_header_buffer
的限定范围内。- 如果请求行外的某一行的长度超过了一个buffer(默认为128k),也会导致返回“bad-request”(400)错误。
方法1: GET 请求改为 POST 【推荐】
- 如果你的web请求是get请求,可以考虑调整为post请求。
- get请求:当发送数据时,GET 方法向 URL 添加数据;URL 的长度是受限制的(URL 的最大长度是 2048 个字符)。
- post请求:原则上没有长度限制。
- 以 opengemini 或
influxdb
数据库的org.influxdb:influxdb-java
客户端库为例
2.20
版本,不支持将url请求内容放post请求体- 但
2.22
版本及以上,支持将url请求内容放post请求体
<!-- maven : https://mvnrepository.com/artifact/org.influxdb/influxdb-java/2.22 -->
<dependency>
<groupId>org.influxdb</groupId>
<artifactId>influxdb-java</artifactId>
<!-- 2.22 / 2.23 / 2.24 -->
<version>2.22</version>
</dependency>
org.influxdb:influxdb-java:org.influxdb.dto.Query#Query(java.lang.String, java.lang.String, boolean)
/**
* @param command the query command
* @param database the database to query
* @param requiresPost true if the command requires a POST instead of GET to influxdb (若 requiresPost == true,则:使用 POST 请求替代 GET 请求)
*/
public Query(final String command, final String database, final boolean requiresPost) {
super();
this.command = command;
this.database = database;
this.requiresPost = requiresPost;
}
方法2:入参分批查询
- 将get请求分批入参进行查询(不建议,这里不做方法的详细描述)
方法3:调整 Nginx Web 服务器的阈值配置
需要对Nginx的配置文件
nginx.conf
进行相应的调整。在http段中加入以下参数:
- client_header_buffer_size: 设定客户端请求头的缓冲区大小。为了应对较大的请求头,我们可以将其设置为512k。
client_header_buffer_size 512k;
- large_client_header_buffers: 设定用于存储大型请求头的缓冲区数量和大小。这里我们设定4个缓冲区,每个大小为512k。
large_client_header_buffers 4 512k;
- client_max_body_size: 限制客户端请求体的最大尺寸。这里我们将其设定为100MB,以适应较大的数据请求。
client_max_body_size 100m;
完成上述配置后,保存并重启Nginx服务器,以使新的配置生效。这样,Nginx就能更好地处理大型请求头和请求体,不再出现“414 Request-URI Too Large”错误。
- 华为云 (HTTP应用型) ELB 的底层本质是
Nginx
。
默认配置项为:
# 请求头: 32KB
client_header_buffer_size 32k;
large_client_header_buffers 4 32k;
# 请求体 : 10000MB
client_max_body_size 10000m;
client_body_buffer_size 128k;
X 参考文献
- PHP配置: 修改
php.ini
文件中的upload_max_filesize
/post_max_size
参数来增加上传限制- 有些WordPres插件也可帮助您增加上传限制,例如"WP Maximum Upload File Size"或"Upload Max File Size"
- OpenGemini
[lib] handler.go#serverWrite
https://github.com/openGemini/openGemini/blob/v1.2.0/lib/util/lifted/influx/httpd/handler.go#L1214
- config.go :
h.Config.MaxBodySize
[lib] error/message.go#HttpRequestEntityTooLarge
[lib] error/error.go#ModuleHTTP = 11
[lib] errno/code.go#InternalError = 6413

本文链接: https://www.cnblogs.com/johnnyzen/p/17929166.html
关于博文:评论和私信会在第一时间回复,或直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
日常交流:大数据与软件开发-QQ交流群: 774386015 【入群二维码】参见左下角。您的支持、鼓励是博主技术写作的重要动力!
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
2020-12-26 [数据库] Oracle之数据迁移至HIVE(待续)