Nginx Web服务器

Nginx Web服务器
Nginx是一个高性能HTTP、反向代理、IMAP、POP3、SMTP服务器。
Nginx特点是占用内存少,并发能力强,高性能,轻量级。
Nginx 相对于Apache优点如下:
高并发响应性能非常,官方Nginx处理静态文件并发5w/s;
负载均衡及反向代理性能非常强;
系统内存和CPU占用率低;
可对后端服务进行健康检查;
支持PHP CGI方式和FastCGI方式;
可以作为缓存服务器、邮件代理服务器;
配置代码简洁且容易上手。
 
一、Nginx 工作原理
NginxWeb服务器主要是各种模块协同工作,模块从结构上分为核心模块、基础模块和第三方模块,基中三类模块分别如下:
核心模块:HTTP模块、event模块和mail模块等。
基础模块:HTTP access模块、HTTPFastCGI模块、HTTP proxy模块和HTTP rewrite模块。
第三方模块:HTTP upstreamrequest hash模块、notice模块和HTTP access key模块、limit_req模块等。
Nginx 的模块从功能上分为如下三类:
handlers(处理器模块):此类模块直接处理请求,并进行输出内容和修改headers信息等操作,handlers处理器模块一般只能有一个。
filters(过滤器模块):此类模块是Nginx的HTTP upstream之类的模块,这些模块主要与后端一些服务比如FastCGI等进行交互,实现服务代理和负载均衡等功能。
Nginx的高并发得益于其采用了epoll模型,异步非阻塞,而Apache采用的是select模型。
select模型的特点为select选择句柄的时候,是遍历所有句柄,也就是说句柄有事件响应时,select需要遍历所有句柄才能获取到哪些句柄有事件通知,因此效率是非常低。
epoll模型的特点为epoll对于句柄事件的选择不是遍历的,是事件响应的,就是句柄上事件来就马上选择出来,不需要遍历整个句柄链表,因此效率非常高。
 
二、Nginx 安装配置
yum安装:yum install nginxpcre-devel pcre -y
源码安装:#安装PCRE库支持  yum install pcre-devel pcre -y
#下载Nginx 源码包:cd/usr/src  wget -c http://nginx.org/download/nginx-1.12.0.tar.gz
#解压Nginx 源码包:tar -xzfnginx-1.12.0.tar.gz
#进入解压目录,然后sed修改Nginx版本信息为JWS
cd nginx-1.12.0; sed -i-e 's/1.12.0//g' -e 's/nginx\//JWS/g' -e's/"NGINX"/"JWS"/g' src/core/nginx.sh;
#预编译Nginx :useradd www;./configure --user=www --group=www --prefix=/usr/local/nginx--with-http_stub_status_module --with-http_ssl_module
#.configure预编译成功后,执行make命令进行编译与make install来安装 :make     makeinstall    
#测试Nginx服务安装是否正确:/usr/local/nginx/sbin/nginx -t
#启动Nginx服务:/usr/local/nginx/sbin/nginx    回车    
#查看进程是否启动:ps -ef |grepnginx           通过浏览器访问Nginx 默认测试页面。
 
三、Nginx 管理及升级
NginxWeb服务器安装完毕后,可以执行以下命令对其进行管理和维护。
#查看Nginx 进程:ps -ef|grep nginx
#平滑启动Nginx :kill -HUP'cat /var/run/nginx.pid'  或者  nginx -s reload   平滑启动的意思是不停止Nginx 的情况下,重启Nginx重新加载配置文件,启动新的工作线程,完美停止旧的工作线程。
#完美停止Nginx :kill -QUIT'cat /var/run/nginx.pid'
#快速停止Nginx :kill -TERM'cat /var/run/nginx.pid'    或者  kill -INT 'cat /var/run/nginx.pid'
#完美停止工作进程(主要用于平滑升级):kill-WINCH 'cat /var/run/nginx.pie'
#强制停止Nginx :pkill -9nginx
#检查对nginx.conf文件的修改是否正确:nginx-t -c /etc/nginx/nginx.conf   或者   nginx -t
#停止Nginx 的命令:nginx -sstop     或者   pkill nginx
#查看Nginx 的版本信息:nginx-v 
#查看完整的Nginx 的配置信息:nginx-V
NginxWeb软件定期更新,以下为将低版本升级或者将高版本降级的方法,一般分为四个步骤:下载、预编译、编译、配置:
wget http://www.nginx.org/download/nginx-1.4.2.tar.gz
#获取旧版本Nginx的configure选项:/usr/local/nginx/sbin/nginx -V
#编译新版本的Nginx :tar -xvfnginx-1.4.2.tar.gz ; cd nginx.1.4.2 ; ./configure --prefix=/usr/local/nginx--user=www --group=www --with=http_stub_status_module--with-http_ssl_module  ; make
#备份旧版本的Nginx可执行文件;复制新版本的Nginx 可执行文件
mv/usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.old
cp objs/nginx  /usr/local/nginx/sbin/
#测试新版本Nginx 是否正常:/usr/local/nginx/sbin/nginx -t
#平滑重启升级Nginx :kill-QUIT 'cat /usr/local/nginx/log/nginx.oldbin'
#验证Nginx 是否升级成功:/usr/local/nginx/sbin/nginx -V     显示最新编译的版本信息即可。
 
