Nginx(“engine x”)是一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP代理服务器。

0、正向代理与方向代理

在nginx.conf中,包含若干配置项。每个配置项由配置指令和指令参数2个部分构成。指令参数也就是配置指令对应的配置值。配置指令是一个字符串,可以用单引号或者双引号括起来,也可以不括。但是如果配置指令包含空格,一定要引起来。指令的参数使用一个或者多个空格或者TAB字符与指令分开。指令的参数有一个或者多个TOKEN串组成。TOKEN串之间由空格或者TAB键分隔。需要注意的是,其每一个指令都必须使用分号(;)结束,否则为语法错误。在location中开启自动列目录功能:autoindex on;
1、location优先级官方文档:
a、Directives with the = prefix that match the query exactly. If found, searching stops.
b、All remaining directives with conventional strings, longest match first. If this match used the ^~ prefix, searching stops.
c、Regular expressions, in order of definition in the configuration file.
d、If #3 yielded a match, that result is used. Else the match from #2 is used.

a、=前缀的指令严格匹配这个查询。如果找到,停止搜索。
b、所有剩下的常规字符串,最长的匹配。如果这个匹配使用^~前缀,搜索停止。
c、正则表达式,在配置文件中定义的顺序。
d、如果第3条规则产生匹配的话,结果被使用。否则,使用第2条规则的结果。
2、location demo

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
location  = / {
# 只匹配"/".
[ configuration A ]
}
location / {
# 匹配任何请求,因为所有请求都是以"/"开始
# 但是更长字符匹配或者正则表达式匹配会优先匹配
[ configuration B ]
}
location ^~ /images/ {
# 匹配任何以 /images/ 开始的请求,并停止匹配 其它location
[ configuration C ]
}
location ~* .(gif|jpg|jpeg)$ {
# 匹配以 gif, jpg, or jpeg结尾的请求.
# 但是所有 /images/ 目录的请求将由 [Configuration C]处理.
[ configuration D ]
}

请求URI例子:
/ -> 符合configuration A
/documents/document.html -> 符合configuration B
/images/1.gif -> 符合configuration C
/documents/1.jpg ->符合 configuration D

3、配置expires
expires起到控制页面缓存的作用,合理的配置expires可以减少很多对服务器的请求,要配置expires,可以在http段中或者server段中或者location段中加入:

1
2
3
4
5
//图片类型一般30天  js/css一般1小时
location ~ \.(gif|jpg|jpeg|png|bmp|ico)$ {
root /var/www/img/;
expires 30d;
}

expires指令可以控制HTTP应答中的“Expires”和“Cache-Control”的头标(起到控制页面缓存的作用):
语法:expires [time|epoch|max|off]
默认值:off
time:可以使用正数或负数。“Expires”头标的值将通过当前系统时间加上设定time值来设定。time值还控制”Cache-Control”的值:负数表示no-cache、正数或零表示max-age=time。
4、Expires步骤:
a、浏览器第一次请求资源,服务器在返回的同时,会在response的header上加上Expires。
b、浏览器收到资源后,把资源和Expires一起缓存下来。
c、第二次请求资源时,拿出Expires和当前请求时间比较下,如果还未过期,则直接从缓存中读取出来【这个就叫命中缓存】。
d、没有命中的话,去服务端请求,走协商缓存道路,最后返回时,会返回一个新的Expires,浏览器在缓存下来。
5、ETag、If-None-Match的缓存管理的方式是:
a、发送请求,返回资源的时候,也返回了一个ETag【文件的Hash值】。
b、浏览器缓存资源,并缓存下ETag。
c、再次请求的时候,Request Header If-None-Match把上次传过来的ETag传过去。
d、web服务器,在生成一个资源文件的ETag,然后跟传过来的比较。
e、一样,返回304 Not-Modified,浏览器从缓存拿。
f、不一样,web服务器返回资源,并返回一个新的ETag,然后重复上面操作。
6、在分布式部署的时候,多台机器的Last-Modified必须保持一致,否则协商缓存会出问题。分布式部署,不同的机器生成的ETag都会不一样。然后协商缓存就会出问题。【因此如果没有搞定ETag一致,就先关闭掉。】
7、必须开启强缓存,协商缓存才会起作用。强缓存:Expires、Cache-control;协商缓存:Last-Modified,If-Modified-Since、ETag、If-None-Match。
强缓存针对静态资源,动态资源不要,html资源不要。强缓存还有一点需要注意的是,通常都是针对静态资源使用,动态资源需要慎用,除了服务端页面可以看作动态资源外,那些引用静态资源的html也可以看作是动态资源,如果这种html也被缓存,当这些html更新之后,可能就没有机制能够通知浏览器这些html有更新。
8、如果资源已经被浏览器缓存下来,在缓存失效之前,再次请求时,默认会先检查是否命中强缓存,如果强缓存命中则直接读取缓存,如果强缓存没有命中则发请求到服务器检查是否命中协商缓存,如果协商缓存命中,则告诉浏览器还是可以从缓存读取,否则才从服务器返回最新的资源。这是默认的处理方式,这个方式可能被浏览器的行为改变:
a、当ctrl+f5强制刷新网页时,直接从服务器加载,跳过强缓存和协商缓存;
b、当f5刷新网页时,跳过强缓存,但是会检查协商缓存;(只是对url里对应的资源进行协商,该资源所引用的资源并不协商??)
9、
页面引用了3个css,而某次上线只改了其中的a.css,如果所有链接都更新版本,就会导致b.css,c.css的缓存也失效,那岂不是又有浪费了?!重新开启变态模式,我们不难发现,要解决这种问题,必须让url的修改与文件内容关联,也就是说,只有文件内容变化,才会导致相应url的变更,从而实现文件级别的精确缓存控制。什么东西与文件内容相关呢?我们会很自然的联想到利用数据摘要要算法对文件求摘要信息,摘要信息与文件内容一一对应,就有了一种可以精确到单个文件粒度的缓存控制依据了。好了,我们把url改成带摘要信息的:

