首页 > 代码库 > Nginx配置进阶(四)

Nginx配置进阶(四)

Nginx配置

============================================================================

概述:


====================================================================

Web 架构扩展思路

1.正向代理和反向代理:

正向代理

  • 定义:

        是一个位于客户端和原始服务器(origin server)之间的服务器,为了从原始服务器取得内容,客户端向代理发送一个请求并指定目标(原始服务器),然后代理向原始服务器转交请求并将获得的内容返回给客户端。客户端必须要进行一些特别的设置才能使用正向代理。

  • 通俗理解:

        主要就是代理客户端去访问互联网上各种各样的服务,是用来隐藏客户端的。

附图:

  正向代理

技术分享


反向代理(Reverse Proxy)

  • 定义:

        指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给internet上请求连接的客户端,此时代理服务器对外就表现为一个反向代理服务器。

  • 通俗的理解:

        向外宣称自己监听在某个端口之上,拥有某个服务,但本身并不提供任何内容,而是把相关的请求转发至后端主机来进行提供服务,用来隐藏服务端

附图:

 向代理

技术分享


两者区别

用途 上来讲:

  • 正向代理的典型用途是:为在防火墙内的局域网客户端提供访问Internet的途径。正向理还可以使用缓冲特性减少网络使用率。

  • 反向代理的典型用途是:将防火墙后面的服务器提供给Internet用户访问反向代理还可以为后端的多台服务器提供负载平衡,或为后端较慢的服务器提供缓冲服务另外,反向代理还可以启用高级URL策略和管理技术,从而使处于不同web服务器系统的web页面同时存在于同一个URL空间下。

安全性 来讲:

  • 正向代理允许客户端通过它访问任意网站并且隐藏客户端自身,因此你必须采取安全措施以确保仅为经过授权的客户端提供服务。

  • 反向代理对外都是透明的,访问者并不知道自己访问的是一个代理。


2.CDN和GSLB

CDN(Content Delivery Network)

  • 定义:

        CDN是构建在网络之上的内容分发网络,依靠部署在各地的边缘服务器,通过中心平台的负载均衡、内容分发、调度等功能模块,使用户就近获取所需内容,降低网络拥塞,提高用户访问响应速度和命中率。

  • CDN的关键技术

       内容存储和分发技术。

  • CDN的基本原理:

       是广泛采用各种缓存服务器,将这些缓存服务器分布到用户访问相对集中的地区或网络中,在用户访问网站时,利用全局负载技术将用户的访问指向距离最近的工作正常的缓存服务器上,由缓存服务器直接响应用户请求。

  • 目的

        是使用户可就近取得所需内容,解决 Internet网络拥挤的状况,提高用户访问网站的响应速度。

GSLB:Global Service LB全局负载均衡器)

  • 作用

      实现在广域网(包括互联网)上不同地域间的服务器的流量调配,保证使用最佳的服务器服务离自己最近的客户,从而确保访问质量。

附图:

技术分享


SLB:Service LB

应用程序发布:

  • 灰度模型

3.缓存服务器

定义:

  • 缓存指的是将需要频繁访问的网络内容存放在离用户较近、访问速度更快的系统中,以提高内容访问速度的一种技术。缓存服务器就是存放频繁访问内容的服务器。

  • 缓存提供了比将访问对象放在Internet Web服务器上更好的方法,它将需要频繁访问的Web页面和对象保存在离用户更近的系统中,当再次访问这些对象的时候加快了速度。

缓存服务器原理及应用模式:

Web缓存服务器的应用模式主要是正向代理反向代理

向代理(Proxy)模式

  • 代理网络用户访问internet,客户端将本来要直接发送到internet上源服务器的连接请求发送给代理服务器处理。正向代理的目的是加速用户在使用浏览器访问Internet时的请求响应时间,并提高广域网线路的利用率。正向代理浏览器无需和该站点建立联系,只访问到Web缓存即可。通过正向代理,大大提高了后续用户的访问速度,使他们无需再穿越Internet,只要从本地Web缓存就可以获取所需要的信息,避免了带宽问题,同时可以大量减少重复请求在网络上的传输,从而降低网络流量,节省资费。