四、Nginx 配置文件优化
nginx.conf 配置文件常用参数详解:
useruser[group];                                定义user和工作group进程使用的凭证。如果group省略,user则使用名称等于的组。
worker_processes1;                                句法:worker_processesnumber | auto;
例如:
#worker_processes 4;
#worker_cpu_affinity0001 0010 0100 1000;
将工作进程绑定到CPU集合。每个CPU集合由允许的CPU的位掩码表示。应该为每个工作进程定义一个单独的集合。默认情况下,工作进程不绑定到任何特定的CPU。
worker_rlimit_nofile10240;                         Nginx进程打开的最多文件描述符数目,最好与ulimit -n的值保持一致。
error_log/usr/local/nginx/logs/error.log                错误日志自定义,[debug | info | notice | warn | error | crit ]
pid /usr/local/nginx/nginx.pid                        pid文件位置
events {
use        epoll;                                        工作模式及连接数上限,epoll是多路复用I/O中的一种方式,可以大大提高Nginx的性能。
worker_connections102400;                        单个后台workerprocess进程的最大连接数(最大连接数=连接数*进程数)
multi_accepton;                                        尽可能多的接受请求。
}
#设定HTTP服务器,利用它的的向代理功能提供负载均衡支持:
http {
include      mime.types;                                设定MIME类型,类型由mime.types文件定义
default_type        application/octet-stream;
access_log        /usr/local/nginx/log/nginx/access.log;        设定日志格式与文件位置
sendfile                on;                                sendfile指令指定Nginx是否调用sendfile函数来输出文件,对于普通应用必须设为on,如果用来进行下载等应用磁盘I/O重负载应用,可设置为off,以平衡磁盘与网络I/O处理速度,降低系统的uptime。
#autoindex        on;                                开户目录列表访问,适合下载服务器,默认关闭。
tcp_nopush        on;                                防止网络阻塞
keepalive_timeout60;                                keepalive超时时间,客户端到服务器端的连接持续有效时间。
tcp_nodelay        on;                                提高数据的实时响应性
#开启gzip压缩
gzip on;
gzip_min_length 1KB;
gzip_buffers        416KB;
gzip_http_version 1.1;
gzip_comp_level2;                                压缩级别,最大为9,值越小,压缩后的比例越小,CPU处理越快,值越大,消耗CPU比较高
gzip_types        text/plainapplication/x-javascript text/css application/xml;
gzip_vary        on;
client_max_body_size 10MB;                        允许客户端请求的最大单文件字节数
client_body_buffer_size128KB;                        缓冲区代理缓冲用户端请求的最大字节数
proxy_connect_timeout 90;                        Nginx跟后端服务器连接超时时间(代理连接超时)
proxy_send_timeout 90;                                后端服务器数据回传时间(代理发送超时)
proxy_read_timeout 90;                                连接成功后,后端服务器响应时间(代理连接超时)
proxy_buffer_size  4KB;                                设置代理服务器(Nginx)保存用户信息的缓冲区大小
proxy_buffers  432KB;                                proxy_buffers缓冲区,网页平均在32KB以下的话,这样设置
proxy_busy_buffers_size 64KB;                        高负荷下缓冲区大小(proxy_buffers*2)
#设定请求缓冲
large_client_header_buffers44KB;                客户请求头部的缓冲区大小,根据系统分页大小来设置,分页大小:getconfPAGESIZE
client_header_buffer_size4KB;
open_file_cachemax=102400inactive=20s;        将为打开的文件指定缓存,默认是没有启用的,max指定缓存数量,建议和打开文件数一致,inactive是指经过多长时间文件没被请求后删除缓存。
open_file_cache_valid30s;                        这个是指多长时间检查一次缓存的有效信息
open_file_cache_min_uses 1;                        open_file_cache指令中inactive参数时间内文件的最少使用次数
includevhosts.conf;                                包含其他配置文件,如自定义的虚拟主机
NginxWeb默认发布静态页面,也可以均衡后端动态页面。
Nginx实现负载均衡需要基于upstream模块,同时需要设置location proxy_pass转发指令实现。
以下为Nginx应用负载均衡集群配置,根据后端实际情况修改即可,jfedu_www为负载均衡模块的名称,可以任意指定,但必须跟vhosts.conf、nginx.conf虚拟主机的proxy_pass段保持一致,否则不能将请求转发至后端的服务器,weight表示配置权重,在fail_timeout内检查max_fails次数,失败则剔除均衡。代码如下:
upstream jfedu_www{
server127.0.0.1:8080 weight=1 max_fails=2 fail_timeout=30s;
server127.0.0.1:8080 weight=1 max_fails=2 fail_timeout=30s;
}
#虚拟主机设置
server{
listen        80;                        侦听80端口
server_namewww.wuyutang.top        定义使用www.wuyutang.top访问
access_loglogs/access.logmain;        定义本虚拟主机的访问日志
     root   /data/webapps/www;        定义服务器的默认网站根目录位置
indexindex.php index.htmlindex.htm;        定义首页索引文件的名称
#默认请求
location~ /{
   root   /data/webapps/www;        定义服务器的默认网站根目录位置
   index index.php index.html index.htm;   定义首页索引文件的名称
#以下是一些反向代理的配置
   proxy_next_upstream http_502 http_504 errortimeout invalid_header;
#如果后端的服务器返回502、504、执行超时等错误,自动将请求转发到upstream负载均衡池中的另一台服务器,实现故障转移
   proxy_redirect  off;
#后端的Web服务器可以通过X-Forwarded-For获取用户真实IP
   proxy_set_header Host $host;
   proxy_set_header X-Real-IP $remote_addr;
   proxy_set_header X-Forwarded-For$proxy_add_x_forwarded_for;
proxy_passhttp://jfedu_www;                请求转向后端定义的均衡模块
}
 #定义错误提示页面
error_page500 502 503 504 /50x.html;
location= /50x.html {
root        html;
}
#配置Nginx动静分离,定义的静态页面直接从Nginx 发布目录读取
location~ .*\. (html|htm|gif|jpg|jpeg|bmp|png|ico|txt|js|css)$
{
root/data/webapps/www;
#expires定义用户浏览器缓存的时间为3天,如果静态页面不常更新,可以设置更长。
expires    3d;
}
#PHP脚本请求全部转发到FastCGI处理,使用FastCGI默认配置
location~\.php${
root/root;
FastCGI_pass127.0.0.1:9000;
FastCGI_indexindex.php;
FastCGI_paramSCRIPT_FILENAME /data/webapps/www $FastCGI_script_name;
includeFastCGI_params;
}
#设定查看Nginx状态的地址
location/NginxStatus{
stub_statuson;
}
}
}
 
