女主宣言

之前看到有人写的一篇关于nginx配置中large_client_header_buffers的问题排查的文章,其中提到:large_client_header_buffers 虽然也可以在server{}内生效,但是只有 低于 nginx主配置中的值才有意义。

对这个结论,我心存疑虑,总觉得这种设计很奇怪,于是自己做了个测试,希望能了解的更深入一些。

PS:丰富的一线技术、多元化的表现形式,尽在“360云计算”,点关注哦!

测试方法

nginx主配置中加入配置项:(在主配置中将header大小控制在1k)

删除所有干扰vhost,仅留下一个:

构造请求的shell:(构造header超过1k的请求)

1

第一次测试结果

测试得到的结果和之前看到的文章的结果不同,该长url请求成功被nginx处理。

什么情况啊?于是查看和文章中环境上的不同,发现很重要的一点:我只有这一个vhost。

于是添加了另外一个vhost,添加vhost配置如下:(没有设置 large_client_header_buffers)

2

第二次测试结果

测试发现,nginx依旧可以处理该长url请求。

再次思考不同点,想到:这些vhost是被主配置中include进来的,是否会和读取顺序有关呢?

于是再次调整配置,将两个vhost放到了一个conf文件中,配置如下:

3

第三次测试结果

得到和文章中相同的结果,nginx返回414 Request-URI Too Large。

带着好奇心,我颠倒了下两个vhost的顺序,如下:

4

第四次测试结果

nginx成功处理该长url请求。

初步结论

通过上面的现象,我得到一个初步结论:在第一个vhost中配置的large_client_header_buffers参数会起作用。

好奇怪的现象啊,我对自己得出的结论也是心存疑惑,于是决定从手册中好好读下控制header_buffer相关的指令。

从手册上理解nginx有关header_buffer配置指令

从手册上找到有两个指令和header_buffer有关:

1.client_header_buffer_size

2.large_client_header_buffers

对nginx处理header时的方法,学习后理解如下:

1.先处理请求的request_line,之后才是request_header。

2.这两者的buffer分配策略相同。

3.先根据client_header_buffer_size配置的值分配一个buffer,如果分配的buffer无法容纳 request_line/request_header,那么就会再次根据large_client_header_buffers配置的参数分配large_buffer,如果large_buffer还是无法容纳,那么就会返回414(处理request_line)/400(处理request_header)错误。

根据对手册的理解,我理解这两个指令在配置header_buffer时的使用场景是不同的,个人理解如下:

1.如果你的请求中的header都很大,那么应该使用client_header_buffer_size,这样能减少一次内存分配。

2.如果你的请求中只有少量请求header很大,那么应该使用large_client_header_buffers,因为这样就仅需在处理大header时才会分配更多的空间,从而减少无谓的内存空间浪费。

为了印证自己对两个配置指令的理解,我把large_client_header_buffer

换成client_header_buffer_size,重新跑上面的多种测试,得到了和之前各种场景相同的结论。

手册上也只是说明了这两个指令的使用场景,没有说更多的东西了,之前的疑惑还是没有得到解答,那么只有最后一招了,也是绝招:从源码中寻找答案

源码学习

这里从client_header_buffer_size指令入手,先查看这个指令的定义部分:

由定义看到,我们在server{}中解析到的值会和http{}中的值做一次merge,作为该server{}下的最终值。查看merge相关的逻辑:

从这段逻辑中得到结论:如果我们在server{}中配置了client_header_buffer_size,那么针对这个server{}块的最终值应该就是我们配置的值。

为了印证我的结论,我重新写了vhost配置,并在代码中加入调试信息,把最终结果打印出来:

调试代码:

重新编译nginx,测试每个server{}中client_header_buffer_size的最终值为:

从值的最终结果看,的确是之前设置的1m,但是请求时却返回了414。

由于将两个server{}的位置颠倒后可以正常处理请求,所以在颠倒的情况下又测试了下最终值,输出如下:

最终值的输出还是1m,但是这次就可以正常处理请求了。

看来nginx在实际处理请求的过程中,一定还有之前不知道的一套逻辑,用来判断

client_header_buffer_size的最终值。

nginx处理请求时的相关代码如下:

这里真相大白:

原来client_header_buffer_size的最终值,是nginx在解析conf后,default_server中经过merge的最终值。

而default_server在nginx中的定义为:在listen指令中定义:

为了验证这一点,我修改vhost配置为:

重启nginx观察merge结果:

merge结果没有不同。测试请求,这次nginx成功处理该请求,和预期的效果一致。

结束语

笔者又测试了large_client_header_buffers,得到和client_header_buffer_size同样的结果。可以得出结论:nginx在处理header时实际分配的buffer大小,是解析conf后,default_server中的最终值。

