nginx的反向代理

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

通常的代理服务器,只用于代理内部网络对Internet的连接请求,客户机必须指定代理服务器,并将本来要直接发送到Web服务器上的http请求发送到代理服务器中。当一个代理服务器能够代理外部网络上的主机,访问内部网络时,这种代理服务的方式称为反向代理服务。

nginx可以作为七层协议上的负载均衡主机,即在应用层上的负载均衡主机,七层负载是面向服务的,报文已经被转发至用户空间,这是不同于四层负载的地方(四层负载在内核(TCP协议栈)就被转发给后台RS)。

Nginx通过proxy模块实现反向代理功能。在作为web反向代理服务器时,nginx负责接收客户请求,并能够根据URI、客户端参数或其它的处理逻辑将用户请求调度至上游服务器上(upstream server)。nginx在实现反向代理功能时的最重要指令为proxy_pass,它能够将location定义的某URI代理至指定的上游服务器(组)上。

⑴proxy_pass URL;

       设置后端服务器的协议和地址;这条指令可以设置的协议是“http”或者“https”,而地址既可以使用域名或者IP地址加端口(可选)的形式来定义:

          proxy_pass http://localhost:8000/uri/;

       如果解析一个域名得到多个地址,所有的地址都会以轮转的方式被使用。当然,也可以使用服务器组来定义多个地址。

       如果proxy_pass没有使用URI,传送到后端服务器的请求URI一般是客户端发起的原始URI,如果nginx改变了请求URI,则请求路径与配置中的路径的匹配部分将被替换为指令中定义的URI:

         若nginx接到的请求的uri是/name/a.html

           location /name/ {
              proxy_pass http://192.168.30.20/remote/;
           } #传送到后端服务器的URI是/remote/a.html

           location /name/ {
              proxy_pass http://192.168.30.20;
           } #传送到后端服务器的URI是/name/a.html

           location /name/ {

              proxy_pass http://192.168.30.20/;

           } #注意与上面用法的区别,这里地址末尾带有斜线,实际上被认为定义了URI,该“/”会替换“/name/",传送到后端服务器的URI是/a.html。

    如果使用正则表达式定义路径,则proxy_pass指令不应使用URI

    location ~ \.php$ {
            proxy_pass   http://127.0.0.1;
        }

    在需要代理的路径中,使用rewrite指令改变了URI,那么nginx将使用重写后的URI处理请求,而忽略proxy_pass指令设置的URI。如下面所示的例子中,传送给上游服务器的URI为/index.php?page=<match>。

           location / {

             rewrite /(.*)$ /index.php?page=$1 break;

             proxy_pass http://localhost:8080;

           }

 

 ⑵proxy模块的其它指令

     ①proxy_connect_timeout time;

         与后端服务器建立连接的超时时间。一般不可能大于75秒;

     ②proxy_cookie_domain off;  #取消当前配置级别的所有proxy_cookie_domain指令

      proxy_cookie_domain domain replacement;

         设置“Set-Cookie”响应头中的domain属性的替换文本,其值可以为一个字符串、正则表达式的模式或一个引用的变量;例如:

           proxy_cookie_domain localhost example.org;

         说明:

           浏览器对 Cookie 有很多限制,如果 Cookie 的 Domain 部分与当前页面的 Domain 不匹配就无法写入。所以如果请求 A 域名,服务器 proxy_pass 到 B 域名,然后 B 服务器输出 Domian=B 的 Cookie,前端的页面依然停留在 A 域名上,于是浏览器就无法将 Cookie 写入。
           不仅是域名,浏览器对 Path 也有限制。我们经常会 proxy_pass 到目标服务0器的某个 Path 下,不把这个 Path 暴露给浏览器。这时候如果目标服务器的 Cookie 写死了 Path 也会出现 Cookie 无法写入的问题。

     ③proxy_cookie_path off;

      proxy_cookie_path path replacement;

         设置“Set-Cookie”响应头中的path属性的替换文本,其值可以为一个字符串、正则表达式的模式或一个引用的变量;例如:

           proxy_cookie_path /two/ /;           

           若“Set-Cookie”响应头含有属性“path=/two/some/uri/”,那么该指令会将这个属性改写为“path=/some/uri/”。

      ④proxy_hide_header field

         nginx默认不会将“Date”、“Server”、“X-Pad”,和“X-Accel-...”响应头发送给客户端。该指令则可以设置额外隐藏的响应头,这些响应头也不会发送给客户端。相反的,如果希望允许传递某些响应头给客户端,可以使用proxy_pass_header指令。

      ⑤proxy_set_header field value;

         重新定义或者添加发往后端服务器的请求头。value可以包含文本、变量或者它们的组合。例如:

           proxy_set_header X-Real-IP $remote_addr;   #给请求头中添加客户端IP

           proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;   

         默认情况下,只有两个请求头会被重新定义:

           proxy_set_header Host $proxy_host;
           proxy_set_header Connection close;

         如果某个请求头的值为空,那么这个请求头将不会传送给后端服务器:

           proxy_set_header Accept-Encoding "";

      ⑥proxy_pass_request_headers on|off;   #是否将http首部发往上游服务器

      ⑦proxy_pass_request_body on|off;  #是否将http请求报文的包体部分发往上游服务器

      ⑧proxy_redirect [default|off|redirect replacement];

         修改上游服务器传来的响应头中的"Location"和"Refresh"字段。例如:

           proxy_redirect http://localhost:8000/two/ http://frontend/one/;       

         replacement字符串可以省略服务器名:

           proxy_redirect http://localhost:8000/two/ /;

           此时将使用代理服务器的主域名和端口号来替换。如果端口是80,可以不加。

      ⑨proxy_send_timeout time;

         在连接断开之前两次发送至upstream server的写操作的最大间隔时长;

      ⑩proxy_read_timeout time;

         在连接断开之前两次从接收upstream server接收读操作的最大间隔时长;

 

    ⑶proxy模块的内置变量

      ①$proxy_host:后端服务器的主机名和端口;

      ②$proxy_port:后端服务器的端口;

      ③$proxy_add_x_forwarded_for

         将$remote_addr变量值添加在客户端“X-Forwarded-For”请求头的后面,并以逗号分隔。 如果客户端请求未携带“X-Forwarded-For”请求头,$proxy_add_x_forwarded_for变量值将与$remote_addr变量相同   

 