五、Nginx 虚拟主机实战
Nginx虚拟主机多个域名对应同一个80端口:
worker_processes 1;
events {
worker_connections1024;
}
http{
include                mime.types;
default_type        application/octet-stream;
sendfile                on;
keepalive_timeout  65;
#virtual hosts config
server {
listen        80;
sever_namewww.tang1.com;
access_loglogs/tang1.access.log;
location/ {
root        html/tang1;
index        index.htmlindex.htm;
}
}
server {
listen        80;
server_namewww.tang2.com
access_loglogs/tang2.access.log;
location/ {
roothtml/tang2;
indexindex.html index.htm;
}
      }
}
创建两个不同的目录mkdir -p/usr/local/nginx/html/{tang1,tang2},然后分别在两个目录创建两个不同的index.html网站页面即可。
 
六、Nginx location深入剖析
Nginx由内核和模块组成,其中内核的设计非常微小和简洁,工作非常简单,公是通过查找配置文件将客户端映射到一个locationblock,而location是Nginx配置中的一个指令,用于访问的URL匹配,而在这个location中所配置的每个指令将会启动不同的模块去完成相应的工作。
默认nginx.conf配置文件中至少存在一个location/,即表示客户端浏览器请求的URL为域名+"/",如果location/newindex/,则表示客户端浏览器请求的URL为域名+“/newindex/”。常见location匹配URL的方式如下:
=        字面精确匹配
^~        最大前缀匹配
/        不带任何前缀
~        大小写相关的正则匹配
~        大小写无关的正则匹配
@        location内部重定向的变量
location规则匹配优先级总结:
(location =)>(location 完整路径)>(location ^~)>(location~或~*正则顺序)>(location部分起始路径)>(location/)
Nginx location规则案例:
location = / {
   [ configuration L1 ]
   #只会匹配/,优先级比location/低
}
location = /index.html{
   [ configuration L2 ]
   #只会匹配/index.html,优先级最高
}
location / {
   [ configuration L3 ]
   #匹配任何请求,因为所有请求都是以“/”开始
   #但是更长字符匹配或者正则表达式匹配会优先匹配,优先我级最低
}
location = /images/ {
   [ configuration L4 ]
   #匹配任何以/images/开始的请求,并停止匹配其他location
}
location ~* \.(html|txt|gif|jpg|jpeg)${
   [ configuration L5 ]
   #匹配以html、txt、gif、jpg、jpeg结尾的URL文件请求
   #但是所有/images/目录的请求将由[ configuration L4 ]处理
}
浏览器发起HTTP requestURI案例与location规则案例匹配如下:
/                        匹配configuration L3
/index.html                匹配configuration L2
/images/                匹配configuration L4
/images/logo.png        匹配configuration L4
/img/test.jpg                匹配configuration L5
企业生产环境中无须在nginx.conf配置文件中同时添加5种规则匹配,生产环境Nginxlocation部分配置代码如下:
location / {
     root /var/www/html;
    expires        60d;
}
location ~ . * \ .(gif|jpg|jpeg|bmp|png|ico|txt|js|css)${
     root /var/www/html;
    expires        60d;
}
location ~ . * \ .(jsp|php|cgi|do)${
root/var/www/html;
proxy_passhttp://wuyutang.top;
proxy_http_version1.1;
proxy_set_headerConnection "";
proxy_set_headerHost $host;
proxy_set_headerX-Real-IP $remote_addr;
proxy_set_headerX-Forwarded-For $proxy_add_x_forwarded_for;
}
location =/newindex.html {
root/var/www/html;
expires          60d;
}
 