个人水平有限,上面的测试方法和理解如有不当的地方,还望大家指正,谢谢!

360云计算

由360云平台团队打造的技术分享公众号,内容涉及数据库、大数据、微服务、容器、AIOps、IoT等众多技术领域,通过夯实的技术积累和丰富的一线实战经验,为你带来最有料的技术分享

Nginx的client_header_buffer_size和large_client_header_buffers学习相关推荐

  1. Nginx code 常用状态码学习小结

    最近了解下Nginx的Code状态码,在此简单总结下.一个http请求处理流程: 一个普通的http请求处理流程,如上图所示: A -> client端发起请求给nginx B -> ng ...

  2. 配置LNMP环境(linux,nginx,mysql,php)[蜗牛学院学习随记]

    一.准备一台干净的linux虚拟机(centos) 1.下载centos7镜像文件(上网搜centos就ok) 2. 点击这个architectures(x86_64) 3.下载镜像 随便选择一个国内 ...

  3. Nginx支持WebSocket反向代理-学习小结

    WebSocket是目前比较成熟的技术了,WebSocket协议为创建客户端和服务器端需要实时双向通讯的webapp提供了一个选择.其为HTML5的一部分,WebSocket相较于原来开发这类app的 ...

  4. Nginx核心知识100讲学习笔记(陶辉)Nginx架构基础(一)

    (转载,非常不错的文章) 一.Nginx的请求处理流程进程结构 1.Nginx的请求处理流程 2.Nginx的进程结构 3.进程作用 1.Master进程 1.是进行work进程的监控管理的 2.看看 ...

  5. http400错误可能是由于nginx导致的

    问题查看: 解决Nginx 400 Bad Request问题的一些思路 解决办法: Nginx的client_header_buffer_size和large_client_header_buffe ...

  6. Nginx 400 Bad Request

    400 Bad Request是一种HTTP错误状态码.HTTP/1.1对400 Bad Request的定义主要是:1.语义有误,当前请求无法被服务器理解.除非进行修改,否则客户端不应该重复提交这个 ...

  7. Nginx 414 Request-URI Too Large

    报错信息: 开发反馈富文本内容太多,发送post请求,Nginx会返回如下报错 <html><head><title>414 Request-URI Too Lar ...

  8. Grafana报错 414 Request-URI Too Large

    Grafana报错 414 报错 Network error request URI too large INFO[09-03|06:26:09] Request Completed logger=c ...

  9. 学习Nginx,看完这篇超详细的文章就够了

    目录 本文简介 一.Nginx的基本概念 1.1.Nginx是什么? 1.2.Nginx能帮助我们做些什么? 1.3.Nginx的特性 二.Nginx的安装 2.1.环境介绍 2.2.安装Nginx ...

最新文章

  1. 给大家介绍一个相当好的播放器 J River Media Center 15
  2. Bitmap 索引 vs. B-tree 索引:如何选择以及何时使用?——2-5
  3. 第一章:1.2.1系统建模
  4. hibernate之工具类
  5. Informix IDS 11零碎治理(918考试)认证指南,第 7 部分: IDS复制(24)
  6. LeetCode 454. 4Sum II
  7. 项目管理知识体系指南(第六版PMBOK 指南)目录
  8. 古体字与简体字对照表_简体字与繁体字对照表大全.pdf
  9. Mybatis 新增返回ID
  10. 如何用好谷歌等搜索引擎?
  11. 相机和雷达外参联合标定
  12. matlab排版形式是什么样子,版式设计技巧!论图文排版的基本形式
  13. 年终思路梳理(三)——工业互联网
  14. Docker学习——DockerFile
  15. Try to become a quitter 学会放弃
  16. 腾讯大逆转阿里,夺回港股王,马化腾“拍了拍”马云
  17. 旅游erp测评:蝶步erp vs小强erp
  18. Ubuntu下Qt报错 “cannot find -lGL“
  19. 如何检查文件正在被使用
  20. MODBUS PLUS测试软件,Modbus Plus

热门文章

  1. DelphiBCB一线程序员开发经验
  2. Spring自学日志05(代理模式)
  3. 注解、路径、 Log4J、<settings>标签
  4. SpringCloud创建Config模块
  5. Ditto剪贴板增强工具
  6. Invalid options in vue.config.js: “baseUrl“ is not allowed
  7. 高级JAVA - 利用函数式接口实现通用的取并集/交集/差集
  8. 杭州师范大学计算机与科学,杭州师范大学信息科学与工程学院
  9. 使用了未经检查或不安全的操作_违规操作就是对家庭的不负责!电气安全员提醒你的安全常识...
  10. nslookup查询结果详解