muugua 发表于 2018-11-11 14:23:49

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_paramGATEWAY_INTERFACECGI/1.1;
  
    fastcgi_paramSERVER_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_indexindex.php;
  
    fastcgi_paramSCRIPT_FILENAME $document_root$fastcgi_script_name;
  
                这里是为FastCGI传递参数用的。
  
                这里"$document_root"默认是"/script",需要修改。
  
    include      fastcgi_params;
  
}
  3、添加php测试页面
# cat > /web/htdocs/index.php
  
> 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_indexindex.php;
  
      fastcgi_paramSCRIPT_FILENAME$document_root$fastcgi_script_name;
  
      include      fastcgi_params;
  
    }
  
}
  

  
添加https支持:
  
server {
  
      listen       443;
  
      server_namewww.yh.com;
  

  
      ssl                  on;
  
      ssl_certificate      /etc/nginx/nginx.crt;证书路径
  
      ssl_certificate_key/etc/nginx/nginx.key;私钥路径
  

  
      ssl_session_timeout5m;
  

  
      ssl_protocolsSSLv2 SSLv3 TLSv1;
  
      ssl_ciphersHIGH:!aNULL:!MD5;
  
      ssl_prefer_server_ciphers   on;
  

  
      location / {
  
            root   /web/htdocs/;
  
            indexindex.html index.php index.htm;
  
      }
  

  
      需要同时添加FastCGI服务,否则https不支持php文件:
  
      location ~ \.php$ {
  
      root         /web/htdocs;
  
      fastcgi_pass   172.16.100.1:9000;
  
      fastcgi_indexindex.php;
  
      fastcgi_paramSCRIPT_FILENAME$document_root$fastcgi_script_name;
  
      include      fastcgi_params;
  
      fastcgi_paramHTTPS on;需要添加此行内容
  
      }
  
}
  下面继续写nginx的配置
  反向代理模块:
  ngx_http_proxy_module
  核心代码是"proxy_pass http://URL"或者是"proxy_pass http://upstream_name",用于实现将用户请求的URI发至上游服务器的某个URI。这里的关键字是"proxy_passhttp://" 。
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_passhttp://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_indexindex.php;
  
      fastcgi_paramSCRIPT_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:8080backup;
  
      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_indexindex.php;
  
            fastcgi_paramSCRIPT_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/threelevels=1:1:2keys_zone=three:1000m;
  

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

  
proxy_cache_valid [ code ...] time:
  
    例如:
  
      proxy_cache_valid200 30210m;表示返回值是200、302的缓存10分钟
  
proxy_cache_methods :为哪些请求方法启用缓存功能;
  
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/cachelevels=1:2    keys_zone=STATIC:10m
  
                                       inactive=24hmax_size=1g;
  
    server {
  
      location / {
  
            proxy_pass             http://www.magedu.com;
  
            proxy_set_header       Host $host;
  
            proxy_cache            STATIC;
  
                这里表示使用那个内存空间,当为off时关闭缓存
  
            proxy_cache_valid      2001d;
  
            proxy_cache_valid   301 302 10m;
  
            proxy_cache_vaild    any 1m;
  
            proxy_cache_use_staleerror 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同时也会与后端服务器建立连接。直到文件上传完成。所以会占用较多资源。


页: [1]
查看完整版本: nginx详解(三)—FastCGI、https、动静分离、proxy、upstream和cache