七、企业实战Nginx 动静分离架构
Nginx动静分离在严格意义上来说是动态请求和静态请求分开,可以理解为使用Nginx处理静态页面,Tomcat、Resin、PHP、ASP处理动态页面。
动静分离从实现角度来讲大致分为两种:
一种是纯粹地把静态文件独立成单独的域名,放在独立的服务器上,也是目前主流推荐的方案;
另一种方法就是动态跟静态文件混全在一起发布,通过Nginx来分开。
Nginx线上Web服务器动静分离及nginx.conf完整配置文件代码如下;
user www www;
worker_processes 8;
worker_cpu_affinity00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000;
pid/usr/local/nginx/nginx.pid;
worker_rlimit_nofile102400;
events
{
use epoll;
worker_connectios102400;
}
http
{
include                mime.types;
default_type  application/octet-stream;
FastCGI_intercept_errorson;
charsetuft-8;
server_names_hash_bucket_size128;
client_header_buffer_size4KB;
large_client_header_buffers4 32KB;
client_max_body_size300MB;
sendfile  on;
tcp_nopush        on;
keepalive_timeout60;
tcp_nodelayon;
client_body_buffer_size                512KB;
proxy_connet_timeout                5;
proxy_read_timeout                60;
proxy_send_timeout                5;
proxy_buffer_size                16KB;
proxy_buffers                        464KB;
proxy_busy_buffers_size                128KB;
proxy_temp_file_write_size        128KB;
gzipon;
gzip_min_length                        1KB;
gzip_buffers                        416KB;
gzip_http_version                1.1;
gzip_comp_level                        2;
gzip_types        text/plainapplication/x-javascript text/css application/xml;
gzip_varyon;
log_format main'$remote_addr - $remote_user[ $time_local ] "$request"'
'$status$body_bytes_sent "$http_referer"'
'"$http_user_agent"$request_time';
upstream jvm_web1 {
server        192.168.9.8:8080weight=1 max_fails=2 fail_timeout=30s;
server        192.168.9.8:8081weight=1 max_fails=2 fail_timeout=30s;
}
include vhosts.conf;
}
以下为vhosts.conf配置文件代码:
server
   {
listen        80;
server_namewww.tang1.com;
indexindex.jsp index.html index.htm;
root/data/webapps/www1;
location/
{
proxy_next_upstreamhttp_502 http_504 error timeout invalid_header;
proxy_set_headerHost $host;
proxy_set_headerX-Real-IP $remote_addr;
proxy_set_headerX-Forwarded-For $proxy_add_x_forwarded_for;
proxy_passhttp://jvm_web1;
}
location~ . * \ . (php|jsp|cgi|shtml)?$
{
proxy_set_headerHost $host;
proxy_set_headerX-Real-IP $remote_addr;
proxy_set_headerX-Forwarded-For $proxy_add_x_forwarded_for;
proxy_passhttp://jvm.web1;
}
location~ . * \ . (html|htm|gif|jpg|jpeg|bmp|png|ico|txt|js|css)$
{
root/data/webapps/www1;
expires        30d;
}
access_log/data/logs/jvm_web1/access.log main;
error_log/data/logs/jvm_web1/error.log crit;
}
配置文件代码中的location ~ . *\ . (php|jsp|cgi|shtml)表示匹配动态页面请求,然后将请求proxy_pass到后端服务器,
而location ~ . * \ .(html|htm|gif|jpg|jpeg|bmp|png|ico|txt|js|css)表示匹配静态页面请求本地返回。
检查Nginx配置是否正确即可,然后测试动静分离是否成功,在192.168.9.8服务器启动8080、8081Tomcat服务或者LAMP服务,删除反端Tomcat或者LAMP服务器上的某个静态文件,测试是否能够访问该文件,如果可以访问,则说明静态资源通过Nginx直接返回了,如果不能访问,则证明动静分离不成功。
 
八、企业实战LNMP高性能服务器
安装的版本是 nginx 1.12  mysql 5.7 php 5.6
1、安装nginx
yum install wget gccgcc-c++ pcre-devel zlib-devel openssl openssl-devel
cd /usr/local/src/
wget http://nginx.org/download/nginx-1.12.2.tar.gz
tar zxvfnginx-1.12.2.tar.gz
cd nginx-1.12.2 
useradd www;./configure --user=www --group=www --prefix=/usr/local/nginx--with-http_ssl_module --with-http_v2_module --with-http_stub_status_module--with-pcre --with-http_gzip_static_module --with-http_dav_module   --with-http_addition_module  --with-http_sub_module--with-http_flv_module --with-http_mp4_module
解释
--with-http_gzip_static_module:        支持压缩
--with-http_stub_status_module:        支持nginx状态查询
--with-http_ssl_module:                支持https
--with-pcre:                                为了支持rewrite重写功能,必须制定pcre
 --with-http_dav_module                   #启用支持(增加PUT,DELETE,MKCOL:创建集合,COPY和MOVE方法)
--with-http_addition_module               #启用支持(作为一个输出过滤器,支持不完全缓冲,分部分相应请求)
--with-http_sub_module                    #启用支持(允许一些其他文本替换Nginx相应中的一些文本)
--with-http_flv_module                            #启用支持(提供支持flv视频文件支持)
--with-http_mp4_module                    #启用支持(提供支持mp4视频文件支持,提供伪流媒体服务端支持)
#make -j 4 &&make install 4核编译
make && makeinstall
vim /etc/profile
在56行添加: exportPATH=/usr/local/nginx/sbin:$PATH
source/etc/profile        重启配置
添加软连  ln -s /usr/local/nginx/sbin/nginx/usr/local/sbin/
生成服务启动脚本
vim /etc/init.d/nginx
#!/bin/bash
# chkconfig: - 99 2
# description: NginxService Control Script
PROG="/usr/local/nginx/sbin/nginx"
PIDF="/usr/local/nginx/logs/nginx.pid"
case "$1" in
        start)
        $PROG
        ;;
        stop)
        kill -3 $(cat $PIDF)
        ;;
        restart)
        $0 stop &> /dev/null
        if [ $? -ne 0 ] ; then continue ; fi
        $0 start
        ;;
        reload)
        kill -1 $(cat $PIDF)
        ;;
        *)
        echo "Userage: $0 { start | stop |restart | reload }"
        exit 1