设置示例:

    proxy_redirect off; 
    proxy_set_header Host $host;    
    proxy_set_header X-Real-IP $remote_addr;    
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;    
    client_max_body_size 10m;    
    client_body_buffer_size 128k;    
    proxy_connect_timeout 30;    
    proxy_send_timeout 15;    
    proxy_read_timeout 15;

blob.png

blob.png

当在192.168.2.18的配置文件中定义了反向代理,指向192.168.2.29,此时我们访问192.168.2.18 就会把请求代理转发给192.168.2.29这台主机

 

 

二、缓存服务器功能

 

 nginx做为反向代理时,能够将来自上游服务器的响应缓存至本地,并在后续的客户端请求同样内容时直接从本地构造响应报文。nginx使用磁盘做缓存

nginx缓存大致上由两部分组成:

·        cache:共享内存(存储键和缓存对象元数据),查找在内存上

·        data:数据在磁盘空间

(1) proxy_cache_path:定义缓存空间(不能定义在server段中,定义在http段中),属于proxy模块

proxy_cache_path  [levels=levels] keys_zone=name:size [inactive=time] [max_size=size] [loader_files=number] [loader_sleep=time] [loader_threshold=time] ;定一个用记保存缓存响应报文的目录,及一个保存缓存对象的键及响应元数据的共享内存区域(keys_zone=name:size),其可选参数有:

levels:每级子目录名称的长度,有效值为1或2,每级之间使用冒号分隔,最多为3级;1:2表示两个级别目录,一级子目录由一个字符组成,二级子目录由二个字符组成
keys_zone:给共享内存命名,存储键的区域,可以定义多个区域,每个区域要有个名称引用。
inactive:非活动缓存项从缓存中剔除之前的最大缓存时长;
max_size:缓存空间大小的上限,当需要缓存的对象超出此空间限定时,缓存管理器将基于LRU算法对其进行清理;
loader_files:缓存加载器(cache_loader)的每次工作过程最多为多少个文件加载元数据;
loader_sleep:缓存加载器的每次迭代工作之后的睡眠时长;
loader_threashold:缓存加载器的最大睡眠时长;