反向代理(Reverse Proxy)模式

  • 针对Web服务器加速功能的,在该模式中,缓存服务器放置在web应用服务器的前面,当用户访问web应用服务器的时候,首先经过缓存服务器,并将用户的请求和应用服务器应答的内容写入缓存服务器中,从而为后续用户的访问提供更快的响应。

ngx_http_proxy_module模块:

1.proxy_pass URL

作用:

  • 将作为代理服务器,把客户端访问的资源的url映射到后端服务器;

使用位置(Context)

  • location, if in location, limit_except

三种使用情况:

proxy_pass后面的路径不带uri时,其会将location的uri传递给后端主机;

技术分享


proxy_pass后面的路径是一个uri时,其会将location的uri替换为proxy_pass的uri;

技术分享


如果location定义其uri时使用了正则表达式的模式,则proxy_pass之后必须不能使用uri; 用户请求时传递的uri将直接附加代理到的服务的之后;

技术分享




实验:验证nginx的返向代理:

1.实验环境

   准备两台虚拟主机,一台作为nginx反向代理服务器,另外一台作为后端web服务器;nginx代理服务器要有一个外网网卡保障和客户端通信,还要有一个内网网卡和后端主机通信;后端web服务器的内网要和nginx的内网在同一网段,这里虚拟机内网网卡采用的是VMnet1模式,进行通信。

2.实验环境搭建:

 1)首先部署好一台虚拟主机作为nginx反向代理服务器,外网网卡ip为10.1.252.161,内网ip为192.168.22.1

技术分享

 

  2)现在我们来部署后端web服务器,ip地址为192.168.22.2/24,并提供测试页面,这里为了实验,又创建了一个admin目录,并也提供了测试页,注意,这里后端主机不用指网关,因为他和代理服务器的内网就在同一网段,中间也没有路由,如果有路由的话,还是需要加网关的。

技术分享


 3)如上,整个实验的环境就已经搭建完成,我们启动后端web服务器,然后现在代理服务器上请求后端服务器,可以正常返回结果,如下:

技术分享

3.实验操作

 1)现在我们在nginx的代理服务器上去编辑其配置文件/etc/nginx/conf.d/defaut.conf,让其把所有内容代理至后端web服务器

技术分享

 启动nginx代理服务器,在浏览器中访问代理服务器10.1.252.161,发现直接代理至后端web服务器,如下:

技术分享

  上面是把root注释掉了,如果不注释,两个都存在的话,同样也会代理至后端服务器,即有proxy,root的存在就没有意义了。

 2)现在我们不代理整个根,我们只代理admin目录至后端服务器

技术分享

 ①首先不加admin用浏览器访问,则访问的是nginx代理服务器的默认测试页,如下:

技术分享

 ②加上admin目录,因为proxy后面有uri所以,会将其替换掉location的uri,即访问的是后端服务器的默认测试页,如下:

技术分享

 ③现在我们把proxy后面的uri去掉,这是会将location中的uri补到proxy的后面,即访问的是后算主机admin目录下的默认页面

技术分享

  访问如下:

技术分享


 3)我们也可以使用正则表达式匹配,把某些符合条件或者同一类资源的url,代理至后端服务器,假如,我这里只把图片类的资源代理至后端服务器

技术分享

 访问如下:

技术分享

 

   如此一来,我们就可以把不同的资源分发到不同的服务器上去运行了,如果我们把所有以.php结尾的动态资源代理到后端另外一台服务器,把根的静态资源代理至另外一台后端服务器,(location中正则表达式的优先级比不带符号的优先级高)这样我们就实现了动静分离


2.proxy_set_header field value;

作用:

  • 设定发往后端主机的请求报文的请求首部的值;

使用位置(Context)

  • http, server, location

  • proxy_set_header X-Real-IP  $remote_addr;

       直接记录前端主机的ip地址(如果前端主机不是客户端而是二级代理,则记录的还是而代理的值)

  • proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

       记录前端主机发请求时记录的proxy_add_x_forwarded_for的值

示例:

  1.因为后端的web主机接受的都是来自于nginx的代理服务器发送过来的请求,所以记录的日志当中都是nginx代理服务器的ip地址,我们查看后端主机的访问日志,如下:

技术分享

  2.我们要想让后端服务器能够记录来自客户端的请求的ip地址,就需要设定发往后端主机请求报文的首部信息了,如下:

技术分享

 然后我们修改后端web服务器的配置文件/etc/httpd/conf/httpd.conf,在日志项的配置中添加指定记录指定首部的值即可,如下:

技术分享

 再次用客户daunting去访问,发现成功记录到客户端的IP地址

技术分享


 2.proxy的缓存

proxy_cache_path

格式和适用位置:

Syntax: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];
    
Default:—    
Context:http

作用定义可用于proxy功能的缓存

参数:

  • levels=levels:缓存目录的层级数量,以及每一级的目录数量;

      levels=ONE:TWO:THREE  例如:leves=1:2:2(每一级为16进制数)

  • keys_zone=name:size

      k/v映射的内存空间的名称及大小

      缓存的组织方式:缓存是哈希值,而且对应的缓存文件名通常是文件内容的哈希内容,并且缓存层级是按照定义的多级结构去存放文件的;

  • inactive=time:非活动时长;

  • max_size=size:磁盘上用于缓存数据的缓存空间上限;

proxy_cache zone | off;

  • 作用:指明要调用的缓存,或关闭缓存机制;

  • 适用位置:http, server, location

proxy_cache_key string;

  • 作用:缓存中用于“键”的内容;

  • 默认值:proxy_cache_key $scheme$proxy_host$request_uri;(协议,代理的服务器,请求的uri)

proxy_cache_valid [code ...] time;

  • 作用:定义对特定响应码的响应内容的缓存时长;

配置示例:

技术分享

proxy_cache_use_stale

  • 语法,默认值及使用上下文

Syntax:proxy_cache_use_stale error | timeout | invalid_header | updating | http_500 | http_502 
| http_503 |http_504 | http_403 | http_404 | off ...;
    
Default:proxy_cache_use_stale off;
    
Context:http, server, location
  • 作用:当代理服务器与后端主机出现故障时,在后端服务器的相应结果为哪种情况下,可以直接用缓存中的缓存项(可能是过期的内容)来响应客户端;

proxy_cache_methods GET | HEAD | POST ...;

  • 作用:为哪些请求方法去检测使用缓存;

  • If the client request method is listed in this directive then the response will be cached. “GET” and “HEAD” methods are always added to the list, though it is recommended to specify them explicitly. 

==========================================================================

proxy_hide_header field;

  • 作用:指明要隐藏的后端主机响应报文的header,(即,指明哪些header不要传给客户端);

  • 默认情况下是nginx不传递header

proxy_connect_timeout time;

  • 作用:定义代理服务器与后端主机的连接超时时长;

  • 默认为60s,最大不能超过75s

buffer相关的配置;

定义调用缓存机制

 1)首先要创建一个缓存的文件目录,实际生产环境中可以放在固态磁盘上或者Raid0上,这样I/O能力很强;(注意文可能需要修改属主和属组为nginx)

[root@nginx nginx]# mkdir /var/cache/nginx/proxy_cache
[root@nginx nginx]# ls /var/cache/nginx/
client_temp  fastcgi_temp  proxy_cache  proxy_temp  scgi_temp  uwsgi_temp

[root@nginx ~]# ll -d /var/cache/nginx/proxy_cache
drwxr-xr-x 3 nginx root 14 Nov  1 14:57 /var/cache/nginx/proxy_cache

 2)因为缓存只能定义在http配置段,所以编辑主配置文件/etc/nginx/nginx.conf

技术分享

  3)如上,已经定义好了,只需要在打算缓存的地方调用缓存即可,比如这里,我们对图片作缓存,编辑配置文件/etc/nginx/conf.d/default.conf

技术分享

 4)定义好之后保存退出,检测语法,重载;然后用浏览器访问morning.jpg,查看缓存目录,已经记录缓存,如下:

[root@nginx ~]# tree /var/cache/nginx/proxy_cache
/var/cache/nginx/proxy_cache
└── 0
    └── 6
        └── 4
            └── 635450b5c68b27bfaa2e0065cb86c460

3 directories, 1 file