esac
exit 0
配置服务开机自动启动
chmod +x/etc/init.d/nginx
chkconfig --add nginx
chkconfig nginx on
2、安装mysql 5.7  (同LAMP环境安装)
3、安装PHP
yum -y install gccgcc-c++ libxml2 libxml2-devel bzip2 bzip2-devel libmcrypt libmcrypt-developenssl openssl-devel libcurl-devel libjpeg-devel libpng-devel freetype-develreadline readline-devel libxslt-devel perl perl-devel psmisc.x86_64 recoderecode-devel libtidy libtidy-devel epel-release libmcrypt-devel
cd /usr/local/src/
wget http://cn2.php.net/distributions/php-5.6.32.tar.gz
tar zxvfphp-5.6.32.tar.gz
cd php-5.6.32
useradd -s/sbin/nologin php-fpm
./configure--prefix=/usr/local/php --sysconfdir=/usr/local/php/etc--with-config-file-path=/usr/local/php/etc/   --with-fpm-user=php-fpm --with-fpm-group=php-fpm --enable-fpm --with-mysql=mysqlnd --with-mysqli=mysqlnd--with-pdo-mysql=mysqlnd --with-mhash --with-openssl --with-zlib --with-bz2 --with-curl --with-libxml-dir--with-gd --with-jpeg-dir  --with-png-dir--with-zlib --enable-mbstring --with-mcrypt --enable-sockets--with-iconv-dir   --enable-zip--with-pcre-dir --with-pear --enable-session --enable-gd-native-ttf --enable-xml --with-freetype-dir --enable-gd-jis-conv--enable-inline-optimization --enable-shared --enable-bcmath --enable-sysvmsg --enable-sysvsem --enable-sysvshm  --enable-mbregex --enable-pcntl --with-xmlrpc--with-gettext --enable-exif --with-readline  --enable-ftp   --enable-redis
提示错误mcrypt.h没有找到,安装libmcrypt-devel包,默认的yum源,没有这个包,需要安装epel扩展源后,才可以安装。
yum install -yepel-release libmcrypt libmcrypt-devel
再次执行./configure,没有错误提示,出现Thankyou for using PHP,配置OK。
make && makeinstall
cp php.ini-production/usr/local/php/etc/php.ini
cp/usr/local/src/php-5.6.32/sapi/fpm/init.d.php-fpm   /etc/init.d/php-fpm (启动脚本)
mv/usr/local/php/etc/php-fpm.conf.default  /usr/local/php/etc/php-fpm.conf (就是去掉了末尾的.default )
chmod 755/etc/init.d/php-fpm
chkconfig --add php-fpm
service php-fpm start
Starting php-fpm  done
chkconfig php-fpm on
vim /etc/profile
exportPATH=/usr/local/php/bin:$PATH
source /etc/profile重新加载
3、测试:在地址栏输入你的ip。然后测试PHP安装是否成功。确保nginx和PHP都是运行的。
写测试页面
cd/usr/local/nginx/html/
 vim index.php
<?php
phpinfo();
?>
配置nginx
核心配置的两个加入到nginx.conf
vim/usr/local/nginx/conf/nginx.conf
找到 location /  index 后添加 index.php
将请求转给php的9000端口 确保nginx 和PHP都是运行的哈。  
 
  location ~\.php$ {
 
           root           html;
           fastcgi_pass   127.0.0.1:9000;
           fastcgi_index  index.php;
           fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
           include        fastcgi_params;
       }
添加phpinfo的网页资源路径。
         try_files $uri $uri/ /index.php?$query_string;
              if (!-e $request_filename){  
                        rewrite ^(.*)$ /index.php?s=$1 last;  break;
                     } 
 
九、Nginx rewrite 规则详解
rewrite规则也称为规则重写,其正则表达式是基于Perl语言,rewriteURL规则重写的用途如下:
对搜索引擎优化(search engineoptimization,SEO)友好,利于搜索引擎抓取网站页面;
隐藏网站URL真实地址,浏览器显示更加美观;
网站变更升级,可以基于rewrite临时重定向到其他页面。
Nginxrewrite规则使用中有3个概念,分别是rewrite结尾标识符、rewrite规则常用表达式、Nginx rewrite变量。
1、Nginx rewrite结尾标识符,用于rewrite规则末尾,表示规则的执行属性,flag标记说明:
last                相当于Apache里的(L)标记,表示完成rewrite;
break                本条规则匹配完成后,终止匹配,不再匹配后面的规则
redirect                返回302临时重定向,浏览器地址会显示跳转后的URL地址
permanent        返回301永久重定向,浏览器地址栏会显示跳转后的URL地址
last和break用来实现URL重写,浏览器地址栏URL地址不变。
说明:                                       
rewrite为固定关键字,表示开始进行rewrite匹配规则
regex部分是 ^/(.*),这是一个正则表达式,匹配完整的域名和后面的路径地址
replacement部分是http://www.tang.com/$1$1,是取自regex部分()里的内容。匹配成功后跳转到的URL。
flag部分permanent表示永久301重定向标记,即跳转到新的 http://www.tang.com/$1地址上
2、Nginx rewrite规则常用表达式,主要用于匹配参数、字符串及过滤设置,详解如下:
.                匹配除“\n”之外的任何单个字符,若要匹配包括“\n”在内的任意字符,请使用诸如“[.\n]”之类的模式。
[word]                匹配字符串word。
[^word]                不匹配字符串word。
tang|TANG        可选择的字符串tang|TANG。
?                匹配前面的字符零次或一次,例如“do(es)?”能匹配“do”或者“does”,"?"等效于"{0,1}"
*                匹配前面的字符零次或多次。如“ol*”能匹配“o”及“ol”、“oll”
+                匹配前面的字符一次或多次。如“ol+”能匹配“ol”及“oll”、“oll”,但不能匹配“o”
^                匹配输入字符串的起始位置
$                匹配输入字符串的结束位置
\                将后面接着的字符标记为一个特殊字符或一个原义字符或一个向后引用。如“\n”匹配一个换行符,而“\$”则匹配“$”
(pattern)        匹配括号内pattern并可以在后面获取对应的匹配,常用$0...$9属性获取小括号中的匹配内容,要匹配圆括号字符需要\(Content\)
3、Nginx rewrite变量,常用于匹配HTTP请求头信息、浏览器主机名、URL等,具体如下:
$args:                #这个变量等于请求行中的参数,同$query_string
$content_length:        请求头中的Content-length字段。
$content_type:        请求头中的Content-Type字段。
$document_root:        当前请求在root指令中指定的值。
$host:                请求主机头字段,否则为服务器名称。
$http_user_agent:        客户端agent信息
$http_cookie:                客户端cookie信息
$limit_rate:                这个变量可以限制连接速率。
$request_method:        客户端请求的动作,通常为GET或POST。
$remote_addr:        客户端的IP地址。
$remote_port:                客户端的端口。
$remote_user:                已经经过AuthBasic Module验证的用户名。
$request_filename:        当前请求的文件路径,由root或alias指令与URI请求生成。
$scheme:                HTTP协议(如http,https)。
$server_protocol:        请求使用的协议,通常是HTTP/1.0或HTTP/1.1。
$server_addr:                服务器地址,在完成一次系统调用后可以确定这个值。
$server_name:                服务器名称。
$server_port:                请求到达服务器的端口号。
$request_uri:                包含请求参数的原始URI,不包含主机名,如:”/foo/bar.php?arg=baz”。
$uri:                        不带请求参数的当前URI,$uri不包含主机名,如”/foo/bar.html”。
$document_uri:        与$uri相同。
if指令与全局变量
if指令语法为if(condition){...},对给定的条件condition进行判断。如果为真,大括号内的rewrite指令将被执行。
来看代码规则:
if ($http_user_agent ~MSIE) {
    rewrite ^(.*)$ /msie/$1 break;
}//如果UA包含"MSIE",rewrite请求到/msid/目录下
 