如 proxy_cache_path /nginx/cache levels=1:1 keys_zone=nginx_cache:64m

(2) proxy_cache zone | off;   #定义一个用于缓存的共享内存区域,其可被多个地方调用;zone为我们之前定义的keys_zone名字,如之前的nginx_cache

(3)proxy_cache_min_uses:某响应报文被缓存之前至少应该被请求的次数;

(4) proxy_cache_lock on | off;   #启用此项,可在缓存未命令中阻止多个相同的请求同时发往upstream,其生效范围为worker级别

(5)proxy_cache_lock_timeout time;   #proxy_cache_lock功能的锁定时长;

(6)proxy_cache_min_uses number;   #某响应报文被缓存之前至少应该被请求的次数;

(7)proxy_cache_use_stale error | timeout | invalid_header | updating | http_500 | http_502 | http_503 |http_504 | http_403 | http_404 | off ... 在无法联系到upstream服务器时的哪种情形下(errortimeouthttp_500)nginx使用本地缓存的过期的缓存对象直接响应客户端请求

例如 proxy_cache_usr_stale error ;

(8)proxy_cache_valid [code ...] time;

 用于为不同的响应设定不同时长的有效缓存时长,例如: proxy_cache_valid  200 302  10m;为200和302响应设置缓存时长为10分钟

(9) proxy_cache_methods GET | HEAD | POST ...;   #为哪些请求方法启用缓存功能;默认GETHEAD

如proxy_cache_methods  GET;把GET请求给缓存

(10) proxy_cache_bypass string;

 设定在哪种情形下,nginx将不从缓存中取数据。例如:

proxy_cache_bypass $cookie_nocache $arg_nocache $arg_comment;

proxy_cache_bypass $http_pragma $http_authorization;

(11) proxy_cache_key string;   #设定在存储及检索缓存时用于“键”的字符串,可以使用变量为$uri其值,但使用不当时有可能会为同一个内容缓存多次;另外,将用户私有信息用于键可以避免将用户的私有信息返回给其它用户;

        例如:proxy_cache_key "$host$request_uri;

blob.png

blob.png

blob.png

blob.png

可见缓存之后访问速度提升还是非常明显的





负载均衡

负载均衡使用的是upstream模块,upstream模块可定义一个新的上下文,它包含了一组upstream服务器,这些服务器可能被赋予了不同的权重、不同的类型、可以检查各个负载服务器的状态甚至可以基于维护等原因被标记为down

配置语法:

       upstream 服务器列表名称 {

          server address [parameters];

          ...

       }

upstream模块常用的[parameters]指令有:

 

weight:权重;默认为1
max_fails=number;设定Nginx与服务器通信的尝试失败的次数。在fail_timeout参数定义的时间段内,如果失败的次数达到此值,Nginx就认为服务器不可用。在下一个fail_timeout时间段,服务器不会再被尝试。失败的尝试次数默认是1。设为0就会停止统计尝试次数,认为服务器是一直可用的。
fail_timeout=time   #默认是10秒
backup   #标记为备用服务器。当主服务器不可用以后,请求会被传给这些服务器。
down   #标记服务器永久不可用,可以跟ip_hash指令一起使用

upstream模块的其它负载均衡算法(用于upstream上下文):

       ①ip_hash;

          作用同lvs中的sh调度算法,将来自于同一个客户端的请求始终调度至同一台后端服务器(除了当服务器不可用的时候)

       ②least_conn;

          将请求发送到活动连接数最少的那台服务器。如果这样的服务器有多台,就尝试按加权轮循来调度

       ③sticky cookie name [expires=time] [domain=domain] [httponly] [secure] [path=path];

          session绑定,将来自于同一个客户端的请求始终调度至同一台后端服务器,从而实现客户端与后端服务器的session保持。

          ip_hash指令无法实现对内网NAT用户的均衡,而sticky指令可以做到;

          ◆sticky工作原理:             

             1.浏览器首次发起请求,请求头未带cookie。nginx接收请求,发现请求头没有cookie,则以轮询方式将请求代理给后端服务器。

             2.后端服务器处理完请求,将响应头和内容返回给nginx。

             3.nginx生成cookie,返回给客户端浏览器。cookie的值与后端服务器对应,可能是明文,也可能是md5、sha1等Hash值。

             4.浏览器接收请求,并创建cookie。

             5.浏览器再次发送请求时,带上cookie。

             6.nginx接收到cookie,直接转给对应的后端服务器

          参数说明:             

             domain:cookie作用的域名

             path:cookie作用的路径

             expires:cookie的过期时长

           7. health_check [interval=time] [fails=number] [passes=number] [uri=uri] [match=name];

        对上游服务器组进行健康状态检测,用于location中;

      参数说明:

        interval=time  #检测的间隔时长,默认为5秒

        fails=number   #连续检测失败多少次即认为上游服务器不可用,默认为1次

        passes=number  #上游服务器从不可用到可用状态时需要连续检测的次数,默认为1次

        uri=uri      #定义用于健康检测的URI,默认为“/”,即默认检测目标服务器的主页

        match=name    #指定一段配置来当作检测条件,默认当响应码为2XX或3XX时认为上游服务器是可用的

 

