Nginx学习:HTTP核心模块(七)请求体及请求限流对于一个请求来说,请求行、请求头、请求体共同构成了它的整体。不过如果仅仅是 GET 请求的话,其实一般会忽略掉请求体。但是,现在大部分的伪 RESTful 开发风格,基本上已经变成了全部都是 POST 的天下了。特别是小型公司,不管前后端分离还是小程序、APP,一套 POST 走天下。 这也不怪我们懒,或者不规范,小公司毕竟是以成本,以效率来搏命的,即使是我自己弄一些小东西,也只是想着怎么简单怎么来,不会去考虑那么复杂的实现。也正因此,POST 中请求体的部分确实是现在非常重要的内容。下面我们来详细看看相关的配置都有哪些。另外,请求限流部分的内容是我之前从来没接触过的,虽说也看过一点相关的知识,知道一些什么令牌桶之类的名词,但确实从没有自己写过。因此,请求限流部分也只是简单地测试和演示,没法给出更详细的原理及解释。 请求正文请求正文,指的就是发来的请求中,body 部分的内容,也就是我们常说的 POST 请求的请求体部分。这一部分的配置主要是请求体的大小、超时时间、缓冲区等等。请求正文相关的配置项都可以用于 http、server、location 各个模块中。 client_body_buffer_size设置读取客户端请求正文的缓冲容量。
如果请求正文大于缓冲容量,整个正文或者正文的一部分将写入临时文件。缓冲大小默认等于两块内存页的大小,在x86平台、其他 32 位平台和 x86-64 平台,这个值是8K。在其他 64 位平台,这个值一般是 16K 。 我们和下面的配置一起测试这个配置指令。 client_body_temp_path定义存储客户端请求正文的临时文件的目录,没错,就是上面的超出 client_body_buffer_size 设置大小的数据所保存的临时文件的位置。默认情况下,它是位于当前运行的 Nginx 程序目录下的 client_body_temp ,比如我这里就是在这里:
它的配置参数是这样的。
这个 path 写相对路径或者绝对路径都可以,如果是相对路径,那么它对应的路径就是运行的 Nginx 程序所在的目录,和日志那些一样。参数后面的 level1 之类的参数,表示的是子目录的结构,最多可以支持三层,比如下面这样的配置。
存储临时文件的路径就是:
client_body_in_file_only这个配置是用于决定 Nginx 是否将客户端请求正文整个写入到临时文件当中。
当它的配置指令值设置为 on 时,请求处理结束后不会删除临时文件。当指令值设置为 clean 时,请求处理结束后会删除临时文件。设置为 off 就是不记录到文件中啦!默认值是 off 。 好了,结合上面三个配置,我们进行一波测试。
先忽略第一个,因为我们开启了
注意哦,这是我们随便代理的,8001 是不存在的,因此直接访问这个页面是会报错的。接下来,用 Postman 发送一个 Post 请求,使用哪种参数形式都可以,这里我使用的是 raw 。 请求之后,就可以看到 Nginx 的运行目录下多了个 client_body_temptest 目录,进去后就看到了下面这样的内容。
试着打开文件,你就会发现里面正是我们发送请求时写在请求体中的内容。好了,接下来怎么测
再次请求页面,在 client_body_temptest 目录下并没有生成新的文件,这要怎么验证呢?其实很简单,用
第一个 . 表示当前目录,看到它的修改时间发生了变化。现在你再把 上面三个配置要注意的几点是:
client_body_in_single_buffer这个配置项可以确定 Nginx 将整个客户端请求正文是否保存在一块缓冲中。
它的默认值是 off ,推荐在使用 client_body_timeout用于定义读取客户端请求正文的超时时间。
默认值是 60 秒,超时是指相邻两次读操作之间的最大时间间隔,而不是整个请求正文完成传输的最大时间。如果客户端在这段时间内没有传输任何数据,Nginx 将返回408(Request Time-out) 错误到客户端。啥意思呢?连接建立了,60s 内啥玩意也不发,直接就报错呗,这个我也不知道怎么测,所以咱们保持默认就好啦。 client_max_body_size它设置允许客户端请求正文的最大长度,这个配置应该是比较常见的,特别是做过上传大文件的同学。
它的默认值是 1m ,和 PHP 中的 这个好测,直接找个大于 1m 的文件用 POST 上传到我们前面那个 /request_body 路径下,然后再修改这个值,超过我们选择的文件大小,再试一次就知道它的效果啦!或者直接设置成小的值,比如 1k ,然后随便找个大于 1k 的测试一下会不会返回 413 错误。 请求限流Nginx 的请求限流部分,主要限的是速度,也就是流量大小。注意,这里是限流,不是限制,限制是限制请求的连接数量 ,后面还有专门的请求限制模块。限流这里最典型的案例就是百度网盘的会员和非会员的下载速度的区别。通过 Nginx 我们也可以方便地对我们自己的流量速度进行限制,我们先来看看这个配置相关的指令。 limit_except在指定的 location 下面,配置 limit_except 后,可以按指定的 HTTP 方法进行请求限制。
在 Apache 下配置虚拟主机的时候,经常会有 Deny 和 Allow 这些相关的配置,而在 Nginx 中,其实我们通常很少去配置这个。毕竟在 Apache 下面,大部分情况下通常我们也是直接 Allow all; 的。 method 参数是用于指定不由这些限制条件进行过滤的 HTTP 方法,可选值有 GET、 HEAD、 POST、 PUT、 DELETE、 MKCOL、 COPY、 MOVE、 OPTIONS、 PROPFIND、 PROPPATCH、 LOCK、 UNLOCK 或者 PATCH。 指定 method 为 GET 方法的同时,Nginx 会自动添加 HEAD 方法。那么其他 HTTP 方法的请求就会由指令引导的配置块中的ngx_http_access_module 模块和 ngx_http_auth_basic_module 模块的指令来限制访问。这两个模块我们后面会单独学习。 那么咱们就来配置一个。为了能够测试 POST 之类的请求,需要连接一下 PHP ,所以咱们就使用之前配置好的 PHP 配置。
在 html/1.php 这个文件中,我们直接打印了 我们的主机是虚拟机的主机,IP 是 192.168.56.1 ,在配置中,我们 deny 了 all ,但是开放了 .101 可以访问。划重点了,上面的 GET 表示除了 GET 之外的,比如 POST 之类的请求,就会走下面的限制约束,第一次接触的小伙伴可能真的会搞反,以为是写在这里的才被限制,其实是反过来的哦,写在这里的是不被限制的。因此,在现在的情况下,.1 主机 GET 访问 http://192.168.56.88/1.php 应该是没问题了,那么 POST 访问会出现什么呢? 大家可以试试,直接返回的就是 403 Forbidden ,也就是没有权限。也就是说,deny 是生效的。现在我们再开一台虚拟机,IP 设置成 192.168.56.101 ,然后使用 CURL 请求。
没有任何问题,POST 也可以正常请求,说明 allow 对 .101 这台虚拟机是生效的。有兴趣的小伙伴可以再开一台虚拟机,设置成别的 IP ,再次进行测试,看看效果怎么样。 limit_rate接下来我们就来看看怎么限制流量,这个配置也比较简单。
默认值是 0 ,单位是 字节/秒 ,默认 0 就表示不限制。Nginx 按连接限速,所以如果某个客户端同时开启了两个连接,那么客户端的整体速率是这条指令设置值的 2 倍。 从 1.17.0 版本开始参数值可以包含变量,如果要根据特定条件限制速率的话,它可能很有用:
另外我们也可以直接使用
变量相关的内容我们在后面的文章中再详细说,一会也会简单演示一下。 最后还可以通过 “X-Accel-Limit-Rate” 响应头来完成速率限制。这种机制可以用 proxy_ignore_headers 指令和 fastcgi_ignore_headers 指令关闭。 上面全是官网的说明内容,具体的演示我们将结合下面的配置指令一起测试。 limit_rate_after这个指令用于设置不限速传输的响应大小。
默认 0 ,单位是字节,当传输量大于此值时,超出部分将根据 limit_rate 的规则限速传送。 测试限流好了,咱们来试试吧。首先得搞个大点的文件,这样传输过程才会持续一段时间,就挑个之前我录过的视频好了。把它放到之前准备好的 /usr/local/nginx/html/mp4/ 目录下并改名为 1.mp4 为了好记好测。接着就配置一个 location 。
现在访问 /limitmp4/1.mp4 ,会发现速度很快,直接下载视频,速度也很惊人,毕竟咱们是在本地的虚拟机上。然后咱们就来进行限流。
配置 limit_rate 设置为 1k ,之后重载 Nginx 并进行访问。很明显,连播放都开始卡顿了,下载速度也直接变慢了。
继续加上 limit_rate_after 限制到 1000m ,limit_rate 设置为 1m ,也就是 1G 以上的文件才会限制流量,再次访问,速度又恢复到了之前的水平。现在你可以随意修改这两个参数了,比如将 limit_rate_after 改成 200m ,我们的文件有 500m ,这时限速又开始了,不过速度比限制在 1k 的时候要好很多,因为现在的传输速度在 1m 。 接下来,我们测试一下
直接设置一个 最后, X-Accel-Limit-Rate 头是针对上游服务器的,也就是反向代理或者负载均衡那边返回的内容是否将对应的响应头返回给客户端的,这个不好测,资料也不多,大概了解一下就好啦。 说了这么半天,到底限流的意义何在呢?除了百度网盘那种收费的作用外,限流还可以保护我们的带宽,避免某一个连接将整台服务器的带宽占满,比如我们下载东西的时候。另外就是在大促高并发的场景下,保障后端程序带宽的稳定性,同样也是避免带宽被占用挤压影响其它业务。 将来我们在学习更多架构方面知识的时候再来详细的研究吧,目前我的认知只到这个水平,反正 Nginx 中是有这个功能的,这一点大家还是要牢记。 总结今天的内容真正的配置指令没几个,请求正文有六个,请求限流只有三个,更多的还是在进行一些测试。毕竟都是自己之前从来没怎么配过玩过的东西。而且我发现,请求限流相关的内容还是非常有意思的,对于大文件上传下载也有了一些想法,直接用 Nginx 就可以避免带宽被某几个用户的大文件操作占满。确实还是收获满满,各位别急,后面还有好玩的东西呢,千万别错过了。 参考文档: http:///en/docs/http/ngx_http_core_module.html |
|