if ($http_cookie ~*"id=([^;]+)(?:;|$)") {
    set $id $1;
 } //如果cookie匹配正则,设置变量$id等于正则引用部分
 
if ($request_method =POST) {
    return 405;
}//如果提交方法为POST,则返回状态405(Method not allowed)。return不能返回301,302
 
if ($slow) {
    limit_rate 10k;
} //限速,$slow可以通过 set指令设置
 
if (!-f$request_filename){
    break;
    proxy_pass http://127.0.0.1;
}//如果请求的文件名不存在,则反向代理到localhost 。这里的break也是停止rewrite检查
 
if ($args ~ post=140){
    rewrite ^ http://mysite.com/permanent;
} //如果querystring中包含"post=140",永久重定向到mysite.com
 
301永久定向到新域名:
server {
    listen 80;
    listen 443 ssl;
    server_name www.old-name.com old-name.com;
    return 301 $scheme://www.new-name.com;
}
不带www的域名301跳转到带www的域名:
server {
    listen 80;
    listen 443 ssl;
    server_name mysite.com;
    return 301$scheme://www.mysite.com$request_uri;
}
http站点301跳转到https站点:
server {
    listen 80;
    server_name www.mysite.com;
    return 301 https://www.mysite.com$request_uri;
}
4、Nginxrewrite以下配置均配置在nginx.conf或者vhosts.conf中。常用的Nginx rewrite案例如下:
将tang.com跳转至www.tang.com:
if ( $host = 'tang.com') {
rewrite^/(. *)$http://www.tang.com/$1 permanent
}
访问www.tang.com跳转www.test.com/newindex.html:
rewrite^/$http://www.test.com/index01.html permanent;
访问/tang/test01/跳转至/newindex.html,浏览器地址不变:
rewrite^/tang/test01/$        /newindex.html        last;
多域名跳转www.tang.com:
if ( $host != 'www.tang.com') {
rewrite^/(.*)$http://www.tang.com/$1 permanent;
}
访问文件和目录不存在跳转至index.php:
if ( ! -e$request_filename ) {
rewrite^/(.*)$ /index.php last;
}
目录对换/xxxx/123456 =>/xxxx? id=123456 :
rewrite^/(.+)/(\d+)        /$1?id=$2        last;
判断浏览器user agent跳转:
if ( $http_user_agent ~MSIE) {
rewrite^(.*)$/ie/$1 break;
}
禁止访问以.sh,.flv,.mp3为文件后缀名的文件:
location ~.*\.(sh|flv|mp3)$ {
return403;
}
将移动用户访问跳转至移动端:
if ( $http_user_agent ~* "(Android)|(iPhone)|(Mobile)|(WAP)|(UCWEB)" ) {
reworte^/$ http://m.tang.com/        permanent;
}
匹配URL访问字符串跳转:
if ( $args ~ * tid=13){
return404;
}
访问/10690/tang/123跳转至/index.php?tid/10690/items=123,[0-9]表示任意一个数字,+表示多个,(.+)表示任何多个字符:
rewrite^/([0-9]+)/tang/(.+)$        /index.php?tid/$1/items=$2        last;
 
十、Nginx Web日志分析
Nginx访问日志打印的格式可以自定义,例如Nginx日志打印格式配置如下,Log_format用来设置日志格式,Name(模块名) Type(日志类型),可以配置多个日志模块,分别供不同的虚拟主机日志记录所调用:
log_format  main '$remote_addr - $remote_user [$time_local] "$request" '
                  '$status $body_bytes_sent"$http_referer" '
             '"$http_user_agent" $request_time';