这回再有文件修改,就只更新那个文件对应的url了,想到这里貌似很完美了。你觉得这就够了么?大公司告诉你:图样图森破!
现代互联网企业,为了进一步提升网站性能,会把静态资源和动态网页分集群部署,静态资源会被部署到CDN节点上,网页中引用的资源也会变成对应的部署路径:

好了,当我要更新静态资源的时候,同时也会更新html中的引用吧,就好像这样:

这次发布,同时改了页面结构和样式,也更新了静态资源对应的url地址,现在要发布代码上线,亲爱的前端研发同学,你来告诉我,咱们是先上线页面,还是先上线静态资源?
a、先部署页面,再部署资源:在二者部署的时间间隔内,如果有用户访问页面,就会在新的页面结构中加载旧的资源,并且把这个旧版本的资源当做新版本缓存起来,其结果就是:用户访问到了一个样式错乱的页面,除非手动刷新,否则在资源缓存过期之前,页面会一直执行错误。
b、先部署资源,再部署页面:在部署时间间隔之内,有旧版本资源本地缓存的用户访问网站,由于请求的页面是旧版本的,资源引用没有改变,浏览器将直接使用本地缓存,这种情况下页面展现正常;但没有本地缓存或者缓存过期的用户访问网站,就会出现旧版本页面加载新版本资源的情况,导致页面执行错误,但当页面完成部署,这部分用户再次访问页面又会恢复正常了。
上面一坨分析想说的就是:先部署谁都不成!都会导致部署过程中发生页面错乱的问题。所以,访问量不大的项目,可以让研发同学苦逼一把,等到半夜偷偷上线,先上静态资源,再部署页面,看起来问题少一些。但是,大公司超变态,没有这样的“绝对低峰期”,只有“相对低峰期”。So,为了稳定的服务,还得继续追求极致啊!这个奇葩问题,起源于资源的 覆盖式发布,用 待发布资源 覆盖 已发布资源,就有这种问题。解决它也好办,就是实现 非覆盖式发布。

看上图,用文件的摘要信息来对资源文件进行重命名,把摘要信息放到资源文件发布路径中,这样,内容有修改的资源就变成了一个新的文件发布到线上,不会覆盖已有的资源文件。上线过程中,先全量部署静态资源,再灰度部署页面,整个问题就比较完美的解决了。
所以,大公司的静态资源优化方案,基本上要实现这么几个东西:
a、配置超长时间的本地缓存 —— 节省带宽,提高性能
b、采用内容摘要作为缓存更新依据 —— 精确的缓存控制
c、静态资源CDN部署 —— 优化网络请求
d、更资源发布路径实现非覆盖式发布 —— 平滑升级

全套做下来,就是相对比较完整的静态资源缓存控制方案了,而且,还要注意的是,静态资源的缓存控制要求在前端所有静态资源加载的位置都要做这样的处理。是的,所有!什么js、css自不必说,还要包括js、css文件中引用的资源路径,由于涉及到摘要信息,引用资源的摘要信息也会引起引用文件本身的内容改变,从而形成级联的摘要变化,大概示意图就是:

10、配置proxy cache缓存:proxy cache缓存是nginx将静态资源存放到指定目录,缓存命中后直接返回,不需要再转发到后端获取,加快了请求速度同时也减轻了后端的压力。 在配置之前,先增加一个模块ngx_cache_purge,是用来手动清除缓存的。
11、

12、

Comments

去留言
2017-03-23

⬆︎TOP