前置知识章节:
1.介绍、安装、hello world、location匹配 ✅
2.▶▶反向代理、负载均衡、缓存服务、静态资源访问✅
3.日志管理、http限流、https配置,http_rewrite模块,第三方模块安装,结语。✅html
💡代理有正向代理和反向代理
💡正向代理:
所谓的正向,就是以请求发起为角度的,此时代理的是用户发起的请求。
用户A没法访问G网,但A能访问B网,而B网能访问G网。那么若是A先经过访问B网,B网帮他访问G网,返回数据给他,那么此时B网就做为了一个代理服务器,并且是正向代理。此时A实际上是知道它要访问G网的,G网并不知道是A访问它的,因此此时是代理了A,正向代理。前端
💡反向代理:
相对于正向代理的代理用户发起的请求,反向代理代理的是资源服务器的请求。
用户A访问B网的某个资源,但B网没有,而后它发给C网,C网返回给B网,B网返回给C网。此时用户A不知道它访问的是C网,因此此时代理的是C网,反向代理。
场景通常是,A能访问B,但不能访问C,B能访问C。咱们使用B这台机来对外提供服务,让关于C的请求都先通过B,B再请求C来返回结果。
反向代理有时候用在内网中,用来作请求转发到内网,这样必定程度的保护了内网的资源和利用上了内网的服务器。固然对于咱们业务来讲,服务器有可能并非部署在内网中的,也能够用在外网服务器代理上。java
💡反向代理是一个很是重要的功能,能够说nginx你最经常使用的功能或许就是反向代理了,动静分离、负载均衡和缓存有时候你可能用不上。nginx
咱们首先须要建立一个web服务端,因为我是主攻java的,因此我这里部署一个java的web服务器,并让他监听8081端口。(192.168.48.131是个人虚拟机的IP,nginx和这个java web服务端都部署在这里。)
访问一下这个要被代理的服务端的接口http://192.168.48.131:8081/user/list
,发现调用成功。
git
💡2.1 修改server:
由于此时是做为一个代理服务器,因此咱们要新建一个server块来充当代理服务器。
❓有人有点疑惑,上面的例子只配了location,咱们为何要配server呢?
其实这里是从业务需求来作区分的。由于咱们如今的目标是弄一个代理服务器,固然了你也能够不建立,而后把下面的location放到以前的server下便可。何时是必须建立的呢?当server_name不同的时候,但这个也是须要你根据业务来判断的,好比你本来使用80端口接收发过来的请求,而如今使用8080端口接收发过来的请求的时候就须要一个新的server_name。
这里新建一个server其实也有介绍server_name的用法的意思。github
修改server_name:server_name是当前服务端监听的地址的意思,
server_name支持几种语法:web
server_name example.com www.example.com
*
只能使用在开头或者结尾,不能使用在中间。当有多个匹配结果的时候,会选择最长的匹配结果。server_name *.example.com www.example.*
server_name ~^www\d+\.example\.com$;
💡2.2 修改location
🔵proxy_pass
用于设置被代理服务器的地址,能够是主机名称(https://www.baidu.com
这样的)、IP地址(域名加端口号)的形式。
🔵下面的这个location的意思是,若是请求路径开头是/api的,那么都代理到proxy_pass指定的地址,好比访问了/api/user/list
,那么获得的结果是http://localhost:8081/user/list
的结果。正则表达式
server { listen 8080; location /api/ { proxy_pass http://localhost:8081/; } }
🔵在lcoation都是location /api/
时,proxy_pass不一样,请求的资源也是不同的:redis
proxy_pass http://localhost:8081;
:请求nginx主机IP:8080/api/user/list
,nginx会将该请求代理转发到http://locahost:8081/api/user/list
。proxy_pass http://localhost:8081/;
:请求nginx主机IP:8080/api/user/list
,nginx会将该请求代理转发到http://locahost:8081/user/list
。proxy_pass http://localhost:8081/test;
请求nginx主机IP:8080/api/user/list
,nginx会将该请求代理转发到http://locahost:8081/testuser/list
。proxy_pass http://localhost:8081/test/;
请求nginx主机IP:8080/api/user/list
,nginx会将该请求代理转发到http://locahost:8081/test/user/list
。在前面,我建立了一个8081的web服务端,并且http://nginx服务器IP:8081/user/list
是有一个接口的.
咱们试一下使用8080来代理一下这个8081这个服务端:
注意下面的这个server若是写在default.conf的时候,是与其它server块同级的。
后端
若是咱们可以经过8080来访问到http://192.168.48.131:8081/user/list
这个接口,那么就说明了咱们的反向代理成功了。此时发向8080端口的,以/api
开头的请求都会代理到8081中。
负载均衡其实也算是基于反向代理的。
上面的反向代理提到一点反向代理能够为咱们的服务端进行代理,你有时候多是多个服务端提供同一功能的,为了让他们可以平摊压力,那么你可能须要负载均衡功能。
🔴准备负载均衡用的业务服务端,我这里给的是一个java Spring Boot端的简单代码,我部署成多个服务端的时候,因为端口不一样,访问info接口返回的数据也不一样,这样就能够测试是否达到了负载均衡。
🔴部署服务端,使用--server.port
来部署到不一样的端口,例如java -jar a-simple-web-0.0.2-SNAPSHOT.jar --server.port=8082
就把个人jar程序部署到了8082端口。
咱们这里新建一个conf.d/loadbalance.conf
,因为nginx.conf内部有一个include /etc/nginx/conf.d/*.conf;
能够把conf.d下的配置文件都导入到nginx.conf的http块中,因此咱们新建的这个conf也是能够导入到nginx.conf中的。
访问http://192.168.31.128:9001/user/info
,看是不是轮询的分发请求,若是响应的时候返回了不一样的端口,那么就证实了是轮询的分发请求。
💡默认轮询负载均衡:在不指定负载均衡策略的时候,默认的策略是按顺序给负载均衡服务端发送请求,而且一次顺序中每一个服务端处理两次请求,好比两个服务端,那么就是AABBAABB这样循环下去。 若是服务端有宕机的,会从负载均衡顺序中去除。等到宕机的服务端可用后,会在30S(好像是)以后加入到可用负载均衡服务端列表中。
💡加权轮询负载均衡:在轮询的基础上加上权重的考虑,假如服务端A的权重是1,服务端B的权重是2,那么6个请求中,服务端A会收到2个请求,服务端B会收到4个请求。
💡ip_hash负载均衡:每一个请求按ip的哈希结果分配到指定的负载服务端响应,(原理相似求余数,把服务端排序以后,根据哈希处理再处理以后获得的余数来选取服务端),这样同一个ip响应的服务端是固定的。能够在必定程度解决服务端Session共享的问题。但这样可能负载压力就分配的不平均了。
语法例子:
upstream ip-hash { ip_hash; server localhost:8081; server localhost:8082; }
💡也可使用第三方模块来负载均衡。但因为咱们上面没有讲过第三方模块,引入前置知识须要占用大量篇幅,因此这里只引出一下,有须要的自查吧。
上面介绍了使用weight参数来实现加权轮询负载均衡,其实还有一些其余的参数。
upstream web-server { server localhost:8081 max_fails=1 fail_timeout=10; server localhost:8082; server localhost:8083 backup; server localhost:8084 down; }
💡使用ip_hash时,不能使用weight和backup。
💡在浏览器访问某个网站的资源的时候,会看浏览器是否缓存了这个数据。若是本地有这个缓存数据,那么就会直接从本地中获取了,不会再请求网络了。这是客户端缓存。nginx传递的响应的某些数据会影响浏览器是否缓存数据以及缓存多久。
💡除了客户端缓存,还有一种代理缓存nginx的缓存是代理缓存,由于它实际上是将代理的服务端的结果缓存了。代理缓存使用ngx_http_proxy_module的指令来配置。
💡(除了这两种,还有(后端)服务端缓存,也就是使用redis等技术进行的后端服务端缓存。)。
💡proxy_cache_path path
:用来定义缓存文件路径。只能用在http块。
语法:
proxy_cache_path path [levels=levels] [use_temp_path=on|off] keys_zone=name:size [inactive=time] [max_size=size] [manager_files=number] [manager_sleep=time] [manager_threshold=time] [loader_files=number] [loader_sleep=time] [loader_threshold=time] [purger=on|off] [purger_files=number] [purger_sleep=time] [purger_threshold=time];
1
),两层(1:2
),三层(1:2:2
)。目录会根据请求URL地址的哈希结果来建立(从末尾开始截取,),假如哈希结果是9cad383e7b0ee3d1d4b7099aace20b3f
,那么levels=1:2
表明第一层目录为长度为一的字符f
,第二层是长度为2的字符b3
。💡proxy_cache zone|off
:能够用在http, server, location。zone是proxy_cache_path的keys_zone.
💡proxy_cache_valid [code...] time
:缓存过时周期,过时以后就不返回代理缓存了。 code是http状态码。
💡proxy_cache_key string
:配置缓存的标识,好比说请求不同的话那确定不返回一样的代理缓存了,这就是是否返回同一个缓存的区分标识。默认值是proxy_cache_key $scheme$proxy_host$request_uri;
,能够用在http, server, location。其余例子:proxy_cache_key $scheme$proxy_host$uri$args;
下面来作一个实验:尝试使用nginx的代理缓存做为代理的响应。
1.咱们新建一个后端接口。这个后端接口能在每一次访问的时候都在控制台打印出一个消息(下面是一个Spring Boot例子):
2.配置反向代理:
3.一开始先测试一下http://192.168.31.128/api/user/info
,看每一次访问是否都向后端发起了请求,确实是每一次都发请求的:
4.而后配置代理缓存:
5.再次测试访问http://192.168.31.128/api/user/info
是否每一次访问都向后端发起了请求,结果应该是后端服务端只会打出一次,或者你能够尝试关闭后端服务端,而后访问,若是仍是可以访问,那么应该是已经代理缓存成功了。
💡永久缓存:上面使用proxy_cache配置的实际上是临时缓存。也就是说必定时间后会自动过时。若是你的数据在很长很长时间都不会过时,那么能够考虑使用proxy_store.
💡若是你想让部分请求不要缓存,可使用proxy_no_cache [string...]
,string能够是变量,若是存在某个string值不为空也不为0,那么此请求不会被缓存。
💡缓存清理:incative配置会帮咱们清除过时的缓存文件,但还没过时的不会清除,须要咱们手动清除(场景是好比说你更新了大量数据,此时缓存中的数据不少都错误了,此时须要清除全部缓存。),若是你须要清除的话,那么一种方法是手动定义一个Linux脚原本清除缓存;一种方法是使用模块nginx-cache-purge。这些因为篇幅问题,不讲述。
浏览器是怎么判断缓存是否须要使用本地缓存以及缓存是否过时的呢?它经过响应头中的expire
,cache-control
,Last-Modified
,Etag
等头信息来判断的。
expire
,Cache-control(max-age)
,若是有本地缓存,那么会使用expire来判断是否过时,不过时,直接使用本地缓存,本地过时以后,再进行远程校验。Thu, 02 Jul 2020 01:05:03 GMT
,若是校验时间不一致,那么不使用本地缓存,一致则使用本地缓存。"5efd32bf-3fa8e"
,若是校验时间不一致,那么不使用本地缓存,一致则使用本地缓存。Etag与Last-Modified的区别是,Etag更精确,因此会优先判断Etag,而后再判断Last-Modified。❗浏览器缓存机制你能够本身了解一下:博客园-HTTP缓存机制。
💡Expire
expires [modified] time;
expires modified +24h;
就表明修改后24小时内不过时。expires 24h;
24天不过时,expires 30d;
30天不过时,expires -1;
表明永不过时测试以前咱们先要提几点:
F5刷新
和Ctrl+F5刷新
就无效,此时测试应该使用在连接栏按回车发请求来测试。expires可用于什么状况能够参考博客园-HTTP缓存机制。1.咱们先在/usr/share/nginx/html
下面存储一张图片,后面会经过访问这种图片,来测试客户端缓存。
2.咱们一开始先不要配置expires:
server { listen 80; server_name 127.0.0.1; location / { root /usr/share/nginx/html; } }
3.屡次访问一下http://192.168.31.128/a.jpg
看看nginx的访问日志/var/log/nginx/access.log
是否有添加
此时要多留意每次请求的响应码,应当有如下几个状况:
4.加了expires以后看看,咱们简单的使用两分钟看看。
server { listen 80; server_name 127.0.0.1; location / { expires 2m; root /usr/share/nginx/html; } }
5.屡次访问一下http://192.168.31.128/a.jpg
看看nginx的访问日志是否有添加
💡nginx能够对外接收静态资源访问的请求。
💡在上面的location的内容的时候,其实有讲到返回文件资源的知识。
好比location ~* \.(gif|jpg|jpeg)$
匹配任何以.gif、.jpg 或 .jpeg 结尾的请求,而后你发的请求匹配成功的时候,会使用root+location获得的路径的资源做为响应。其实这些也就是静态资源了,因此其实也能够经过nginx来达到静态资源的访问。
💡在先后端分离以后,前端做为静态资源访问,应该部署到哪里呢?由于咱们此时是不该该把前端静态资源部署到后端服务器上的。那么这时候放到nginx服务端上也是能够的。利用nginx的静态资源访问做为前端的服务端。
💡或者你也能够把nginx做为文件资源访问的服务端。