log_format 指定日志格式niginx日志格式及其内部变量函数参数说明:
$remote_addr 记录客户端IP地址
$server_name 虚拟机主机名称
$http_x_forwarded_forHTTP请求的真实IP
$remote_user 记录客户端用户名称
$request记录请求的URL和Http协议版本
$status 记录返回http请求的状态
$upstream_statusupstream的状态
$ssl_protocol SSL协议版本
$body_bytes_sent发送客户端的字节数,不包括响应头的大小
$bytes_sent 发送客户端的总字节数
$connection_requests当前通过一个连接获得的请求数量
$http_referer记录从哪个页面链接过来的
$http_user_agent记录客户端浏览器的相关信息
$request_length请求的长度,包括请求行,请求头和正文
$msec 日志写入时间
$request_time请求处理的时间,单位为秒,精度毫秒,nginx发送第一个字节到发送完响应数据的时间。
$upstream_response_time应用程序响应的时间,nginx响应向后端服务器建立连接开始到接受完数据然后关闭连接为止的总时间。
1、access_log/usr/local/nginx/logs/access.log compression buffer=32k;access_log off;
access_log:为访问日志设置路径,格式和缓冲区的大小(nginx访问日志支持缓存)。 在同一个配置层级里可以指定多个日志。特定值off会取消当前配置层级里的所有access_log指令。 如果没有指定日志格式则会使用预定义的“combined”格式。
2、open_log_file_cachemax=1000 inactive=20s valid=1m min_uses=2;
open_log_file_cache:定义一个缓存,用来存储频繁使用的文件名中包含变量的日志文件描述符。 该指令包含以下参数:
max :设置缓存中描述符的最大数量;如果缓存被占满,最近最少使用(LRU)的描述符将被关闭。
inactive :设置缓存文件描述符在多长时间内没有被访问就关闭; 默认为10秒。
min_uses :设置在inactive参数指定的时间里, 最少访问多少次才能使文件描述符保留在缓存中;默认为1。
valid :设置一段用于检查超时后文件是否仍以同样名字存在的时间; 默认为60秒。
off : 禁用缓存功能
3、IP PV UV VV的介绍
IP:独立的IP,一天内相同的访问相同的IP地址被计算一次。
PV:PageView,就是页面浏览量或者点击量,就是每 次打开一个页面就算作一次PV,也指页面刷新的次数,每一次页面刷新,就算做一次PV流量。
UV:UniqueVisitor,独立访客数,一天内访问某站点的人数,以COOKIE为依据,一天内相同客户端的IP只被计算为一次访客。
VV : VisitView,访客访问的次数,当访客完成所有的浏览并最终关掉该网站的所有页面时,便完成了一次访问,同一访客一天内可能有多次访问行为,访问次数累计。
4、通过Nginx日志,可以简单分析WEB网站的运行状态、数据报表、IP、UV(uniquevisitor)、PV(page view)访问量等需求,如下为常用需求分析:
统计nginx服务器的独立IP数
awk  '{print $1}' access.log |sort -r|uniq -c | wc-l
统计Nginx的PV量
awk  '{print $7}' access.log |wc -l
统计Nginx服务器UV统计(仅做演示)
awk  '{print $11}' access.log |sort -r|uniq -c |wc-l
分析Nginx访问日志截止目前为止访问量前20的IP列表。
awk  '{print $1}'  access.log|sort |uniq -c|sort -nr |head -20
分析Nginx访问日志早上9点至中午12点的总请求量。
sed -rn'/06\/Nov\/2018:09/,/06\/Nov\/2018:12/'p access.log|wc -l
分析Nginx访问日志截止目前为止访问量前20的IP列表。
awk  '{print $1}'  access.log|sort |uniq -c|sort -nr |head -20
分析Nginx访问日志状态码404、502、503、500、499等错误信息页面,打印错误出现次数大于20的IP地址。
awk '{if($9~/502|499|500|503|404/) print $1,$9}' access.log |sort|uniq -c|sort -nr|awk'{if($1>20) print $2}'
分析Nginx访问日志访问最多的页面。
awk  '{print $7}'  access.log |sort |uniq -c|sort -nr|head -20
分析Nginx访问日志请求处理时间大于5秒的URL,并打印出时间、URL、访客IP。
awk  '{if ($NF>5)  print $NF,$7,$1}'  access.log|sort -nr|more
 
十一、Nginx 日志切割案例
如果Nginx没有默认日志切割,可以用以下脚本实现自动切割,并删除七天前的日志。脚本代码如下:
#!/bin/bash
#初始化
LOGS_PATH=/var/logs/nginx/
YESTERDAY=$(date -d"yesterday" +%Y-%m-%d)
#按天切割日志
mv${LOGS_PATH}/access.log ${LOGS_PATH}/access_${YESTERDAY}.log
#向 Nginx 主进程发送 USR1信号,重新打开日志文件,否则会继续往mv后的文件写内容,导致切割失败.
#kill usr1意将服务停止接受新的连接,等待当前连接停止,重新载入配置文件,重新打开日志文件,重启服务器,从而实现相对平滑的不关机的更改。
kill -USR1 `ps axu |grep "nginx: master process" | grep -v grep | awk '{print $2}'`
#删除7天前的日志
cd ${LOGS_PATH}
find . -mtime +7 -name"*20[1-9][3-9]*" | xargs rm -f
exit 0
将这个脚本添加到计划任务,每天执行一次即可:
0 0 * * */usr/local/script/cut_del_logs.sh > /dev/null 2>&1
 
十二、Nginx 防盗链配置案例
防止别人直接从你网站引用图片等链接,消耗了你的资源和网络流量。
location ~.*\.(jpg|gif|png|swf|flv|wma|wmv|asf|mp3|mmf|zip|rar)$ {
   expires 5d;
   valid_referers none blocked 堂.我爱你 *.堂.我爱你;
   if ($invalid_referer) {
    return 403;
    #rewrite ^/ http://wuyutang.top/403.jpg;
    break;
   }
  }
Nginx 防盗链参数详解:
valid_referers        表示可用的referers设置。
none                表示空的来路即不存在的Referer头,也就是直接访问,比如直接在浏览器打开一个图片。
blocked                表示被防火墙标记过的来路即Referer头。
 