uptream使用注意:

       ①只能用于http上下文

       ②各server只能直接使用IP或主机名,不要加协议

    ⑶默认情况下,nginx按加权轮转的方式将请求代理到各上游服务器。与上游服务器通信的时候,如果出现错误,请求会被传给下一个服务器,直到所有可用的服务器都被尝试过。如果所有服务器都返回失败,客户端将会得到最后通信的那个服务器的(失败)响应结果。

    ⑷地址可以是域名或者IP地址,端口是可选的(默认是80),或者是指定“unix:”前缀的UNIX域套接字的路径。如果一个域名解析到多个IP,本质上是定义了多个server。

例如:

http{

    listen 80;

     upstream php_nginx{

        server 192.168.2.29 weight=2;

        server 192.168.2.30:8080 weight=3 max_fails=5 fail_timeout=30;

        server 192.168.2.109 backup;

    }

    location / {

    proxy_pass http://php_ngix;

    health_check interval=30 fails_time=5 url=/ match=check-php;

    }

    match check-php{

        status  200

       header Content-Type = text/html;

      body ~ "Welcome to nginx!";

          }

}

 实际上发现health_check 是在商业版本中的,下面换几种健康检查方法:

ngx_http_proxy_module 模块和ngx_http_upstream_module模块(自带)

 严格来说,nginx自带是没有针对负载均衡后端节点的健康检查的,但是可以通过默认自带的ngx_http_proxy_module 模块和ngx_http_upstream_module模块中的相关指令来完成当后端节点出现故障时,自动切换到健康节点来提供访问。
       这里列出这两个模块中相关的指令:
ngx_http_proxy_module 模块中的 proxy_connect_timeout 指令、proxy_read_timeout指令和proxy_next_upstream指令

proxy_connect_timeout:

语法: proxy_connect_timeout time; 
默认值:    proxy_connect_timeout 60s;
上下文:    http, server, location

设置与后端服务器建立连接的超时时间。应该注意这个超时一般不可能大于75秒。

 

proxy_read_timeout:

语法: proxy_read_timeout time;
默认值:    proxy_read_timeout 60s;
上下文:    http, server, location

定义从后端服务器读取响应的超时。此超时是指相邻两次读操作之间的最长时间间隔,而不是整个响应传输完成的最长时间。如果后端服务器在超时时间段内没有传输任何数据,连接将被关闭。

 

proxy_next_upstream:

语法: proxy_next_upstream error | timeout | invalid_header | http_500 | http_502 | http_503 | http_504 |http_404 | off ...;
默认值:    proxy_next_upstream error timeout;
上下文:    http, server, location

指定在何种情况下一个失败的请求应该被发送到下一台后端服务器:

error      # 和后端服务器建立连接时,或者向后端服务器发送请求时,或者从后端服务器接收响应头时,出现错误
timeout    # 和后端服务器建立连接时,或者向后端服务器发送请求时,或者从后端服务器接收响应头时,出现超时
invalid_header  # 后端服务器返回空响应或者非法响应头
http_500   # 后端服务器返回的响应状态码为500
http_502   # 后端服务器返回的响应状态码为502
http_503   # 后端服务器返回的响应状态码为503
http_504   # 后端服务器返回的响应状态码为504
http_404   # 后端服务器返回的响应状态码为404
off        # 停止将请求发送给下一台后端服务器

