nginx(五十二)处理来自客户端的HTTP请求行和请求头

一    知识铺垫

①  connection_pool_size

说明: connection_pool_size '512 字节'是 nginx 框架和客户端'建立了tcp连接时'就产生的

补充: pool_size只是内存池的'初始'分配大小,'实际'使用中可以'超出'此大小

强调: 连接池中的'连接'是指'tcp(代指)|udp(传输层)'连接

连接内存池'作用':对于'HTTP长连接',tcp连接块'被复用',增加对'资源的利用率'

②  worker_connections

注意:nginx做'反向代理'的时候,每一个'客户端'消耗'两个[client-->nginx-->upstream]'连接

说明: worker_connections'不是随便'设置的,而是与'两个指标'有重要关联

     [1]、一是'内存'大小

     [2]、二是操作系统级别的"进程最大可打开文件数" -->进程最大可打开文件数'受限于'操作系统

相关参考

③  client_header_buffer_size

1)client_header_buffer_size则具体指明'某一用途下'的内存大小

2)这里就是'最开始接收HTTP请求'的内存大小

3)如果'请求行+请求头'的大小如果'没超过1k',large_client_header_buffers 没有'用武'之地

补充: 当接收到'1个字节(data)'时,'才会分配'这1K内存;建立好连接,到接收到'data字节',有时间差

思考:client_header_buffer_size'为什么'要从connection_pool中'分配'呢?

解读:

  1)建立好'tcp连接'后就会有'connection_pool连接池'

  2)此时究竟'收到的消息是HTTP/1'还是'其他协议'消息并'不确定',所以只能'从连接内存池'中分配

④  large_client_header_buffers

large_client_header_buffers都是从'连接内存池'中分配的

重点: 了解分配'大内存'生效的场景   <-- 如果'请求行+请求头'的大小如果'没超过1k'

1)假设:large_client_header_buffers的配置默认为'4 8k'

2)请求行'request line'的大小不能超过8k,否则返回'414'错误

3)请求头'request header'中的'每一个头部字段'的大小不能超过8k,否则返回400错误

   备注:实际是'494'错误,但nginx统一返回'400'了

4)'请求行+请求头'总的大小'不能'超过'4 * 8k'

5)大内存主要是解决'接收'问题

+++++++++++++  '分配大内存的流程'  +++++++++++++

先分配'8K'的内容,'复制'之前的1K的内容,用省下的7k'继续接收'url,继续用'状态机'分析

 ⑤  request_pool_size  

说明: 而对于'请求'而言,需要保留'大量'的'上下文'信息,所以'连接内存池预分配'比请求内存池'大'

上下文信息: 'URI'、'Header'等

补充: 请求内存池涉及到'业务',根据业务需要'修改'参数

⑥   有限状态机解析HTTP请求

⑦  client_header_timeout

client_header_timeout'含义':

    1)当client 'connect'到服务端后,建立'tcp'连接后,并没有send数据

    2)服务端'socket recv 头信息'的超时时间

目的: 设置这种'读取客户端数据'的超时时间,为了避免客户端'建立连接后'不发送任何数据,浪费'资源'

补充:'网络波动'、tcp超时重传等也会造成nginx在'建立连接'后,无法在'规定'时间接收完整header

二   处理HTTP请求头部的流程

①  接收请求事件模块

[1]、nginx开始'处理'nginx请求'之前'完成的事情

   1)nginx框架先对客户端'建立连接',预分配'512'字节的内存大小

   2)开始准备'接收'用户的'请求(data)'信息

[2]、nginx开启'内存'缓冲区接收tcp字节流、用状态机解析'请求头+请求行'

②  接收请求HTTP模块

思考来源 

流程图参考

三   nginx在处理HTTP请求头遇到的报错

思考:'接收'tcp字节流和状态机'解析'请求行、请求头'发现'的问题

0) TLS/SSL

   常见: 配置了'双向认证',但是客户端认证'不通过' -->客户端'证书过期'、'没有'配置证书

   典型'error.log'报错: No required SSL certificate was sent

1)request_line

    [1]、url太长['一般是查询参数'],超过默认'8k'会报错

    [3]、请求行中的'HTTP1.2协议'nginx 'listen'不支持

2)request_header

    [1]、请求行中'没有Host'头

    [2]、单个'request_geader'太大,超过默认的'8k'

    [3]、由于与'request_line'共用内存,剩余的大内存'不足以'容纳'继续接收'请求头

①  排查思路

说明:nginx记录'4xx',不一定是nginx自身返回的

1)是否'转发'到上游

   [1]、没有转发 --> 查看'access.log'和'error.log'日志综合分析

   [2]、转发了  --> 还要协查'源站'的日志

2)频次:'偶'现还是'必'现

   [1]、低频    --> '抓包'、分析轻链路'499'

   [2]、高频    -->  客户端的'请求方式'和服务端的'配置'

②  400 Bad Request

原因: 服务端认为'客户端请求语法(参数)'错误,导致nginx'无法理解'去处理请求

1) HTTP1.1没有携带Host头

rpm安装高版本curl

2)请求发送时的协议不正确

eg: http://www.wzj.com:443  ;  nginx配置的'listen ssl 443'
 
client sent plain HTTP request to HTTPS port while reading client request header

3) Request请求头太大

1)400报错的时候,怎么判断是否是浏览器的'Header(尤其Cookies)'过大?

2)通过'nginx的debug日志'和浏览器'控制面板'来看

③  url过大 414报错

Request-URL的长度'超出'了服务器的处理能力

实验: 模拟'URL'过大

④  408报错

408(Request Timeout):如果'完成请求'所花时间太长,'服务器'可以'返回'此状态码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值