十三、Nginx HTTPS 企业实战
HTTPS(全称:Hyper TextTransfer Protocol over Secure SocketLayer),是以安全为目标的HTTP通道,简单讲是HTTP的安全版。即HTTP下加入SSL层,HTTPS的安全基础是SSL,因此加密的详细内容就需要SSL。HTTPS有两部分组成,即HTTP+SSL/TLS,在HTTP基础上又加了一层处理加密信息的模块,服务端和客户端的信息传输都会通过TLS进行加密,传输的数据都是加密后的数据。
SSL(Secure SocketsLayer 安全套接层),及其继任者传输层安全(Transport LayerSecurity,TLS)是为网络通信提供安全及数据完整性的一种安全协议。TLS与SSL在传输层对网络连接进行加密。
SSL协议位于TCP/IP协议与各种应用层协议之间,为数据通讯提供安全支持。SSL协议可分为两层:SSL记录协议(SSL Record Protocol):它建立在可靠的传输协议(如TCP)之上,为高层协议提供数据封装、压缩、加密等基本功能的支持。
安全传输层协议(TLS)用于在两个通信应用程序之间提供保密性和数据完整性。该协议由两层组成:TLS 记录协议(TLS Record)和 TLS 握手协议(TLS Handshake)。较低的层为 TLS 记录协议,位于某个可靠的传输协议(例如TCP)上面,与具体的应用无关,所以,一般把TLS协议归为传输层安全协议。
HTTPS传输、解密、验证的完整过程:
1. 客户端发起HTTPS请求
用户在浏览器里输入一个https网址,然后连接到server的443端口。
2. 服务端的配置
采用HTTPS协议的服务器必须要有一套数字证书,可以自己制作,也可以向组织申请。区别就是自己颁发的证书需要客户端验证通过,才可以继续访问,而使用受信任的公司申请的证书则不会弹出提示页面(startssl就是个不错的选择,有1年的免费服务)。这套证书其实就是非对称加密中的公钥和私钥。
3. 传送证书
下发的证书其实就是公钥,只是包含了很多信息,如证书的颁发机构,过期时间等等。
4. 客户端解析证书
这部分工作是由客户端的TLS来完成的,首先会验证公钥是否有效,比如颁发机构,过期时间等等,如果发现异常,则会弹出一个警告框,提示证书存在问题。如果证书没有问题,那么就生成一个随即值(后续对称加密中用的私匙)然后用证书(客户端下发的公匙)对该随机值(客户端生成的私匙)进行加密。
5. 传送加密信息
传送的是用证书加密后的随机值(客户端私匙),目的就是让服务端得到客户端生成的私匙,以后客户端和服务端的通信就可以走对称加密流程了,也就是通过这个客户端产生的私匙来进行加密解密了。
6. 服务段解密信息
服务端用私钥(这个是第2步中和公匙对应的非对称加密的私匙)解密后,得到了客户端传过来的随机值(对称加密的私钥),然后把内容通过该值进行对称加密。所谓对称加密就是,将信息和私钥通过某种算法混合在一起,这样除非知道私钥,不然无法获取内容,而正好客户端和服务端都知道这个私钥,所以只要加密算法够彪悍,私钥够复杂,数据就够安全。
7. 传输加密后的信息
这部分信息是服务段用对称加密私钥加密后的信息,可以在客户端被还原
8. 客户端解密信息
客户端用之前生成的私钥解密服务段传过来的信息,于是获取了解密后的内容。整个过程第三方即使监听到了数据,也束手无策。
HTTPS证书申请与颁发方法:
1.安装nginx的时候的需要http_ssl_module模块
   否则在配置完server后重启nginx会出现[emerg] 10464#0:unknown directive “ssl” in…
./configure--prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module
 2. 生成证书步骤
cd/usr/local/nginx/conf
a、//使用openssl生成服务端RSA密钥及证书:
openssl genrsa -des3-out server.key 1024
b、//创建签名请求的证书(CSR):
openssl req -new -keyserver.key -out server.csr
c、//加载SSL支持的Nginx并使用私钥时去除口令:(可避免nginx配置SSL安全证书后,重启免输入密码)
#cp server.keyserver.key.bak
#openssl rsa -inserver.key.bak -out server.key
d、//自动签发证书:
openssl req -x509 -days3650 -key server.key -in server.csr -out server.crt 
说明:3650天表示十年,这是用步骤a,b的的密钥和证书请求生成证书server.crt,-days参数指明证书有效期,单位为天,x509表示生成的为X.509证书。以上签署证书仅仅做测试用,真正运行的时候,应该将CSR发送到一个CA返回真正的证书。网上有些文档描述生成证书文件的过程比较繁琐,就是因为    他们自己建立了一个CA中心,然后再签署server.csr。
用openssl x509 -noout-text -in server.crt 可以查看证书的内容。证书实际上包含了Public Key。
e、将crt证书格式导出为cer证书格式,供ios客服端调用使用:
openssl x509 -inserver.crt -out server.cer -outform der
f、将pem证书格式导出为crt证书格式
openssl x509 -outformder -in your-cert.pem -out your-cert.crt
3、nginx.conf文件配置:
server {
        listen       80;
        server_name 堂.我爱你;
        location / {
            root  html;
            index  index.php index.html index.htm;
            try_files $uri $uri//index.php?q=$uri&$args;
        rewrite ^(.*)  https://堂.我爱你$document_uri permanent;
        }
server {
        listen       443 ssl;
        server_name  堂.我爱你;
        ssl_certificate      /usr/local/nginx/conf/server.crt;
       ssl_certificate_key /usr/local/nginx/conf/server.key;
        ssl_session_cache    shared:SSL:1m;
        ssl_session_timeout  5m;
        ssl_ciphers  HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers  on;
        location / {
                root  html;
                index  index.php index.html index.htm;
                try_files $uri $uri//index.php?q=$uri&$args;
        }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
}
        location ~.*\.(html|htm|gif|jpg|jpeg|bmp|png|ico|txt|js|css|flv|wma|wmv|asf|mp3|mmf|zip|rar)$
                {
                        root html;
       #expires定义用户浏览器缓存的时间为3天,如果静态页面不常更新,可以设置更长。
                expires    7d;
        }
        location ~ \.php$ {
            #root   html;
            fastcgi_pass   127.0.0.1:9000;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
           # fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
            include        fastcgi_params;
        }
配置完重启nginx服务即可。