【Nginx21】Nginx学习:FastCGI模块(三)缓冲区与响应头
Nginx学习:FastCGI模块(三)缓冲区与响应头
缓存相关的内容占了 FastCGI 模块将近一小半的内容,当然,用过的人可能不多。而今天的内容说实话,我平常也没怎么用过。第一个是缓冲区相关的知识,其实和我们之前学习过的 client_body_buffer_size 有点类似,但它是针对后端动态程序的响应缓冲区来说的。另一个也是响应有关的,主要是响应头相关的一些配置。
今天学习的内容都是可以设置在 http、server、location 中的,有特殊情况的我会单独说。
FastCGI缓冲区配置
就像开头所说的,它和 client_body_buffer_size 的概念是类似的,只不过针对的是后端程序的响应缓冲。什么意思呢?其实就是将响应保存在内存中,如果内容太多,就会保存到一个临时文件里。
fastcgi_buffering
启用或禁用来自 FastCGI 服务器的响应缓冲。
fastcgi_buffering on | off;
启用缓冲后,Nginx 会尽快收到来自 FastCGI 服务器的响应,并将其保存到由 fastcgi_buffer_size 和 fastcgi_buffers 指令设置的缓冲区中。如果整个响应不适合内存,可以将其中的一部分保存到磁盘上的临时文件中。写入临时文件由 fastcgi_max_temp_file_size 和 fastcgi_temp_file_write_size 指令控制。
当缓冲被禁用时,响应会在收到时立即同步传递给客户端。 Nginx 不会尝试从 FastCGI 服务器读取整个响应。 Nginx 一次可以从服务器接收的最大数据大小由 fastcgi_buffer_size 指令设置。
也可以通过在“X-Accel-Buffering”响应头字段中传递“yes”或“no”来启用或禁用缓冲。可以使用 fastcgi_ignore_headers 指令禁用此功能。
它的默认值就是开启的,用于控制整个 FastCGI 的缓冲区控制,上面已经说明了关闭会发生什么情况。提到的配置指令我们马上一一学习,最后再将所有配置指令合在一起进行一个简单的测试。
fastcgi_buffer_size
设置用于读取从 FastCGI 服务器接收到的响应的第一部分的缓冲区大小。
fastcgi_buffer_size size;
这部分通常包含一个小的响应头。默认情况下,缓冲区大小等于一个内存页,这是 4K 或 8K,具体取决于平台。然而,它可以做得更小。它和 client_header_buffer_size 这类的配置指令是类似的,就相当于是 FastCGI 版本的。
fastcgi_buffers
为单个连接设置用于从 FastCGI 服务器读取响应的缓冲区的数量和大小。
fastcgi_buffers 8 4k|8k;
默认情况下,缓冲区大小等于一内存页。这是 4K 或 8K,具体取决于平台。这个配置项是创建几个缓冲区用的,比如设置成 8 4k ,表示的就是 8*4=32k 的缓冲区,而上面的 fastcgi_buffer_size 是第一个头缓冲区的大小,不包含在这边,因此,整个缓冲区的大小就是 8*4k+fastcgi_buffer_size 的结果。它和 client_header_buffer_size 类似,可以看成是主要的响应体的大小。
fastcgi_busy_buffers_size
当启用来自 FastCGI 服务器的响应缓冲时,限制在响应尚未完全读取时可能正忙于向客户端发送响应的缓冲区的总大小。
fastcgi_busy_buffers_size size;
默认值是 8 或 16 K,其余缓冲区可用于读取响应,并在需要时将部分响应缓冲到临时文件。默认情况下,大小受 fastcgi_buffer_size 和 fastcgi_buffers 指令设置的两个缓冲区的大小限制。
fastcgi_max_temp_file_size
该指令设置临时文件的最大大小。
fastcgi_max_temp_file_size size;
默认值是 1024m ,零值表示禁用对临时文件的响应的缓冲。如果启用了来自 FastCGI 服务器的响应缓冲,并且整个响应不适合由 fastcgi_buffer_size 和 fastcgi_buffers 指令设置的缓冲区,则可以将部分响应保存到临时文件中。一次写入临时文件的数据大小由 fastcgi_temp_file_write_size 指令设置。此限制不适用于将缓存或存储在磁盘上的响应。
fastcgi_temp_file_write_size
当启用从 FastCGI 服务器到临时文件的响应缓冲时,限制一次写入临时文件的数据大小。
fastcgi_temp_file_write_size size;
默认情况下,大小受 fastcgi_buffer_size 和 fastcgi_buffers 指令设置的两个缓冲区限制。临时文件的最大大小由 fastcgi_max_temp_file_size 指令设置。
fastcgi_temp_path
定义一个目录,用于存储带有从 FastCGI 服务器接收到的数据的临时文件。
fastcgi_temp_path path [level1 [level2 [level3]]];
默认值是 Nginx 运行目录下的 fasstcgi_temp 目录,整体和之前学过的 client_body_temp_path 是类似的,在指定目录下最多可以使用三级子目录层次结构。例如,在以下配置中:
fastcgi_temp_path /spool/nginx/fastcgi_temp 1 2;
临时文件可能存储的目录就是:
/spool/nginx/fastcgi_temp/7/45/00000123457
前面我们学习的 FastCGI 缓存相关的配置中,缓存临时文件配置项 fastcgi_cache_path 有个参数 use_temp_path 和这个配置项有关系,之前我们已经学习过了。
综合测试
新建一个配置,注意要用非正则针对指定目录的配置,要不然会被我们最开始的那个 location ~ \.php
给抢走,因为它那边指定了 php 结尾,优先级比直接指定目录要高,只需要加上 ^~
就好了,之前在 location 中已经详细讲解过了。
location ^~ /fastcgi1/ {root html;fastcgi_pass unix:/var/sock/php-fpm/www.sock;fastcgi_index index.php;fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;include fastcgi_params;fastcgi_buffer_size 100;fastcgi_buffers 2 100;fastcgi_busy_buffers_size 100;fastcgi_temp_file_write_size 100;fastcgi_temp_path /root/fastcgi_temp_test 1 2;
}
都设置得很小是吧,但是我们要准备的 PHP 文件需要返回的响应还是要设置的很大,否则很难看出效果。
// 1.php
<?php
$c = $_GET['c'] ?? 2000;
for ($i=$c;$i>0;$i--){print_r($_SERVER);
}
照理说,我们设置的都只是 100 字节,但实际循环 2000 次返回的响应有 2M 了,这时才能看到指定的 fastcgi_temp_path 文件夹产生了变动,里面也会生成子目录。这一块确实不太理解,设置成 1600 次循环,达不到 2M 的响应,就不会产生临时文件。去掉 fastcgi_temp_file_write_size 的配置之后,2M 的响应也不会产生文件。
这一块比较难测,而且出来的效果说实话和我们想像的也不太一样。所以如果有大佬知道这是什么情况,欢迎评论留言哈。将来如果有学习或者接触到类似的问题,也会再单独写文章说说。
另外,上面的数值大家可以乱调一下试试,这几个配置之间有各种限制,比如:
nginx: [emerg] "fastcgi_temp_file_write_size" must be equal to or greater than the maximum of the value of "fastcgi_buffer_size" and one of the "fastcgi_buffers" in /etc/nginx/nginx.conf:396nginx: [emerg] "fastcgi_busy_buffers_size" must be less than the size of all "fastcgi_buffers" minus one buffer in /etc/nginx/nginx.conf:396
这些看英文也都能猜到是啥意思了。即使通过检查了,并且 reload 成功之后,请求时也可能会报这些错。
2022/08/22 22:24:52 [crit] 1811#0: *79 open() "/root/fastcgi_temp_test/0000000001" failed (13: Permission denied) while reading upstream, client: 192.168.56.1, server: core.nginx.test, request: "GET /fastcgi1/1.php HTTP/1.1", upstream: "fastcgi://unix:/var/sock/php-fpm/www.sock:", host: "192.168.56.88"2022/08/22 22:20:33 [error] 1792#0: *71 upstream sent too big header while reading response header from upstream, client: 192.168.56.1, server: core.nginx.test, request: "GET /fastcgi1/1.php HTTP/1.1", upstream: "fastcgi://unix:/var/sock/php-fpm/www.sock:", host: "192.168.56.88"
第一个错误是指定的临时文件夹,它的上级目录的权限必须是 755 ,所有 Nginx 下面的文件夹目录都有这个要求。第二个是 fastcgi_buffer_size 设置小了,我想极限测试,也就是设置成 1 ,结果就直接报错了。这个和响应返回的头的大小有关,我这里测试是设置到 76 就可以了,不过为了统一,我就全部设置到 100 了。
响应头处理
在 FastCGI 的处理中,HTTP 请求标头字段作为参数传递给 FastCGI 服务器。在作为 FastCGI 服务器运行的应用程序和脚本中,这些参数通常作为环境变量提供。例如,“User-Agent”标头字段作为 HTTP_USER_AGENT 参数传递。除了 HTTP 请求头字段之外,还可以使用 fastcgi_param 指令传递任意参数。这些参数在 PHP 中都可以在 $_SERVER
里面看到。
对于这些响应头,Nginx 中也有一些字段进行处理,这里不仅是响应头,请求头部分的内容也一起写在这里了。
fastcgi_hide_header
默认情况下,nginx 不会从 FastCGI 服务器的响应中将头字段“Status”和“X-Accel-...”传递给客户端。
fastcgi_hide_header field;
没有默认值,也就是除了上面那些响应头以外,其它响应头都会进行传递,相反,如果需要允许传递字段,则可以使用 fastcgi_pass_header 指令。
我们在 PHP 文件中定义一个响应头 header("oopp:111");
,然后正常查看页面,这个 oopp 会返回来,而添加了 fastcgi_hide_header oopp;
之后,在浏览器上就看不到这个响应头的信息了。
fastcgi_pass_header
允许将其他禁用的标头字段从 FastCGI 服务器传递到客户端。
fastcgi_pass_header field;
可以指定在禁用列表中的响应头返回,比如 “X-Accel-...” 这些的。具体有哪些可以看后面的 fastcgi_ignore_headers 配置。
比如我们之前测试过的 X-Accel-Expires 响应头,在 PHP 中设置了,但是前端浏览器的响应头中不会显示,就可以用这个传递到前端浏览器上。
那么如果 fastcgi_hide_header 和 fastcgi_pass_header 同时设置一个响应头字段呢?以先后顺序为准,后设置的生效。
fastcgi_ignore_headers
忽略对来自 FastCGI 服务器的某些响应头字段的处理。
fastcgi_ignore_headers field ...;
以下字段可以忽略:“X-Accel-Redirect”、“X-Accel-Expires”、“X-Accel-Limit-Rate”(1.1.6)、“X-Accel-Buffering”(1.1.6) 、“X-Accel-Charset”(1.1.6)、“Expires”、“Cache-Control”、“Set-Cookie”(0.8.44)和“Vary”(1.7.7)。
如果未禁用,则处理这些标头字段具有以下效果:
“X-Accel-Expires”、“Expires”、“Cache-Control”、“Set-Cookie”、“Vary”设置响应缓存的参数
“X-Accel-Redirect”执行到指定 URI 的内部重定向
“X-Accel-Limit-Rate”设置向客户端传输响应的速率限制
“X-Accel-Buffering”启用或禁用响应缓冲
“X-Accel-Charset”设置响应的所需字符集
默认值是空的,就是这些都会处理,假如设置一个 X-Accel-Expires ,那么我们之前在 PHP 中设置的 X-Accel-Expires 响应头延长缓存时间的效果就不起作用了。
总结
缓冲区部分可能还是需要更深入的学习操作系统及网络相关的知识才能够解释清楚,目前我的水平也就只能到这里了。测试代码也是按自己的想法来进行测试的。另外一块的响应头部分比较简单,大家可以自己测试一下哦。
参考文档:
http://nginx.org/en/docs/http/ngx_http_fastcgi_module.html
相关文章:
【Nginx21】Nginx学习:FastCGI模块(三)缓冲区与响应头
Nginx学习:FastCGI模块(三)缓冲区与响应头 缓存相关的内容占了 FastCGI 模块将近一小半的内容,当然,用过的人可能不多。而今天的内容说实话,我平常也没怎么用过。第一个是缓冲区相关的知识,其实…...
正则表达式(常用字符简单版)
量词 字符类 边界匹配 分组和捕获 特殊字符 字符匹配 普通字符:普通字符按照字面意义进行匹配,例如匹配字母 "a" 将匹配到文本中的 "a" 字符。元字符:元字符具有特殊的含义,例如 \d 匹配任意数字字符…...
从零开始学习Python爬虫:详细指南
导言: 随着互联网的迅速发展,大量的数据可供我们利用。而Python作为一种简单易学且功能强大的编程语言,被广泛应用于数据分析和处理。学习Python爬虫技术,能够帮助我们从互联网上获取数据,并进行有效地分析和利用。本文…...