ngx_http_headers_module模块

  • The ngx_http_headers_module module allows adding the “Expires” and “Cache-Control” header fields, and arbitrary fields, to a response header.

作用:

  • 向由代理服务器响应给客户端的响应报文添加自定义首部,或修改指定首部的值;

add_header name value [always];

  • 作用:添加自定义首部;

  • 常用定义:

       add_header X-Via  $server_addr;  代理服务器的地址

       add_header X-Accel $server_name; 代理服务器的名称

expires [modified] time;

    expires epoch | max | off;

  • 作用:用于定义Expire或Cache-Control首部的值;即:设定响应报文的过期时长。

示例:

  向响应报文中,指明客户端请求的内容是经由nginx代理服务器发送的(指明nginx代理服务器ip),编辑配置文件/etc/nginx/conf.d/default.conf

技术分享

 浏览器访问可以看到经由的nginxIP地址,如下:

技术分享


注意:

  nginx向后端代理时,具体要使用http_proxy模块,还是fastcgi模块,取决于后端服务器所支持的协议。如果后端主机为amp,则只能使用http_proxy模块,因为我们面向客户端提供服务的是httpd的http协议或者https协议。如果,后端主机为fpm server时,才能够使用fastcgi模块。

======================================================================================

ngx_http_upstream_module模块 

功用:用于定义可以引用的服务器组,并定义这些服务器组的调度方法,从而完成能够将多台服务器,在面向前端的代理服务器请求时,可以以负载均衡的方式进行响应

upstream name { ... }

  • 作用:定义后端服务器组,会引入一个新的上下文;

  • Context(使用位置): http

示例:

upstream backend {
    server backend1.example.com weight=5;
    server 127.0.0.1:8080       max_fails=3 fail_timeout=30s;
    server unix:/tmp/backend3;

    server backup1.example.com  backup;
}

server address [parameters];

  • 作用:在upstream上下文中server成员,以及相关的参数;

  • Context:upstream

address的表示格式:

  • unix:/PATH/TO/SOME_SOCK_FILE

       某个套接字文件,要确保web服务器一定得是当前反代服务器上的web服务才可以;只能完成本地通信

  • IP[:PORT]

  • HOSTNAME[:PORT]

      后端主机有基于主机名的虚拟主机,则向后端反代时会指向这个特定的虚拟主机,而不是默认虚拟主机

parameters:

  • weight=number

      权重,默认为1;

  • max_fails=number

      失败尝试最大次数;超出此处指定的次数时,server将被标记为不可用;

  • fail_timeout=time

      设置将服务器标记为不可用状态的超时时长;

  • max_conns

  • backup

  • down

实验:定义使用nginx以负载均衡的方式进行响应

 1.在上面实验nginx反代单台后端主机的基础上,我们再添加一台虚拟主机作为后端服务器web2,配置方法同上面后端web主机1(VMnat1模式,为内网地址),并提供默认测试页面如下:

技术分享

技术分享


2.实验:实现将用户的请求代理至后端的服务器组

  1)首先编辑主配置文件/etc/nginx/nginx.conf,在http段的上下文中定义upstream服务器组;

技术分享

  2)然后,编辑配置文件/etc/nginx/conf.d/default.conf(上例中的配置已经清空,这是原始配置文件),使nginx反代至upstream组,如下:

技术分享

  配置好之后,保存,重载,使用浏览器访问,可以发现后端两台web服务器以轮询的方式响应

技术分享

  3)现在我们再来编辑主配置文件/etc/nginx/nginx.conf,在web1上添加权重wegit 2

技术分享   再次测试,发现权重打的web1,响应的次数多

技术分享

 

 4)现在我们来设置max_fails的值等于2,也就是说如果请求两次失败以后就标记为不可用,如下:

技术分享

  我们现在把后端web2服务器httpd停掉,再去访问,发现停掉web2之后,nginx代理服务器只向web1服务器调度;

技术分享

 然后我们把停止服务的web2再启动起来,发现一段时间之后,又可以正常被调度至web2的服务之上了

