nginx详解(三)―FastCGI、https、动静分离、proxy、upstream和cache

    nginx同样支持FastCGI,这里使用Centos6.4平台、nginx-1.4.2、mysql-5.5.28、php-5.4.19,为了后面配置https,所以主机IP:172.16.100.1,主机名:www.yh.com

    鉴于这里为延时FastCGI模块,所以直接从配置FastCGI服务器开始讲起:


php服务器配置:

1、为php提供配置文件:

# cp php.ini-production /etc/php.ini

2、为php-fpm提供Sysv init脚本,并添加至服务列表。

# cp sapi/fpm/init.d.php-fpm  /etc/rc.d/init.d/php-fpm
# chmod +x /etc/rc.d/init.d/php-fpm
# chkconfig --add php-fpm
# chkconfig php-fpm on

3、为php-fpm提供配置文件。

# cp /usr/local/php/etc/php-fpm.conf.default /usr/local/php/etc/php-fpm.conf

4、编辑php-fpm的配置文件:

# vim /usr/local/php/etc/php-fpm.conf

    配置fpm的相关选项为你所需要的值,并启用pid文件(如下最后一行):

pm.max_children = 150
pm.start_servers = 8
pm.min_spare_servers = 5
pm.max_spare_servers = 10
pid = /usr/local/php/var/run/php-fpm.pid

    另为了方便查看php-fpm的启动、停止的状态信息,仍需要做如下配置:

[ -f /etc/rc.d/init.d/functions ] && . /etc/rc.d/init.d/functions
daemon $php_fpm_BIN --daemonize $php_opts(只是添加一个daemon)

    接下来就可以启动php-fpm了:

# service php-fpm start

    使用如下命令来验正(如果此命令输出有中几个php-fpm进程就说明启动成功了):9000

# ps aux | grep php-fpm

 

整合nginx和php5:

1、编辑/etc/nginx/fastcgi_params文件,将如下行的内容放到最前面。否则报错。

# vim /etc/nginx/fastcgi_param
    fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
    fastcgi_param  SERVER_SOFTWARE    nginx;

2、编辑nginx的主配置文件修改为如下内容:

location / {
    root    /web/htdocs;
    index   index.php index.html index.htm;
}
locaiton ~* \.php$ {
    root    /web/htdocs;
    fastcgi_pass   172.16.100.1:9000;
                /usr/local/php/etc/php-fpm.conf的监听地址也要修改为此地址。
                如果只是为本机提供FastCGI,IP地址可以为127.0.0.1。
                但是如果FastCGI为独立主机,服务就必须监听在外网地址上。
                而且静态服务器上和动态服务器都必须有相同的root目录。
                
    fastcgi_index  index.php;
    fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name; 
                这里是为FastCGI传递参数用的。
                这里"$document_root"默认是"/script",需要修改。 
    include        fastcgi_params;
}

3、添加php测试页面

# cat > /web/htdocs/index.php <<EOF
> <h1>The FastCGI server is working!</h1>
> <?php
> phpinfo();
> ?>
> EOF

4、重启nginx服务器,并测试

# service nginx restart
# elinks http://172.16.100.1/index.php


nginx支持https:

须同时添加http支持:
server {
    listen    172.16.100.1:80;
    server_name    www.yh.com; 
    location / {
        root    /web/htdocs;
        index   index.php index.html index.htm;
    }
    
    location ~ \.php$ {
        root           /web/htdocs;
        fastcgi_pass   172.16.100.1:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include        fastcgi_params;
    }
}
  
添加https支持:       
server {
        listen       443;
        server_name  www.yh.com;
 
        ssl                  on;
        ssl_certificate      /etc/nginx/nginx.crt;证书路径
        ssl_certificate_key  /etc/nginx/nginx.key;私钥路径
 
        ssl_session_timeout  5m;
 
        ssl_protocols  SSLv2 SSLv3 TLSv1;
        ssl_ciphers  HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers   on;
 
        location / {
            root   /web/htdocs/;
            index  index.html index.php index.htm;
        }
        
        需要同时添加FastCGI服务,否则https不支持php文件:
        location ~ \.php$ {
        root           /web/htdocs;
        fastcgi_pass   172.16.100.1:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include        fastcgi_params;
        fastcgi_param  HTTPS on;需要添加此行内容
        }
}