分布式计算框架:Spark、Dask、Ray
目录 什么是分布式计算 分布式计算哪家强:Spark、Dask、Ray 2 选择正确的框架 2.1 Spark 2.2 Dask 2.3 Ray 什么是分布式计算 分布式计算是一种计算方法,和集中式计算是相对的。 随着计算技术的发展,有些应用需要非常巨大的计算能力才…...

什么是伪类链(Pseudo-class Chaining)?
聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ Pseudo-class Chaining⭐ 写在最后 ⭐ 专栏简介 前端入门之旅:探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅!这个专栏是为那些对Web开发感兴趣、刚刚…...
每日一题:leetcode 57 插入区间
给你一个 无重叠的 ,按照区间起始端点排序的区间列表。 在列表中插入一个新的区间,你需要确保列表中的区间仍然有序且不重叠(如果有必要的话,可以合并区间)。 示例 1: 输入:intervals [[1,3…...
第五节:实现自己的第一个environment
本专栏是强化学习运用在买卖股票之上的入门学习内容。 主要解决强化学习代码落地和代码实践,不需要学习相关数学原理,直观简单的带领读者入门强化学习炒股。 查看本专栏完整内容,请访问:https://blog.csdn.net/windanchaos/category_12391143.html 本文发布地址:https://b…...

无套路,财务数据分析-多组织损益表分析分享
在报表众多的财务数据分析中,损益表是老板们最关注的报表,特别是当有多组织时,损益表的分析就变得更加重要了。以前受限于数据分析工具,做损益表分析时很难做到多维度灵活分析,但随着BI数据可视化工具的发展࿰…...

Java并发编程第6讲——线程池(万字详解)
Java中的线程池是运用场景最多的并发框架,几乎所有需要异步或并发执行任务的程序都可以使用线程池,本篇文章就详细介绍一下。 一、什么是线程池 定义:线程池是一种用于管理和重用线程的技术(池化技术),它主…...

AI + Milvus:将时尚应用搭建进行到底
在上一篇文章中,我们学习了如何利用人工智能技术(例如开源 AI 向量数据库 Milvus 和 Hugging Face 模型)寻找与自己穿搭风格相似的明星。在这篇文章中,我们将进一步介绍如何通过对上篇文章中的项目代码稍作修改,获得更…...

归并排序(Java 实例代码)
目录 归并排序 一、概念及其介绍 二、适用说明 三、过程图示 四、Java 实例代码 MergeSort.java 文件代码: 归并排序 一、概念及其介绍 归并排序(Merge sort)是建立在归并操作上的一种有效、稳定的排序算法,该算法是采用分…...

【VUE】数字动态变化到目标值-vue-count-to
vue-count-to是一个Vue组件,用于实现数字动画效果。它可以用于显示从一个数字到另一个数字的过渡动画。 插件名:vue-count-to 官方仓库地址:GitHub - PanJiaChen/vue-countTo: Its a vue component that will count to a target number at a…...
Mysql /etc/my.cnf参数详解(二)
#buffer相关 #buffer pool根据实际内存大小调整,标准为物理内存的50% innodb_buffer_pool_size15996M //默认值128M,innodb_buffer_pool_size | 134217728 key_buffer_size 33554432 #根据物理内存大小设置 确保每个instance内的内存2G左右 <5000 1,>5000 &…...
AUTOSAR规范与ECU软件开发(实践篇)6.10AUTOSAR操作系统概念与配置方法介绍(下)
目录 2、 RTA-OS工程创建 3、 AUTOSAR操作系统配置方法 (1) 描述文件导入 (2) Counter配置...
蓝牙 - 经典蓝牙物理信道介绍
物理信道有多种类型。所有蓝牙物理信道的特点都是一组物理层的频率与时间参数相结合,并受到空间因素的限制。对于基本的和经过调整的蓝牙组网(piconet)所用物理信道,跳频用于定期改变频率,以减少干扰影响,同时也是出于监管原因。 …...

性能测试中未做集群时,在登入中已经保存了登入的session,但可能会出现在不同的服务器上显示登入失败
Session未进行集群共享时,则会出现服务器2,未登录...

Python环境下载安装使用
天行健,君子以自强不息;地势坤,君子以厚德载物。 每个人都有惰性,但不断学习是好好生活的根本,共勉! 文章均为学习整理笔记,分享记录为主,如有错误请指正,共同学习进步。…...

图像扭曲之波浪扭曲
源码: void wave_sine(cv::Mat& src,cv::Mat& dst,double amplitude,double wavelength) {dst.create(src.rows, src.cols, CV_8UC3);dst.setTo(0);double xAmplitude amplitude;double yAmplitude amplitude;double xWavelength wavelength;double yWa…...

《自动驾驶与机器人中的SLAM技术》之GNSS相关基础知识总结
简介 本篇基于对《自动驾驶与机器人中的SLAM技术》中的GNSS定位相关基础知识进行总结用于备忘 知识点整理 GNSS(全球卫星导航系统)定位原理 GNSS 通过测量自身与地球周围各卫星的距离来确定自身的位置 , 而与卫星的距离主要是通过测量时间间隔来确定的 GNSS与GPS的关系 GPS(…...

【前端|CSS系列第4篇】面试官:你了解居中布局吗?
欢迎来到前端CSS系列的第4篇教程!如果你正在寻找一种简单而又强大的前端技术,以使你的网页和应用程序看起来更加专业和美观,那么居中布局绝对是你不能错过的重要知识。 在前端开发中,实现居中布局是一项必备技能,无论…...
Frozen-Flask :将 Flask 应用“冻结”为静态文件
Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是:将一个 Flask Web 应用生成成纯静态 HTML 文件,从而可以部署到静态网站托管服务上,如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...
Python爬虫(二):爬虫完整流程
爬虫完整流程详解(7大核心步骤实战技巧) 一、爬虫完整工作流程 以下是爬虫开发的完整流程,我将结合具体技术点和实战经验展开说明: 1. 目标分析与前期准备 网站技术分析: 使用浏览器开发者工具(F12&…...
Linux云原生安全:零信任架构与机密计算
Linux云原生安全:零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言:云原生安全的范式革命 随着云原生技术的普及,安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测,到2025年,零信任架构将成为超…...
鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/
使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题:docker pull 失败 网络不同,需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...

C# 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...

初学 pytest 记录
安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...
重启Eureka集群中的节点,对已经注册的服务有什么影响
先看答案,如果正确地操作,重启Eureka集群中的节点,对已经注册的服务影响非常小,甚至可以做到无感知。 但如果操作不当,可能会引发短暂的服务发现问题。 下面我们从Eureka的核心工作原理来详细分析这个问题。 Eureka的…...
python报错No module named ‘tensorflow.keras‘
是由于不同版本的tensorflow下的keras所在的路径不同,结合所安装的tensorflow的目录结构修改from语句即可。 原语句: from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后: from tensorflow.python.keras.lay…...

技术栈RabbitMq的介绍和使用
目录 1. 什么是消息队列?2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...

android13 app的触摸问题定位分析流程
一、知识点 一般来说,触摸问题都是app层面出问题,我们可以在ViewRootImpl.java添加log的方式定位;如果是touchableRegion的计算问题,就会相对比较麻烦了,需要通过adb shell dumpsys input > input.log指令,且通过打印堆栈的方式,逐步定位问题,并找到修改方案。 问题…...