技术分享


  5)如果在一个服务器后面添加backup参数,则表示这个服务器为备用服务器。只用当所有的后端服务器全都不能正常工作时,这台备用服务器才启用,开始工作;只要有一台后端服务器恢复工作,则备用服务器就停止工作。

  6)如果在一个服务器的后面添加参数down,则表示这个服务器不可用,一般在应用程序发布,灰度模型时使用,如果服务器调试好要上线,只要把down去掉即可


 2.其他调度算法

least_conn;

  • 最少连接调度算法,当server拥有不同的权重时其为wlc;

ip_hash;

  • 源地址hash调度方法;

hash key [consistent];

  • 基于指定的key的hash表来实现对请求的调度,此处的key可以直接文本、变量或二者的组合;

  • 作用:将请求分类,同一类请求将发往同一个upstream server;

  • If the consistent parameter is specified the ketama consistent hashing method will be used instead.

技术分享


keepalive connections;

  • 为每个worker进程保留的空闲的长连接数量;


示例:

 1.ip_hash算法:

 在上例的基础上,我们采用ip_hash的调度方法,同样编辑配置文件如下:

技术分享

 使用curl命令访问可以发现第一次访问被调度的的后端服务器将始终为这个客户端提供服务,如下:

技术分享


2.hash key算法

 1)我们现在对客户请求的url做哈希算法,为了验证此算法,现在我们在后端的两台主机分别创建10个文件(url),url的名称都是相同的,内容不同,以此来判断到底是来自后端的哪个主机,如下:

技术分享技术分享

 现在我们不添加调度算法,对test0.html请求,可以发现,在后端的两台服务器上做轮询,如下:

[root@CentOS6 ~]# for i in {1..10};do curl http://10.1.252.161/test0.html;done
Test Page 0 ON Server 1
Test Page 0 ON Server 2
Test Page 0 ON Server 1
Test Page 0 ON Server 2
Test Page 0 ON Server 1
Test Page 0 ON Server 2
Test Page 0 ON Server 1
Test Page 0 ON Server 2
Test Page 0 ON Server 1
Test Page 0 ON Server 2

 2)现在我们把用户请求的uri做哈希运算作为调度算法,编辑配置文件如下:

技术分享

 测试我们发现,只要第一次请求的uri调度到后端某台服务器,将会一直在此服务器之上,如下:

[root@CentOS6 ~]# for i in {1..10};do curl http://10.1.252.161/test0.html;done
Test Page 0 ON Server 2
Test Page 0 ON Server 2
Test Page 0 ON Server 2
Test Page 0 ON Server 2
Test Page 0 ON Server 2
Test Page 0 ON Server 2
Test Page 0 ON Server 2
Test Page 0 ON Server 2
Test Page 0 ON Server 2
Test Page 0 ON Server 2
[root@CentOS6 ~]# for i in {1..10};do curl http://10.1.252.161/test5.html;done
Test Page 5 ON Server 1
Test Page 5 ON Server 1
Test Page 5 ON Server 1
Test Page 5 ON Server 1
Test Page 5 ON Server 1
Test Page 5 ON Server 1
Test Page 5 ON Server 1
Test Page 5 ON Server 1
Test Page 5 ON Server 1
Test Page 5 ON Server 1
[root@CentOS6 ~]# for i in {1..10};do curl http://10.1.252.161/test3.html;done
Test Page 3 ON Server 2
Test Page 3 ON Server 2
Test Page 3 ON Server 2
Test Page 3 ON Server 2
Test Page 3 ON Server 2
Test Page 3 ON Server 2
Test Page 3 ON Server 2
Test Page 3 ON Server 2
Test Page 3 ON Server 2
Test Page 3 ON Server 2
[root@CentOS6 ~]# for i in {1..10};do curl http://10.1.252.161/test0.html;done
Test Page 0 ON Server 2
Test Page 0 ON Server 2
Test Page 0 ON Server 2
Test Page 0 ON Server 2
Test Page 0 ON Server 2
Test Page 0 ON Server 2
Test Page 0 ON Server 2
Test Page 0 ON Server 2
Test Page 0 ON Server 2
Test Page 0 ON Server 2

ngx_stream_core_module模块

功用:模拟反代基于tcp或udp的服务连接,即工作于传输层的反代或调度器;

upstre














Nginx配置进阶(四)