下面继续写nginx的配置

反向代理模块:

ngx_http_proxy_module

    核心代码是"proxy_pass http://URL"或者是"proxy_pass http://upstream_name",用于实现将用户请求的URI发至上游服务器的某个URI。这里的关键字是"proxy_pass http://" 。

Syntax:proxy_pass URL;
    
Default:―    
Context:location, if in location, limit_except
第一种情况:
location /name/ {
    proxy_pass    http://127.0.0.1/remote/;
}
    注意:当/name和/remote是不同的URI名称时,/name可能只是一个不存在的URI,无意义
         即客户端请求会被代理至http://IP/remote,nginx会自动处理映射关系。第二种情况: 
location /some/path/ {
    proxy_pass    http://127.0.0.1;
}   
    注意:当http://IP后面没有任何内容时(即使是"/"),/some/path/会自动传递到其后。
         即请求被代理至http://127.0.0.1/some/path/ 
第三种情况:
location ~* \.html$ {
    proxy_pass      http://172.16.100.1;    
}    
    注意:不同于第一、二两种情况,
         当location使用模式匹配时,http://172.16.100.1后面绝对不能跟任何东西。
         因为被模式匹配的内容会被自动添加到后面,不是映射了。也就是客户端请求被代理到
         http://172.16.100.1/(.*)\.html$
         所以后端服务器必须也具有模式中的目录或文件。

    上面讲述的是静态html的代理,而如果想要代理FastCGI请求,则可以使用"fastcgi_pass address:9000"或者"fastcgi_pass upstream_name",这些内容在"ngx_http_fastcgi_module"中可以看到帮助文档。

其他参数:

proxy_connect_timeout:nginx将一个请求发送至upstream server之前等待的最大时长;
proxy_cookie_domain  :将upstream server通过Set-Cookie首部设定的domain属性修改为指定的值,其值可以为一个字符串、正则表达式的模式或一个引用的变量;
proxy_cookie_path    : 将upstream server通过Set-Cookie首部设定的path属性修改为指定的值,其值可以为一个字符串、正则表达式的模式或一个引用的变量;
proxy_hide_header    :设定发送给客户端的报文中需要隐藏的首部;
proxy_pass           :指定将请求代理至upstream server的URL路径;
proxy_set_header     :将发送至upsream server的报文的某首部进行重写;
proxy_redirect       :重写location并刷新从upstream server收到的报文的首部;
proxy_send_timeout   :在连接断开之前两次发送至upstream server的写操作的最大间隔时长;
proxy_read_timeout   :在连接断开之前两次从接收upstream server接收读操作的最大间隔时长;

如下面的一个示例:
	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;

动静分离实验:

    nginx作为代理服务器,使得客户端访问动态内容和静态内容分别发送到不同的服务器上。

实验环境:

    静态服务器IP:172.16.100.15

    动态服务器IP:172.16.100.1

    nginx代理服务器IP:172.16.100.17


动态服务器上的修改FastCGI的监听地址:

# vim /usr/local/php/etc/php-fpm.conf
    listen = 172.16.100.1:9000

nginx代理服务器上配置:

server {
    listen    172.16.100.17:80;
    server_name     www.yh.com;
静态段:    
    location ~* \.(jpg|png|ico|css|gif|html)$ {
        root        /web/htdocs;
        proxy_pass  http://172.16.100.15;
        proxy_set_header X-Real-IP $remote_addr;
    }
动态段:   
    location ~ \.php$ {
        root           /web/htdocs;
        fastcgi_pass   172.16.100.1:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include        fastcgi_params;
     }
}


负载均衡模块:

ngx_http_upstream_module

Syntax:upstream name { ... }
    
Default:―    
Context:http

upstream上下文中常用的指令:

ip_hash:   基于客户端IP地址完成请求的分发,它可以保证来自同一个客户端的请求始终被转发至同一个server中。
keepalive: nginx代理服务器与后端server之间是否使用长连接,可以减少tcp的三次握手。
least_conn:最少调度算法。这样就无法使用ip_hash了。
server:     定义一个upstream服务器的地址,还包括下面的一些可选参数。
        weight      :权重。
        max_fails   :最大失败连接次数。
        fail_timeout:允许后端服务器多长时间没有响应。
        backup      :用于fallback,当其他upstream都宕机时,才会启用此server。
        down        :手动标记此server不再接受任何请求,也就是权重为0。

upstream一般和proxy结合使用,应用案例如下:

http{
    ...
    upstram jingtai {
        server    172.16.100.1    weight=1;
        server    172.16.100.15   weight=3;
        server    127.0.0.1:8080  backup;
        ip_hash;
    }
    upstram dongtai {
        server    172.16.100.16:9000;
        server    172.16.100.17:9000;
    }
    upstram memcacheservers {
        server    172.16.100.18:11211;
        server    172.16.100.19:11211;
    }
    server {
        ...
        location / {
            set $memcached_key    "$uri?$args";发送查询键到memcached。
            memcached_pass        memcacheservers;
            error_page    404     =@fallback;如果没有命中,就发送其他server.
        }
        location ~* \.(jpg|png|ico|css|gif|html)$ {
            proxy_pass    http://jingtai;            add_header x-cahce-server $upstream _cache_status;
                方便客户端在测试时查看缓存是否命中的。这是upstream模块的内置函数。
                使用curl -I 可以看到返回304
                使用谷歌浏览器在响应报文中可以看到首部信息值为HIT。
        }  
        location ~ \.php$ {
            fastcgi_pass   dongtai;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
            include        fastcgi_params;
        }
}


缓存服务器:

    在反向代理场景中,nginx有一系列指令可用于定义其工作特性,如缓冲区大小等,给这些指令设定一个合理的值,可以有效提升其性能。

1、 缓冲区设定

nginx在默认情况下在将其响应给客户端之前会尽可能地接收来upstream服务器的响应报文,它会将这些响应报文存暂存于本地并尽量一次性地响应给客户端。然而,在来自于客户端的请求或来自upsteam服务器的响应过多时,nginx会试图将之存储于本地磁盘中,这将大大降低nginx的性能。因此,在有着更多可用内存的场景中,应该将用于暂存这些报文的缓冲区调大至一个合理的值。

proxy_buffer_size size:设定用于暂存来自于upsteam服务器的第一个响应报文的缓冲区大小;
proxy_buffering on|off:启用缓冲upstream服务器的响应报文,否则,如果proxy_max_temp_file_size指令的值为0,来自upstream服务器的响应报文在接收到的那一刻将同步发送至客户端;一般情况下,启用proxy_buffering并将proxy_max_temp_file_size设定为0能够启用缓存响应报文的功能,并能够避免将其缓存至磁盘中;
proxy_buffers 8 4k|8k:用于缓冲来自upstream服务器的响应报文的缓冲区大小;

2、缓存

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

proxy_cache zone|off    :定义一个用于缓存的共享内存区域,其可被多个地方调用;缓存将遵从upstream服务器的响应报文首部中关于缓存的设定,如 "Expires"、"Cache-Control: no-cache"、 "Cache-Control: max-age=XXX"、"private"和"no-store" 等,但nginx在缓存时不会考虑响应报文的"Vary"首部。为了确保私有信息不被缓存,所有关于用户的私有信息可以upstream上通过"no-cache" or "max-age=0"来实现,也可在nginx设定proxy_cache_key必须包含用户特有数据如$cookie_xxx的方式实现,但最后这种方式在公共缓存上使用可能会有风险。因此,在响应报文中含有以下首部或指定标志的报文将不会被缓存。

proxy_cache_key    :设定在存储及检索缓存时用于“键”的字符串,可以使用变量为其值,但使用不当时有可能会为同一个内容缓存多次;另外,将用户私有信息用于键可以避免将用户的私有信息返回给其它用户;
proxy_cache_lock    :启用此项,可在缓存未命令中阻止多个相同的请求同时发往upstream,其生效范围为worker级别;
proxy_cache_lock_timeout    :proxy_cache_lock功能的锁定时长;
proxy_cache_min_uses        :某响应报文被缓存之前至少应该被请求的次数;
      也就是说nginx智能的只缓存 被请求几次  的数据,否则只请求一次的内容缓存一次也没有用
proxy_cache_path:(用在httpd段)定义一个用记保存缓存响应报文的目录,及一个保存缓存对象的键及响应元数据的共享内存区域(keys_zone=name:size),其可选参数有:
	levels:每级子目录名称的长度,有效值为1或2,每级之间使用冒号分隔,最多为3级;
	inactive:非活动缓存项从缓存中剔除之前的最大缓存时长;
		就是在有效的缓存时间内没有被用到,那么为防止在下一刻用到,nginx还需要再等待的时间
        
	max_size:缓存空间大小的上限,当需要缓存的对象超出此空间限定时,缓存管理器将基于LRU算法对其进行清理;
	loader_files:缓存加载器(cache_loader)的每次工作过程最多为多少个文件加载元数据;
	loader_sleep:缓存加载器的每次迭代工作之后的睡眠时长;
	loader_threashold:缓存加载器的最大睡眠时长;
    例子:  
	proxy_cache_path  /data/nginx/cache/one    levels=1      keys_zone=one:10m;
	proxy_cache_path  /data/nginx/cache/two    levels=2:2    keys_zone=two:100m;
	proxy_cache_path  /data/nginx/cache/three  levels=1:1:2  keys_zone=three:1000m;

proxy_cache_use_stale:在无法联系到upstream服务器时的哪种情形下(
如error、timeout或http_500等)让nginx使用本地缓存的过期的缓存对象直接响应客户端请求;(也就是是否可以使用过期的缓存对象的)其格式为:

proxy_cache_valid [ code ...] time:
    例如:
        proxy_cache_valid  200 302  10m;表示返回值是200、302的缓存10分钟
proxy_cache_methods [GET HEAD POST]:为哪些请求方法启用缓存功能;
proxy_cache_bypass string:设定在哪种情形下,nginx将不从缓存中取数据;
    例如:
	 proxy_cache_bypass $cookie_nocache $arg_nocache $arg_comment;
 	 proxy_cache_bypass $http_pragma $http_authorization;
         包含用户隐私数据的信息不要缓存

示例1:

http {
    proxy_cache_path  /data/nginx/cache  levels=1:2    keys_zone=STATIC:10m
                                         inactive=24h  max_size=1g;
    server {
        location / {
            proxy_pass             http://www.magedu.com;
            proxy_set_header       Host $host;
            proxy_cache            STATIC;
                这里表示使用那个内存空间,当为off时关闭缓存
            proxy_cache_valid      200  1d;
            proxy_cache_valid	   301 302 10m;
            proxy_cache_vaild 	   any 1m;
            proxy_cache_use_stale  error timeout invalid_header updating
                                   http_500 http_502 http_503 http_504;
        }
    }
}

示例2:

httpd
{
	fastcgi_cache_path /data/cache/fastcgi levels=1:2:1 keys_zone=fcgi:20m max_size=1g;
	server{
	location ~ \.php$ {
		root /web/htdocs;
		fastcgi_pass 172.16.100.1:9000;
		fastcgi_index index.php;
		fastcgi_para SCRIPT_FILENAME /scripts$fastcgi_script_name;
		include fastcgi_params;
		fastcgi_cache fcgi;
		fastcgi_cache_valid 200 10m;
	}
	}
}



nginx与squid:

nginx是异步的,当用户上传文件时,nginx只有文件完全上传完成,才会将文件传递到后端服务器。由于服务器之间带宽较高,所以不会占用过多后端服务器的资源。

squid是同步的,只要与用户一建立连接,那么squid同时也会与后端服务器建立连接。直到文件上传完成。所以会占用较多资源。    



你可能感兴趣的:(nginx,https,fastcgi)