网站建设公司的问答营销案例,网络网站建设app,火车头 wordpress4.9,企业型网站建设步骤及注意事项Nginx学习#xff1a;响应头与Map变量操作 响应头是非常重要的内容#xff0c;浏览器或者客户端有很多东西可能都是根据响应头来进行判断操作的#xff0c;比如说最典型的 Content-Type #xff0c;之前我们也演示过#xff0c;直接设置一个空的 types 然后指定默认的数据… Nginx学习响应头与Map变量操作 响应头是非常重要的内容浏览器或者客户端有很多东西可能都是根据响应头来进行判断操作的比如说最典型的 Content-Type 之前我们也演示过直接设置一个空的 types 然后指定默认的数据类型的值所有的请求浏览器都会直接下载。另外我们现在在做前后分离的开发时也经常会通过头信息来传递一些标志参数那么自定义响应头的作用就更加重要了。另外一个 Map 部分则是 Nginx 中的一种变量设置方式话不多说直接开始吧。 今天学习的内容响应头部分都是可以设置在 http、server、location 中的有特殊情况的我会单独说。而 Map 部分则都是只能在 http 中进行配置。 响应头 在 Nginx 中响应头模块就是 ngx_http_headers_module 模块。总共就三个配置指令其实并不复杂。而且相信其中两个指令大家都至少是见过的。除了可以添加自定义的响应头之外在这个模块中还有一个非常重要的内容就是 HTTP 的 Expire 缓存设置。在最后我们将会统一进行一个测试先来看看响应头模块中的三个配置指令。 add_header 如果响应代码等于 200、201 (1.3.10)、204、206、301、302、303、304、307 (1.1.16、1.0.13) 或 308 (1.13)则将指定字段添加到响应标头。 add_header name value [always]; 默认值没有但是 Nginx 会默认帮我们添加一些响应头比如说 Server 显示 Nginx 版本号的还有 Content-Type 这个标准响应头。它的参数值可以包含变量最后的 always 表示忽略上面的那些状态码任何响应都返回这个响应头。 我们可以定义多个响应头如果当前的作用域中没有定义那么会从上一级继承。 如果是空的内容这个响应头不会返回。 add_trailer 如果响应代码等于 200、201、206、301、302、303、307 或 308则将指定字段添加到响应的末尾。 add_trailer name value [always]; 它的用法和 add_header 是一样的但是不好测据说是用在分段响应上的。不过我们之前在 Nginx学习HTTP核心模块十二内嵌变量https://mp.weixin.qq.com/s/0ks7GgfcvJpQp7mA1IgQcA 中讲过一个 $sent_trailer_[name] 变量大家还记得吧它可以获取到响应尾所添加的内容然后我们就可以输出到日志中。当时已经做过测试啦这里就不再重复说了。 expires 如果响应代码等于 200、201 (1.3.10)、204、206、301、302、303、304、307 (1.1.1)则启用或禁用添加或修改“Expires”和“Cache-Control”响应头字段。 expires [modified] time;
expires epoch | max | off; 默认值是 off 也就是关闭的任何响应都不会返回 Expire 和 Cache-Control 响应头。这个呀其实就是 HTTP 中的 Expire 和 Cache-Control 的基础知识相关的配置。比如我们查看一些网站的请求时会有一些静态资源像是 js 文件、图片之类的会返回 200 响应但是后面还会跟着一个 from memory cache 或者 from disk cache 。这种就是使用了 Expire 或 Cache-Control 缓存在缓存有效时间之内都会直接从本地读取缓存不会发送请求。 和 Last-Modified 以及 Etag 的区别就是这两个以文件的修改为主真的会发一个请求到服务器服务器判断没修改之后再返回 304 。而 Expire 和 Cache-Control 连请求都不会发必须强制刷新或者让浏览器不使用缓存。而且直接请求 URL 看不到效果需要是静态页面中通过 src 加载的内容才会走这个缓存。Expire 比较老一些新的是 Cache-Control 所以两个同时存在时会走 Cache-Control 。不过 Nginx 中这个配置指令会一起设置。 好了点到为止还不太清楚的小伙伴可以继续查阅相关资料哦。 正常来说这个 time 是要过期的时间长度比如 10 秒后过期写 10s 就好了。没错是当前时间加上 expires 设置的时间。如果使用 modified 则是当前访问路径的文件的修改时间加上 expires 的时间。注意服务端和客户端的时间要一致比如我之前测试时服务端虚拟机的时间比我的电脑慢了3分钟设置 10s 的缓存就一直都不会生效。 我们也可以通过 符号指定一个时间。 expires 15h30m; 这样就是指定当天的 15 点 30 分过期。 expires 还会影响到 Cache-Control 的值。 如果设置一个负数的话Cache-Control 会设置 no-cache 如果设置为非负数包括 0 的话Cache-Control 的 max-age 会等于这个数值 而真正的 Expire 响应头则是具体的 GMT 时间值也就是当前时间加上 expires 指定后的具体时间。 设置为 epoch 参数则表示永远不缓存对应的头信息为 “Expires” 设置成 “Thu, 01 Jan 1970 00:00:01 GMT” 而 “Cache-Control” 会设置成 “no-cache” 设置为 max 参数则表示永远不过期“Expires” 设置成 “Thu, 31 Dec 2037 23:55:55 GMT” 而 “Cache-Control” 会设置成 10 年。 最后一个参数的值可以是一个变量。 响应头测试 好了就这三个配置指令不多吧。但是如你对 HTTP 的基础知识真的都不清楚的话那就没别的办法了先自己测试一下明白是什么意思然后赶紧去恶补一下吧。 我们先写个 location 方便测试。 location /headers/ {alias html/;add_header PPOP abc$uri;add_header GET_VALUE $arg_a;add_trailer op def$uri;access_log logs/params2.log vvv;expires 10s;add_header Cache-Control public;
} 通过 alias 还是指向了 html 这个根目录主要是我比较懒不想多建目录啦。然后 add_header 的大家自己测试一下吧看看响应头会不会返回数据。注意第二个我们是接收的 $arg_[name] 这种形式的变量参数哦如果不传变量看看会不会有响应头返回回来。 然后就是 add_trailer 的测试上回我们只是大概说了下这回还是再简单的看一下。在 location 中我们将访问日志 access_log 配置为一个新的日志目录文件了并且指定了日志格式是 vvv 。然后我们需要再到 http 中添加一个配置。 // http 下
log_format vvv op_trailer$sent_trailer_op; 这个配置指令后面我们学习日志模块时会详细地再学习现在先这么配就好了。然后访问请求之后就可以在日志文件中看到信息了。 // params2.log
………………
op_trailerdef/headers/index.html
……………… 好了最后的重点就是对于 expires 的测试了。我们需要先创建一个静态文件然后加载一张图片。注意图片路径我也是走的上面配置的 headers 这个 location 直接走 /img/ 目录是不行的哦因为我们的 expires 是配置在这个 location 当中了。 // cache1.html
222111
img src/headers/img/1.jpeg width200px/ 然后开始请求访问并多次刷新。我们测试的 10s 需要注意测试机与当前主机的时间同步问题。另外还添加了一个 Cache-Control 头设置为 public 这个有啥用大家也可以自己查下哦都是基础知识。不用设置它也可以。 注意看第一次是 200 正常响应然后中间几次也是 200 但后面有了一个 memory cache 的标志了。查看 Nginx 的 access_log 也不会看到这些请求说明真的是没有发请求。然后 10s 后再请求一次会发现返回了一个 304 这是 Last-Modified 在起作用。同时Expire 也被更新了。之后的请求又开始 memory cache 了。 看到了吧这就是静态资源的多级缓存。在架构设计中缓存前推中最重要的就是 HTTP 的这两块缓存是非常重要的理论知识而且也是非常容易就通过配置能够实现的理论实践大家可以赶紧应用在自己的项目中哦。好处嘛减少流量带宽占用毕竟现在流量费也挺贵的好吧你不担心流量费但至少 access_log 文件还能小点是不是。 ps.去看看京东、淘宝、网易、新浪这些大网站是怎么设置过期时间的哦大部分图片可能都是 max 而 js、css 之类的则可能会比较短哦。 Map变量 之前我们学过的都是 Nginx 提供的系统变量这一次我们要自己设置变量啦。在 Nginx 中目前可知的设置变量的方法有三种分别是 set 指令、map 指令和正则方式。正则就是匹配之后那个 $1 这种。 set 指令我们后面再说今天先来看看 map 模块相关的指令。 map Map 模块 ngx_http_map_module 它可以创建变量但是它的值是取决于另外一个变量的。什么意思呢我们先来看看这个指令的介绍。 map string $variable { ... } 这参数有点怪呀第一个 string 表明要进行判断的值。第二个参数就是我们要创建的变量名称。后面花括号中的内容是对于那个 string 的匹配结果。来看一个例子。 map $arg_a $a {default 0;aaa 1;~.*aaa 2;aaa* 3;bbb 1;ccc 2;
}server {listen 8088;root html;location / {if ($a 1) {return 200 aaa$a;}if ($a 2) {return 200 bbb$a;}return 200 $a;
} 注意map 要放在 http 下面哦不能在 server 或 location 中。 在 map 中我们设置了第一个参数是 $arg_[name] 这个变量这样我们就可以通过 GET 参数 a 来传递值。第二个参数是赋值之后的变量名。 花括号中的内容是匹配规则可以看到 default 表示默认值aaa 是普通匹配~.*aaa 是正则匹配。意思就是请求中有一个 GET 参数是 a 并且参数的值是 aaa 那么 $a 的结果就是 1 如果是 xaaa 那么 $a 就是 2 如果是 aaa* 结果值就是 3 注意这个 * 没有特别含义的目前状态下是不能进行通配的其它两个不用说了吧如果不匹配或者没有这个 GET 参数的话返回 0 。 然后在下面的 location 中如果 $a 的值是 1 那么返回的结果前面加上 aaa 如果是 2结果前面加上 bbb 其它情况直接返回 $a 的值。 来测试一下吧。 [rootlocalhost ~]# curl http://127.0.0.1:8088/
0
[rootlocalhost ~]# curl http://127.0.0.1:8088/?aaaa
aaa1
[rootlocalhost ~]# curl http://127.0.0.1:8088/?awaaa
bbb2
[rootlocalhost ~]# curl http://127.0.0.1:8088/?accc
bbb2
[rootlocalhost ~]# curl http://127.0.0.1:8088/?addd
0 看出效果了吧是不是感觉似曾相识没错不要怀疑自己这就是编程语言中的 switch 。 第一个参数是一个 string 你也可以写一个固定的字符串但是那样就没意义了。因此map 通常都会配合系统提供的变量来进行操作比如官网的例子。 map $http_host $name {hostnames;default 0;example.com 1;*.example.com 1;example.org 2;*.example.org 2;.example.net 3;wap.* 4;
}map $http_user_agent $mobile {default 0;~Opera Mini 1;
} 第一个例子是对 Host 请求头进行匹配返回 $name 值。注意这里的 * 是可以通配的因为这是针对主机名的匹配其实走的是主机掩码就是域名那一套比如泛解析的掩码通配。可以加上一个 hostnames 参数就可以实现对主机名的通配这个 hostnames 需要放在最上面。 第二个例子可以用于判断浏览器类型比如说现在最常用的判断是否移动端或者判断是否是微信客户端然后通过这个变量就可以配合 if 指令进行跳转高大上吧 花括号中除了匹配规则、default 和 hostnames 之外 还有两个特殊的参数include 和 volatile 前者可以包含一个带有值的文件。可以有多个。后者可以表示该变量不可缓存。 另外如果正则、hostnames、还有普通匹配同时匹配到了怎么办呢那就是优先顺序的问题了嘛。 普通字符串值最高前面带 * 通配掩码的比如*.example.com后面带 * 通配掩码的比如mail.*第一个匹配的正则表达式在配置文件中的出现顺序默认 default 的值 map_hash_bucket_size 设置映射变量哈希表的存储桶大小。默认值取决于处理器的缓存线大小。 map_hash_bucket_size size; 默认值根据系统情况而定默认值是 32 或 64 或 128 。 map_hash_max_size 设置映射变量哈希表的最大大小。 map_hash_max_size size; 默认值是 2048。 设置哈希表 之前很多内容中其实都提到过哈希表这个东西今天就放到这里一起说明一下吧因为 Map 模块后面的两个配置指令也和这个东西有关以下是官方文档的解释。 为了快速处理静态的数据集合诸如虚拟主机名、 map指令的值、 MIME类型和请求头的字段名Nginx 使用了哈希表。在 Nginx 启动和更新配置的过程中它会尽可能为哈希表选择最小的容量 同时使每个哈希桶的长度不超过设置的配置参数。这些桶用于保存键和对应的哈希值。整个哈希表的容量以哈希桶的数量来定义。Nginx不断调整哈希表直到哈希表容量超过配置的最大值。大部分哈希表都有对应的指令允许修改这些配置参数。比如针对虚拟主机名的哈希表有server_names_hash_max_size 和 server_names_hash_bucket_size 两条指令。 哈希桶大小的参数会对齐到处理器缓存线长度的整数倍。这将加速哈希表中的键查找因为在现代的处理器上这可以减少内存访问的次数。如果哈希桶大小等于处理器的缓存线长度那么在最坏情况下键查找时的内存访问次数是两次—— 第一次是计算哈希桶的地址第二次是在哈希桶内进行键查找。因此如果nginx提示需要增大哈希表容量或者哈希桶大小时应优先增大前者。 说实话我也不懂是啥意思但看得出来 一是数据结构方面的问题哈希是空间换时间的一种策略因此占用的内存空间也不能无限大会有一个限制二是哈希表在 Nginx 启动时就把所有键值对确定了之后不能再添加修改开放地址法键的数量大于可能的值的数量不需要进行线性探测而且尽量选择最小值但是会通过哈希桶的数量来调整容量直到达到最大值三是有计算机原理中内存对齐的概念哈希表可以快速访问通过对齐能够减少内存访问次数CPU缓存四是如果 Nginx 日志中提示需要增大哈希表的话优先调整 xxxx_bucket_size 之类的指令大小也就是增大容量 其它的嘛哥们实在是无能为力了 只能帮到这里了。希望各位大佬有时间并且不小心看到这篇文章的话能够不吝赐教。 总结 今天的内容中add_header 确实是用过但是其它的说实话真的从来没接触过。没错你没看错干了这么些年直到现在我也没完全搞清楚 HTTP 中缓存的这些东西。但是通过学习今天的内容并且在写文章时不断地查阅资料这下真的算是彻底搞明白了 Expire 和 Last-Modified 这些东西到底是干嘛了。这下面试的时候总算不慌了当然是前提别人能给 35 快 40 的老码农一个能面试的机会。Cry.... 另外的 Map 模块其实也从来都没用过甚至之前都不知道有这个功能。毕竟在 Nginx 中如果需要定义变量的话set 指令真的很方便不过通过了今天的学习貌似 map 还是一个可以挖掘的宝藏功能哦而且它真的非常像 switch 的作用更加地灵活方便。 参考文档 http://nginx.org/en/docs/http/ngx_http_headers_module.html http://nginx.org/en/docs/http/ngx_http_map_module.html