需要理解一点的是,只有在没有向客户端发送任何数据以前,将请求转给下一台后端服务器才是可行的。也就是说,如果在传输响应到客户端时出现错误或者超时,这类错误是不可能恢复的。

 

upstream里参数讲解:

max_fails=number      

# 设定Nginx与服务器通信的尝试失败的次数。在fail_timeout参数定义的时间段内,如果失败的次数达到此值,Nginx就认为服务器不可用。在下一个fail_timeout时间段,服务器不会再被尝试。 失败的尝试次数默认是1。设为0就会停止统计尝试次数,认为服务器是一直可用的。 你可以通过指令proxy_next_upstream、fastcgi_next_upstream和 memcached_next_upstream来配置什么是失败的尝试。 默认配置时,http_404状态不被认为是失败的尝试。


fail_timeout=time      

# 设定服务器被认为不可用的时间段以及统计失败尝试次数的时间段。在这段时间中,服务器失败次数达到指定的尝试次数,服务器就被认为不可用。默认情况下,该超时时间是10秒。


       在实际应用当中,如果你后端应用是能够快速重启的应用,比如nginx的话,自带的模块是可以满足需求的。但是需要注意。如果后端有不健康节点,负载均衡器依然会先把该请求转发给该不健康节点,然后再转发给别的节点,这样就会浪费一次转发。
       可是,如果当后端应用重启时,重启操作需要很久才能完成的时候就会有可能拖死整个负载均衡器。此时,由于无法准确判断节点健康状态,导致请求handle住,出现假死状态,最终整个负载均衡器上的所有节点都无法正常响应请求。如果公司的业务程序都是java开发的,因此后端主要是nginx集群和tomcat集群。由于tomcat重启应部署上面的业务不同,有些业务启动初始化时间过长,就会导致上述现象的发生,因此不是很建议使用该模式。
       并且ngx_http_upstream_module模块中的server指令中的max_fails参数设置值,也会和ngx_http_proxy_module 模块中的的proxy_next_upstream指令设置起冲突。比如如果将max_fails设置为0,则代表不对后端服务器进行健康检查,这样还会使fail_timeout参数失效(即不起作用)。此时,其实我们可以通过调节ngx_http_proxy_module 模块中的 proxy_connect_timeout 指令、proxy_read_timeout指令,通过将他们的值调低来发现不健康节点,进而将请求往健康节点转移。
       以上就是nginx自带的两个和后端健康检查相关的模块。

测试:

配置文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
upstream cluster_proxy {
 
     # simple round-robin
     server 172.16.204.130:8000 max_fails=2 fail_timeout=20s;
     server 172.16.204.130:8001 max_fails=2 fail_timeout=20s;
 
}
 
server {
     listen 80;
server_name nginx.proxy.com;
     access_log logs/nginx_proxy_access_log main;
 
     location / {
         proxy_pass http: //cluster_proxy;
         proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
     }
 
}

二、nginx_upstream_check_module模块

 除了自带的上述模块,还有一个更专业的模块,来专门提供负载均衡器内节点的健康检查的。这个就是淘宝技术团队开发的 nginx 模块 nginx_upstream_check_module,通过它可以用来检测后端 realserver 的健康状态。如果后端 realserver 不可用,则所以的请求就不会转发到该节点上。
       在淘宝自己的 tengine 上是自带了该模块的,大家可以访问淘宝tengine的官网来获取该版本的nginx,官方地址:http://tengine.taobao.org/
       如果我们没有使用淘宝的 tengine 的话,可以通过补丁的方式来添加该模块到我们自己的 nginx 中。模块官网:https://github.com/yaoweibin/nginx_upstream_check_module

 

安装git

# yum -y install git

下载源码

# git clone https://github.com/yaoweibin/nginx_upstream_check_module.git

下载nginx源码,跟进自己版本而定:http://nginx.org/download/

 

打补丁

进入nginx目录,需要注意,下载的nginx版本和补丁版本要严格对应

我下载的1.12.2 就要用1.12.1+的,版本请对应好!(FAQ:其他版本例如1.11.2如遇到以下问题:)

