网站首页 > 精选教程 正文
公司一项目采用LNMP架构,最近老是报500,Nginx错误日志如下:
[error] 7649#0: *60873458 upstream sent too big header while reading response header from upstream, client: XXX, server: XXX, request: "GET /xx HTTP/1.1",
因为涉及到一些敏感信息,所以一些关键信息去除了,但这不影响问题的分析。
从字面理解应该是upstream返回的header头超出限制了 ,这里大概脑补下FastCgi协议,Nginx和PhpFpm是通过这个协议进行数据传输的,其中Nginx和后端所有Upstream交互都是分两步的,第一步是处理头,第二步是处理body,每个协议实现自己的部分。
FastCgi协议这里不详述,在本案例中,头部分相关于后端写回的http头太大了,具体是哪部分大,一般来说是Cookiem的内容过长。
百度了一下,说要调整缓冲区大小,
fastcgi_buffer_size 16k;
fastcgi_buffers 8 128k;
其中fastcgi_buffer_size默认是4K,在这个案例中,因为后端返回的Cookie和其它Http头信息超出4K了,所以报错,这里调整为16K,问题解决。
具体可以看下Nginx源码中处理FastCgi头的函数ngx_http_upstream_process_header:
if (rc == NGX_AGAIN) {
if (u->buffer.last == u->buffer.end) {
ngx_log_error(NGX_LOG_ERR, c->log, 0,
"upstream sent too big header");
ngx_http_upstream_next(r, u,
NGX_HTTP_UPSTREAM_FT_INVALID_HEADER);
return;
}
continue;
}
这里会判断last是否等于end,Nginx针对缓冲是通过ngx_buf结构来描述的:
struct ngx_buf_s {
u_char *pos;
u_char *last;
off_t file_pos;
off_t file_last;
u_char *start; /* start of buffer */
u_char *end; /* end of buffer */
ngx_buf_tag_t tag;
ngx_file_t *file;
ngx_buf_t *shadow;
……
其中start是缓冲的开始部分,end是结束部分,这是系统分配下来的,实际用的时候是将数据读到缓冲区里,并增加last部分,还有个pos表示应用处理的部分。
打个比方,我申请了1000的内存,开始地址为 1000,结束为1999(当然实际地址不可能这么小,这些是留给OS的,这里只是便于说明问题),那刚开始start为1000,end为1999,pos和last都为1000;这个时候应用读取后端upstream的头部分,读取了500字节,那last指向1500,post指向0,然后解析upstream的头,转换为内部一些结构,则pos也推进了。
回到上面的情况, 这里判断了last是否指向了end,这种情况下表示这个缓冲区已经用完了,在案例中,因为配的是4K,即表示从upstream中读取的头超出了4K,所以报错。
这个配置是针对每个Upstream的,即如果同时有1000个请求,则占用1000*16K的内存,所以不宜设的过大,这也是Nginx保存内存的一种办法。
猜你喜欢
- 2024-10-08 蓝易云 - 什么是HTTP500内部服务器错误,要如何修复?
- 2024-10-08 网页出现500错误是什么问题 打开网页出现500
- 2024-10-08 thinkphp5出现500错误怎么办 php报500错误
- 2024-10-08 NGINX 500 错误--调整文件打开句柄大小
你 发表评论:
欢迎- 最近发表
-
- java 服务之间调用(rpc)(java实现服务器)
- Java机器学习库(Java ML)(二、聚类)
- 「Java库」如何使用优秀的加密库Jasypt来保护你的敏感信息?
- GitHub精选 | 轻量级Android和Java日志库
- Java面试官:MySQL binlog 有什么作用?主从延迟的了解么?
- Excel函数核武器库:50个高频场景公式——第二弹
- Excel函数核武器库:50个高频场景公式——第一弹
- Spring Cache高性能缓存库 - Caffeine简介
- Java通过Kafka Streams库来实现数据流处理
- 一连问了好几个大佬,竟然都不知道Redis为什么默认16个数据库?
- 标签列表
-
- nginx反向代理 (57)
- nginx日志 (56)
- nginx限制ip访问 (62)
- mac安装nginx (55)
- java和mysql (59)
- java中final (62)
- win10安装java (72)
- java启动参数 (64)
- java链表反转 (64)
- 字符串反转java (72)
- java逻辑运算符 (59)
- java 请求url (65)
- java信号量 (57)
- java定义枚举 (59)
- java字符串压缩 (56)
- java中的反射 (59)
- java 三维数组 (55)
- java插入排序 (68)
- java线程的状态 (62)
- java异步调用 (55)
- java中的异常处理 (62)
- java锁机制 (54)
- java静态内部类 (55)
- java怎么添加图片 (60)
- java 权限框架 (55)
本文暂时没有评论,来添加一个吧(●'◡'●)