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]