[root@liukaitest2 nginx-1.11.2]# patch -p1 < /root/software/nginx_upstream_check_module/check_1.11.1+.patch
can't find file to patch at input line 4
Perhaps you used the wrong -p or --strip option?
The text leading up to this was:
--------------------------
|diff --git src/http/modules/ngx_http_upstream_hash_module.c src/http/modules/ngx_http_upstream_hash_module.c
|--- src/http/modules/ngx_http_upstream_hash_module.c 2016-05-31 15:43:51.000000000 +0200
|+++ src/http/modules/ngx_http_upstream_hash_module.c 2016-06-22 17:20:19.553955295 +0200
--------------------------
File to patch:

请把patch -p1 改为 patch -p0

# cd nginx-1.12.2
# patch -p1 < ../nginx_upstream_check_module/check_1.12.1+.patch

 

编译nginx:

# ./configure --prefix=/usr/local/nginx \
--user=nginx --group=nginx \
--with-http_ssl_module \
--with-http_realip_module \
--with-http_addition_module \
--with-http_gzip_static_module \
--with-http_stub_status_module \
--with-http_sub_module \
--with-pcre \
--add-module=../nginx_upstream_check_module         #### 这个是必选,指向下载的补丁解压包。

测试:

配置文件:

复制代码

       upstream cluster {

            # simple round-robin
            server 172.16.204.130:8000;
            server 172.16.204.130:8001;

            check interval=1000 rise=1 fall=3 timeout=60000 type=http;


        }

        server {
            listen 80;
        server_name nginx.check.com;
            access_log logs/nginx_check_access_log main;

            location / {
                proxy_pass http://cluster;            }

            location /status {
                check_status;

                access_log   logs/nginx_check_status_access_log main;
           }
        }

复制代码

 

详细解释:

上面配置的意思是,对cluster这个负载均衡条目中的所有节点,每1000ms检测一次,请求1次正常则标记 realserver状态为up,如果检测 3 次都失败,则标记 realserver的状态为down,超时时间为60000ms,检测类型:http。

 

官网解释:

Syntax: check interval=milliseconds [fall=count] [rise=count] [timeout=milliseconds] [default_down=true|false] [type=tcp|http|ssl_hello|mysql|ajp] [port=check_port]
Default: 如果没有配置参数,默认值是:interval=30000 fall=5 rise=2 timeout=1000 default_down=true type=tcp
Context: upstream

 

中文详细解释:

 - interval:向后端发送的健康检查包的间隔。
    - fall(fall_count): 如果连续失败次数达到fall_count,服务器就被认为是down。
    - rise(rise_count): 如果连续成功次数达到rise_count,服务器就被认为是up。
    - timeout: 后端健康请求的超时时间。
    - default_down: 设定初始时服务器的状态,如果是true,就说明默认是down的,如果是false,就是up的。默认值是true,也就是一开始服务器认为是不可用,要等健康检查包达到一定成功次数以后才会被认为是健康的。
    - type:健康检查包的类型,现在支持以下多种类型
        - tcp:简单的tcp连接,如果连接成功,就说明后端正常。
        - ssl_hello:发送一个初始的SSL hello包并接受服务器的SSL hello包。
        - http:发送HTTP请求,通过后端的回复包的状态来判断后端是否存活。
        - mysql: 向mysql服务器连接,通过接收服务器的greeting包来判断后端是否存活。
        - ajp:向后端发送AJP协议的Cping包,通过接收Cpong包来判断后端是否存活。
    - port: 指定后端服务器的检查端口。你可以指定不同于真实服务的后端服务器的端口,比如后端提供的是443端口的应用,你可以去检查80端口的状态来判断后端健康状况。默认是0,表示跟后端server提供真实服务的端口一样。该选项出现于Tengine-1.4.0。

 

check_status:健康检查页面,可以通过域名/status(自定义配置) 查看节点状况。例如:

在生产环境的实施应用中,需要注意的有 2 点:
1、主要定义好type。由于默认的type是tcp类型,因此假设你服务启动,不管是否初始化完毕,它的端口都会起来,所以此时前段负载均衡器为认为该服务已经可用,其实是不可用状态。

2、注意check_http_send值的设定。由于它的默认值是"GET / HTTP/1.0\r\n\r\n"。假设你的应用是通过http://ip/name访问的,那么这里你的check_http_send值就需要更改为"GET /name HTTP/1.0\r\n\r\n"才可以。针对采用长连接进行检查的,这里增加keep-alive请求头,即"HEAD /name HTTP/1.1\r\nConnection: keep-alive\r\n\r\n"。如果你后端的tomcat是基于域名的多虚拟机,此时你需要通过check_http_send定义host,不然每次访问都是失败,范例:check_http_send "GET /mobileapi HTTP/1.0\r\n HOST www.redhat.sx\r\n\r\n";






fastcgi模块


nginx能够通过fastcgi模块实现将客户端的动态文件请求代理至fastcgi server例如PHP服务器,此时nginx与fastcgi server的通信是通过fastcgi协议进行的 。

⑴fastcgi模块的常用指令:

     ①fastcgi_pass address;  #指定fastcgi server的地址和端口,也支持使用unix sock;

         例如:

            fastcgi_pass localhost:9000;

            fastcgi_pass 192.168.30.20:9000;

            fastcgi_pass unix:/tmp/fastcgi.socket;

     ②fastcgi_bind address | off;   #指定联系fpm服务器时使用的地址;

     ③fastcgi_param parameter value [if_not_empty];

         定义传递给fastcgi server的参数;参数值可以是文本、变量或它们的组合,if_not_empty表示不为空时才传递

         例:fastcgi_param SCRIPT_FILENAME /web/scripts$fastcgi_script_name;

     ④fastcgi_index name;   #默认主页名;就是当URI中的文件名缺省时,使用此文件名

     ⑤fastcgi_connect_timeout time;   #连接fastcgi服务器的超时时长;

     ⑥fastcgi_send_timeout time;   #向fastcgi服务传输数据的超时时长;

⑵通常建议nginx和fastcgi server(如php-fpm)部署在同一台服务器上,因为二者如果通过网络通信的话会造成额外的性能开销。

 

配置示例:

location ~ \.php$ {

            root           /usr/share/nginx/html;

            fastcgi_pass   127.0.0.1:9000;

            fastcgi_index  index.php;

            fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;

            include        fastcgi_params;

        }

说明:

①参数SCRIPT_FILENAME保存是的脚本文件的绝对路径;例如,若请求的URI是/status.php,那么向fastcgi server传递的脚本文件路径就是/scripts/status.php

②nginx有两个文件fastcgi_params和fastcgi.conf,它们存放着nginx向fastcgi server传递的参数,二者唯一的区别是后者比前者多了一行 SCRIPT_FILENAME 的定义:

    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

 

测试:

我们首先 要在在server段里添加默认页面为index.php

如:indexindex.phpindex.html;

安装php-fpm;yum install php-fpm


我们要修改/etc/nginx/fastcgi_params如下:

fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
fastcgi_param  SERVER_SOFTWARE    nginx;

fastcgi_param  QUERY_STRING       $query_string;
fastcgi_param  REQUEST_METHOD     $request_method;
fastcgi_param  CONTENT_TYPE       $content_type;
fastcgi_param  CONTENT_LENGTH     $content_length;

fastcgi_param  SCRIPT_FILENAME    $document_root$fastcgi_script_name;
fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
fastcgi_param  REQUEST_URI        $request_uri;
fastcgi_param  DOCUMENT_URI       $document_uri;
fastcgi_param  DOCUMENT_ROOT      $document_root;
fastcgi_param  SERVER_PROTOCOL    $server_protocol;

fastcgi_param  REMOTE_ADDR        $remote_addr;
fastcgi_param  REMOTE_PORT        $remote_port;
fastcgi_param  SERVER_ADDR        $server_addr;
fastcgi_param  SERVER_PORT        $server_port;
fastcgi_param  SERVER_NAME        $server_name;

# PHP only, required if PHP was built with --enable-force-cgi-redirect
fastcgi_param  REDIRECT_STATUS    200;

在/usr/share/nginx/html下创建一个index.php文件如下:

<?php

      pgpinfo();

?>

运行php-fpm:

systemctl start php-fpm

nginx -t

nginx -s reload

浏览器访问192.168.2.18

blob.png


这里可以看出我们之前由于在测试httpd的时候pgp-mysql安装过,这里也同样支持

 

fastcgi 同样还支持fastcgi_cahe  、fastcgi_cache_path、fastcgi_cache_valid等,用法类似proxy_cahe