• Nginx介绍



    Nginx


    Nginx (engine x) 是一个高性能的HTTP和反向代理web服务器,同时也提供了IMAP/POP3/SMTP服务。Nginx是由伊戈尔·赛索耶夫为俄罗斯访问量第二的Rambler.ru站点(俄文:Рамблер)开发的,第一个公开版本0.1.0发布于2004年10月4日。

    其将源代码以类BSD许可证的形式发布,因它的稳定性、丰富的功能集、示例配置文件和低系统资源的消耗而闻名。2011年6月1日,nginx 1.0.4发布。

    Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,在BSD-like 协议下发行。其特点是占有内存少,并发能力强,事实上nginx的并发能力确实在同类型的网页服务器中表现较好,中国大陆使用nginx网站用户有:百度、京东、新浪、网易、腾讯、淘宝等。

    Nginx特性:
    轻量级、高性能HTTP服务器
    高性能的reverse proxy反向代理服务器
    代理http、mail
    基于模块化设计
    基于事件驱动模型
    重新加载配置及在线升级时,不需要中断正在处理的请求(nginx热部署)
    带缓存的日志写操作
    重写(rewrite)模块
    支持验证HTTP referer,实现反倒链机制
    支持sendfile,将数据在内核中直接封装响应客户端,不需要将数据复制到进程地址空间
    10000个非活跃的HTTP KEEPALIVE连接仅占用2.5M内存
    支持缓存功能

    WEB服务器响应客户端请求的方式:

    多进程方式
    	服务器每接收一个客户端请求,由服务器主进程生成一个子进程响应,响应结束后,子进程结束 
    	稳定
    多线程方式 
    	服务器每接收一个客户端请求,由服务器主进程生成一个线程响应
    	节点系统开销
    异步方式 
    

    同步机制和异步机制

    用于描述网络中的主机通信的模式
    同步机制
    	发送方发送请求后,需要等待接收方回应,才会继续发送下一个请求
    异步机制
    	发送方发送请求后,不等待接收文回应,继续发送下一个请求
    

    阻塞和非阻塞

    用于描述进程处理调用的方式 
    
    阻塞机制
    	调用结果返回前,进程会从运行状态切换到挂起状态,待调用结果返回后,进程再次进入就绪状态,获取CPU后继续执行
    非阻塞机制
    	调用结果如果不能及时返回,进程也不会进入挂起状态,而是开始处理下一个请求,待调用结果返回时,进程暂停运行该任务,开始继续处理上一个任务
    

    同步阻塞
    同步非阻塞
    异步阻塞
    异步非阻塞

    Nginx服务器处理请求的机制

    由主进程(master process)事先生成多个空闲的工作进程(worker process),每个工作进程等待客户端的访问请求 
    每个工作进程响应请求时,使用的是异步非阻塞方式
    

    Nginx的事件处理机制

    在非阻塞模型下,进程无法及时获取IO结果时,可以进行其他的操作;
    IO操作返回结果时,进程如何知道?
    	方法1: 进程每隔一段时间轮询一次
    	方法2:	IO操作完成后,主动通知进程 
    

    系统中的select, poll, epoll, kqueue4种系统调用机制就是实现第二种方法的应用,此4种模型也称为事件驱动机制;
    事件驱动机制可以使得进程可以同时处理多个请求

    Nginx的事件驱动模型

    Nginx服务器接收和处理客户端请求时,就是基于事件驱动机制的
    
    SELECT
    	Linux, windows平台支持的事件驱动模型
    	首先,创建所关注事件的描述符集合。对于每一个描述符,需要关注其上面的读事件,写事件,异常事件;所以要创建三类事件描述符集合 
    	调用底层以的select()函数,等待事件发生
    	轮询所有事件描述符,检查是否有事件发生,如果有,就进行处理 
    	
    POLL
    	Linux平台支持的事件驱动模型,2.1.23版本内核中引入 
    	和select一样,需要创建 一个关注事件的描述符集合,等待事件发生,轮询描述符集合,检测有没有事件发生,如果有,就执行 
    	不一样的是,select需要创建三类描述符集合,而poll只需要创建一类集合,在每个描述符下分别创建读、写、异常事件,最后轮询时,可同时轮询
    	
    EPOLL(事件驱动模型)
    	Linux 2.5.44内核后引入 
    	把描述符列表的管理交由内核负责,一旦有某种事件发生,内核把发生事件的描述符列表通知给进程,避免轮询减少系统开销
        (详解事件驱动模型)
    
    kqueue 
    	支持BSD系列平台的高效事件驱动模型 
    	
    /dev/poll 
    
    	支持UNIX衍生平台的高效事件驱动模型 
    	
    eventport 
    
    	支持Solaris 10及以上版本平台的高效事件驱动模型 
    

    Nginx服务器架构 :

    Nginx启动时会启动一个主进程master及多个子进程worker;配置缓存时还会启动cache load和cache manager进程。所有进程以"共享内存"机制完成进程间通信;master进程以特权用户运行,其他进程以非特权用户运行

    master主进程主要完成如下工作:
    1、读取并验证配置文件
    2、创建、绑定、及关闭套接字
    3、启动、终止及维护worker进程的个数
    4、无须中止服务而重新配置工作特性
    5、控制非中断式程序升级,启用新的二进制程序并在需要时回滚至老版本
    6、重新打开日志文件
    7、编译嵌入式perl脚本

    worker进程主要完成如下工作:
    1、接收、传入并处理客户端的连接
    2、提供反向代理及过滤功能
    3、IO调用,获取响应数据
    4、与后端服务器通信,接收后端服务器处理结果
    5、数据缓存、访问缓存索引、查询和调用缓存数据
    6、发送请求结果,响应客户端请求
    7、接收主程序指令,比如重启、退出、升级等

    cache load进程主要完成的工作:
    1、检查缓存存储中的缓存对象
    2、使用缓存元数据建立内存数据库

    cache manager进程的主要工作:
    1、缓存的失效及过期检验

    Nginx配置是分段的:
    main,http,server,upstream(反向代理),location(类似于documentroot),mail

    Nginx安装

    useradd nginx

    yum install -y pcre-devel openssl-devel

    tar zxf nginx-1.4.7.tar.gz

    cd nginx-1.4.7

    ./configure

    --prefix=/usr/local/nginx
    --error-log-path=/var/log/nginx/error.log
    --http-log-path=/var/log/nginx/access.log
    --pid-path=/var/run/nginx/nginx.pid
    --lock-path=/var/lock/nginx.lock
    --user=nginx
    --group=nginx
    --with-http_ssl_module
    --with-http_flv_module
    --with-http_stub_status_module
    --with-http_gzip_static_module
    --http-client-body-temp-path=/var/tmp/nginx/client
    --http-proxy-temp-path=/var/tmp/nginx/proxy
    --http-fastcgi-temp-path=/var/tmp/nginx/fcgi
    --http-uwsgi-temp-path=/var/tmp/nginx/uwsgi
    --http-scgi-temp-path=/var/tmp/nginx/scgi
    --with-pcre
    --with-file-aio
    --with-http_ssl_module
    --with-http_secure_link_module
    --with-http_perl_module

    make && make install

    http://pan.baidu.com/share/link?shared=402894734&uk=3340480807

    nginx服务启动脚本:

    !/bin/bash

    chkconfig: 2345 86 14

    Descirption: Nginx Script File

    prog="/usr/local/nginx/sbin/nginx"
    pfile="/var/run/nginx/nginx.pid"

    if [ $# -ne 1 ];then
    echo "Usage:basename $0 { start | stop | restart | reload | configtest }"
    exit 9
    fi

    case $1 in
    start)
    $prog
    if [ $? -eq 0 ];then
    echo "Starting nginx service ..... [ok]"
    # create lock file
    touch /var/lock/subsys/nginx
    fi
    ;;
    stop)
    kill cat $pfile
    if [ $? -eq 0 ];then
    echo "Stopping nginx.... [ok]"
    fi
    ;;
    restart)
    kill cat $pfile
    echo "Stopping nginx...."
    $prog
    if [ $? -eq 0 ];then
    echo "Starting nginx service ..... [ok]"
    # create lock file
    touch /var/lock/subsys/nginx
    fi
    ;;
    reload)
    kill -s HUP cat $pfile
    ;;
    configtest)
    $prog -t &> /dev/null
    if [ $? -eq 0 ];then
    echo "Syntax is ok!!!"
    else
    $prog -t
    fi
    ;;
    *)
    echo "Usage:basename $0 { start | stop | restart | reload | configtest }"
    ;;
    esac

    mime:多用途互联网邮件扩展
    用于识别非文本文档

    Nginx配置---/etc/nginx/nginx.conf

    启动worker进程的数量;如果是CPU密集型,如SSL及压缩应用,worker数量与CPU个数一致;如果是IO密集型,如响应大量给客户端 ,worker进程个数为CPU个数的1.5或者2倍
    worker_processes 1;

    每个worker进程支持的连接数
    events {
    worker_connections 1024;
    }

    启用sendfile机制
    sendfile on;

    启用长连接并设置超时时间
    keepalive_timeout 65;

    是否对发送给客户端的内容进行压缩

    gzip on;

    每个server定义一个虚拟主机 server { }

    location / {
    root html;
    index index.html index.htm;
    }

    location /URI路径 {
    root "/web/htdocs" 定义URI路径所对应的网页文件存放的路径
    }
    URI路径
    http://www.bj.com/URI路径

    如果错误代码为500,502,503,504,则返回URI路径下50x.html页面内容
    error_page 500 502 503 504 /50x.html;

    location [ = | ~ | ~* | ^~ ] URI路径 {...}

    location URI路径 {}:
    对当前路径及子路径下的所有资源都生效

    location = URI路径 {}:
    精确匹配指定路径,不包括子路径,因此只对当前资源生效

    location ~ URI路径 {}:区分大小写
    locaiton ~* URI路径 {}:不区分大小写
    模式匹配URI路径,此处的URI可使用正则表达式

    location ^~ URI路径 {}
    不使用正则表达式

    匹配优先级:
    =匹配优先级最高
    ^~匹配优先级次之
    ~ ~*

    示例1:客户端通过http://10.1.1.1访问/web/htdocs下的网页
    location / {
    root /web/htdocs;
    index index.html index.htm;
    }

    示例2:客户端通过http://10.1.1.1/bbs,访问/web/bbs下的网页
    location /bbs {
    root /web;
    index index.html index.htm;
    }

    基于客户端IP地址进行访问控制
    location / {
    ....
    allow 10.1.1.100;
    deny 10.1.1.0/24;
    }
    默认规则是允许访问。如果想要明确禁止某个客户端访问可直接写deny 10.1.1.1;
    如果想要明确只允许某个客户端访问,要这样写
    allow 10.1.1.100
    deny all

    基于用户名/密码认证访问
    location / {
    auth_basic "please input user:";
    auth_basic_user_file /etc/nginx/.user;
    }

    使用htpasswd命令创建用户名、密码

    配置显示nginx连接数
    location /status {
    stub_status on;
    access_log off;
    allow 10.1.1.100;
    deny all;
    }

    http://10.1.1.1/status访问结果

    Active connections: 4 打开的所有连接数
    server accepts handled requests
    10 10 36 已经接受的连接数 已经处理的连接数 已经处理的请求数
    Reading: 0 Writing: 1 Waiting: 3
    Reading:nginx正在读取其报文首部的连接数
    Writing:nginx正在读取其报文主体的连接数、或者正在处理请求的请求个数以及正在响应客户端的连接个数
    Waiting:长连接中保持活动连接的连接个数(Reading+Writing)

    配置基于SSL的HTTP

    HTTPS server

    server {
        listen       443 ssl;
        server_name  localhost;
    
        ssl_certificate      /usr/local/nginx/ssl/nginx.crt;
        ssl_certificate_key  /usr/local/nginx/ssl/nginx.key;
    
        ssl_session_cache    shared:SSL:1m;
        ssl_session_timeout  5m;
    
        ssl_ciphers  HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers  on;
    
        location / {
            root   /web/ssl;
            index  index.html index.htm;
        }
    }
    

    生成自签证书:

    cd /etc/pki/CA

    生成证书服务器私钥

    (umask 077; openssl genrsa 2048 > private/cakey.pem)

    Generating RSA private key, 2048 bit long modulus
    .........................+++
    ..............+++
    e is 65537 (0x10001)

    生成自签证书

    openssl req -new -x509 -key private/cakey.pem -out cacert.pem

    touch index.txt

    echo 01>serial

    生成WEB服务器的密钥

    mkdir /usr/local/nginx/ssl

    cd /usr/local/nginx/ssl

    (umask 077;openssl genrsa 1024 > nginx.key)

    Generating RSA private key, 1024 bit long modulus
    ..............................++++++
    .............++++++
    e is 65537 (0x10001)

    创建证书申请

    openssl req -new -key /usr/local/nginx/ssl/nginx.key -out /usr/local/nginx/ssl/nginx.csr

    签署证书

    cd /usr/local/nginx/ssl/

    openssl ca -in nginx.csr -out nginx.crt -days 3650

    配置基于域名的虚拟主机
    server {
    listen 80;
    server_name www.a.com;
    location / {
    root /web/a;
    index index.html;
    access_log /var/log/nginx/bj/access_log main;
    error_log /var/log/nginx/bj/error_log;
    }
    }

    nginx添加第三方模块支持

    http://labs.frickle.com/nginx_ngx_cache_purge/下载最新版本模块

    1、查看nginx当前编译的模块

    [root@www nginx-1.11.4]# /usr/local/nginx/sbin/nginx -V
    nginx version: nginx/1.11.4
    built by gcc 4.4.7 20120313 (Red Hat 4.4.7-11) (GCC)
    built with OpenSSL 1.0.1e-fips 11 Feb 2013
    TLS SNI support enabled
    configure arguments: --prefix=/usr/local/nginx --user=nginx --group=nginx --with-threads --with-file-aio --with-ipv6 --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_addition_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_auth_request_module --with-http_random_index_module --with-http_secure_link_module --with-http_degradation_module --with-http_stub_status_module --with-http_slice_module --http-client-body-temp-path=/var/tmp/nginx/client --http-proxy-temp-path=/var/tmp/nginx/proxy --http-fastcgi-temp-path=/var/tmp/nginx/fastcgi --http-uwsgi-temp-path=/var/tmp/nginx/uwsgi --http-scgi-temp-path=/var/tmp/nginx/scgi --with-pcre

    2、解压缩下载的模块,重新编译nginx添加新模块支持

    [root@www nginx-1.11.4]# tar zxf ngx_cache_purge-2.3.tar.gz
    [root@www ~]# cd nginx-1.11.4
    [root@www nginx-1.11.4]# ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-threads --with-file-aio --with-ipv6 --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_addition_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_auth_request_module --with-http_random_index_module --with-http_secure_link_module --with-http_degradation_module --with-http_stub_status_module --with-http_slice_module --http-client-body-temp-path=/var/tmp/nginx/client --http-proxy-temp-path=/var/tmp/nginx/proxy --http-fastcgi-temp-path=/var/tmp/nginx/fastcgi --http-uwsgi-temp-path=/var/tmp/nginx/uwsgi --http-scgi-temp-path=/var/tmp/nginx/scgi --with-pcre --add-module=/root/ngx_cache_purge-2.3
    [root@www nginx-1.11.4]# make

    注意不要make install,否则会覆盖安装

    3、 替换nginx可执行命令即可

    [root@www ~]# /usr/local/nginx/sbin/nginx -s stop
    [root@www ~]# cp /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.bak
    [root@www ~]# cd nginx-1.11.4
    [root@www nginx-1.11.4]# cp objs/nginx /usr/local/nginx/sbin/nginx

    LEMP/LNMP:
    PHP+MySQL

    仅支持以FastCGI方式工作的PHP

    编译安装cmake

    tar zxf cmake-2.8.6.tar.gz

    cd cmake-2.8.6

    ./configure

    make && make install

    安装MySQL

    groupadd mysql

    useradd -g mysql -s /sbin/nologin mysql

    mkdir /mydata/data -p

    chown -R mysql.mysql /mydata/data/

    tar zxf mysql-5.5.28.tar.gz

    cd mysql-5.5.28

    cmake . -DCMAKE_INSTALL_PREFIX=/usr/local/mysql

    -DMYSQL_DATADIR=/mydata/data
    -DSYSCONFDIR=/etc
    -DWITH_INNOBASE_STORAGE_ENGINE=1
    -DWITH_ARCHIVE_STORAGE_ENGINE=1
    -DWITH_BLACKHOLE_STORAGE_ENGINE=1
    -DWITH_SSL=system
    -DWITH_ZLIB=system
    -DWITH_LIBWRAP=0
    -DMYSQL_UNIX_ADDR=/tmp/sql.sock
    -DDEFAULT_CHARSET=utf8
    -DDEFAULT_COLLATION=utf8_general_ci

    make && make install

    chgrp -R mysql /usr/local/mysql/

    cd /usr/local/mysql

    scripts/mysql_install_db --user=mysql --basedir=/usr/local/mysql --datadir=/mydata/data/

    cp support-files/my-large.cnf /etc/my.cnf

    cp support-files/mysql.server /etc/init.d/mysqld

    chmod +x /etc/init.d/mysqld

    chkconfig --add mysqld

    chkconfig --list mysqld

    mysqld 0:off 1:off 2:on 3:on 4:on 5:on 6:off

    vim /etc/profile.d/mysql.sh

    export PATH=$PATH:/usr/local/mysql/bin

    source /etc/profile.d/mysql.sh

    vim /etc/ld.so.conf.d/mysql.conf

    /usr/local/mysql/lib

    ldconfig

    ln -s /usr/local/mysql/include/ /usr/include/mysql

    安装php-5.3.6

    yum localinstall -y --nogpgcheck libmcrypt-2.5.7-1.2.el6.rf.i686.rpm libmcrypt-devel-2.5.7-1.2.el6.rf.i686.rpm mhash-0.9.9-1.el6.rf.i686.rpm mhash-devel-0.9.9-1.el6.rf.i686.rpm mcrypt-2.6.8-10.el6.i686.rpm

    tar zxf php-5.3.6.tar.gz

    cd php-5.3.6

    ./configure --prefix=/usr/local/php --with-mysql=/usr/local/mysql --with-openssl --with-mysqli=/usr/local/mysql/bin/mysql_config --enable-mbstring --with-freetype-dir --with-jpeg-dir --with-png-dir --with-zlib --with-libxml-dir=/usr --enable-xml --enable-sockets --enable-fpm --with-mcrypt --with-config-file-path=/etc --with-config-file-scan-dir=/etc/php.d --with-bz2

    make && make install

    复制php配置文件

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

    复制php-fpm配置文件

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

    复制php-fpm启动脚本

    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 --list php-fpm

    php-fpm 0:关闭 1:关闭 2:启用 3:启用 4:启用 5:启用 6:关闭

    编辑/usr/local/php/etc/php-fpm.conf配置文件

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

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

    /etc/init.d/php-fpm start

    Starting php-fpm done

    netstat -tnlp | grep php-fpm

    tcp 0 0 127.0.0.1:9000 0.0.0.0:* LISTEN 15457/php-fpm

    整合nginx和php
    编辑nginx配置文件,去掉如下配置的注释:

    vim /etc/nginx/nginx.conf

    location ~ .php$ {
    root /web/htdocs;
    fastcgi_pass 127.0.0.1:9000;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
    include fastcgi_params;
    }

    编辑/etc/nginx/fastcgi_params文件,并将内容修改为如下内容,配置fastcgi参数:
    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;

    编辑nginx配置文件,指定php首页

    vim /etc/nginx/nginx.conf

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

    /etc/init.d/nginx restart

    在/web/htdocs目录下创建php页面,测试访问

    vim /web/htdocs/index.php

    xcache:在同一个PHP服务器,为多个进程缓存同一个opcode

    安装xcache-2.0.0,加速php解析

    yum install -y m4 autoconf

    tar zxf xcache-2.0.0.tar.gz

    cd xcache-2.0.0

    生成configure配置程序

    /usr/local/php/bin/phpize

    Configuring for:
    PHP Api Version: 20090626
    Zend Module Api No: 20090626
    Zend Extension Api No: 220090626

    ./configure --enable-xcache --with-php-config=/usr/local/php/bin/php-config

    make && make install

    安装完毕后,有如下提示:
    Installing shared extensions: /usr/local/php/lib/php/extensions/no-debug-non-zts-20090626/

    编辑php.ini,整合php与xcache

    将xcache提供的样例配置导入php.ini

    mkdir /etc/php.d

    cp xcache.ini /etc/php.d/

    编辑/etc/php.d/xcache.ini,找到zend_extension开头的行,修改为如下内容:
    zend_extension = /usr/local/php/lib/php/extensions/no-debug-non-zts-20090626/xcache.so

    重新启动php-fpm
    /etc/init.d/php-fpm restart

    通过浏览器再次浏览php页面,在页面中可以找到关于xcache特性说明,表明成功
    XCache
    XCache Support enabled
    Version 2.0.0
    Modules Built cacher
    Readonly Protection N/A
    Cache Init Time 2015-12-24 14:04:43
    Cache Instance Id 19574
    Opcode Cache enabled, 62,914,560 bytes, 1 split(s), with 8192 slots each
    Variable Cache enabled, 4,194,304 bytes, 1 split(s), with 8192 slots each
    Shared Memory Schemes mmap

    location ~* .php$ {
    fastcgi_pass 127.0.0.1:9000;
    }

    Nginx反向代理

    server {
    listen 80;
    server_name www.bj.com;
    location / {
    后端服务器;
    }
    }

    后端服务器:
    proxy_pass

    示例:

    用户访问http://10.1.2.1/forum时,将以后台服务器10.1.2.2的bbs目录中的页面返回客户端

    location /forum {
    proxy_pass http://10.1.2.2/bbs;
    }

    特殊情况:
    如果在定义location时,加入了~ ~* ^~这样的模式匹配字符,proxy_pass在写时,只能写到服务器地址
    location ~* /forum {
    proxy_pass http://10.1.1.2;
    }

    当用户访问www.bj.com/forum时,将代理到http://10.1.1.2/forum

    nginx反向代理示例配置:
    10.1.1.1安装nginx作为前端服务器
    10.1.1.2安装httpd作为后端服务器

    客户端访问http://10.1.1.1/forum时,代理到后端服务器的http://10.1.1.2/bbs
    location /forum {
    proxy_pass http://10.1.1.2/bbs;
    }

    使用模式匹配的方式定义location,当客户端访问http://10.1.1.1/forum时,代理到后端服务器http://10.1.1.2/forum上
    location ~* ^/forum {
    proxy_pass http://10.1.1.2;
    }
    后端服务器上也要有对应的forum目录

    此时,对于后端服务器来说,access_log中记录的日志,客户端IP是nginx的IP
    10.1.1.1 - - [24/Dec/2015:16:35:36 +0800] "GET /forum/ HTTP/1.0" 200 35 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 BIDUBrowser/8.1 Safari/537.36"

    配置proxy_set_header,实现后端服务器记录真实的客户端IP

    编辑/etc/nginx/nginx.conf

    vim /etc/nginx/nginx.conf

    location ~* ^/forum {
    proxy_pass http://10.1.1.2;
    proxy_set_header X-Real-IP $remote_addr;
    }

    proxy_set_header X-Real-IP $remote_addr;
    代理在httpd请求报文中加入X-Real-IP段的内容,该内容是变量$remote_addr的值,即真实客户端的IP

    编辑后端服务器配置文件/etc/httpd/conf/httpd.conf,修改combined日志格式,将客户端地址%h换成%{X-Real-IP}i,表示记录HTTP请求报文中X-Real-IP的内容
    LogFormat "%{X-Real-IP}i %l %u %t "%r" %>s %b "%{Referer}i" "%{User-Agent}i"" combined

    刷新浏览器,再次查看后端服务器access_log,日志中记录的是真实客户端的IP地址10.1.1.100
    10.1.1.100 - - [24/Dec/2015:16:38:54 +0800] "GET /forum/ HTTP/1.0" 200 35 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 BIDUBrowser/8.1 Safari/537.36"

    将前端所有请求代理到后端WEB服务器

    location / {

    root html;

    index index.html index.htm;

    }

    location / {
    proxy_pass http://192.168.0.101/;
    proxy_set_header x-real-ip $proxy_add_x_forwarded_for;
    }

    Nginx负载均衡

    Nginx负载均衡算法:
    roundrobin, rr,轮询,默认算法
    ip_hash:根据请求报文中的源IP地址,将相同客户端的请求转发到同一个服务器上
    least_conn

    nginx负载均衡配置:

    定义upstream段,指定后端服务器IP;upstream段要写在server段外面
    upstream webserver {
    server 10.1.1.2 weight=1 max_fails=2 fail_timeout=2;
    server 10.1.1.3 weight=1 max_fails=2 fail_timeout=2;
    server 127.0.0.1:8080 backup;
    }

    server {
    ....
    location / {
    proxy_pass http://webserver/;
    proxy_set_header X-Real-IP $remote_addr;
    }
    }

    定义虚拟主机,提供错误页面
    server {
    listen 8080;
    server_name localhost;
    location / {
    root /web/sorry;
    index index.html;
    }
    }
    在/web/sorry目录下提供index.html错误页面

    经过以上配置后,当客户端访问http://10.1.1.1时,由后端两台服务器10.1.1.2和10.1.1.3负载均衡方式提供页面;当两台后端服务器均down后,跳转到本地8080端口所对应的页面

    配置使用ip_hash算法将同一个客户端的请求代理到相同的后端服务器

    upstream webserver {
    ip_hash;
    server 192.168.0.101 weight=1 max_fails=2 fail_timeout=2;
    server 192.168.0.111 weight=1 max_fails=2 fail_timeout=2;
    #server 127.0.0.1:8080 backup; >>>ip_hash算法不支持backup,因此将其注释
    }

    Nginx缓存
    缓存组成的两部分:
    共享内存: 存储键和缓存对象元数据
    磁盘空间:存储数据

    定义缓存空间
    proxy_cache_path: 不能定义在server{}中

    proxy_cache_path /nginx/cache/first levels=1:2:3 keys_zone=first:20m max_size=1G

    levels=
    定义缓存目录子目录的级别,及每个子目录的名称字符个数; 最多只能有3级子目录
    levels=1:2:2,3级子目录,第1级目录字符个数为1,第2级目录字符个数为2,第3级目录字符个数为2,字符个数最多只能有2个
    keys_zone=name:size
    定义存储键的区域(定义共享内存的名称)
    max_size=1G
    指定/nginx/cache/first中的1G空间用于存储缓存数据

    Nginx缓存配置:

    定义缓存存放路径为/web/cache/first, 最多使用1G空间; 并定义键值区域名称为first,大小为20m
    proxy_cache_path /web/cache/first levels=1:2 keys_zone=first:20m max_size=1g;

    在location中开启缓存功能,指定使用键值名称为first的缓存
    在httpd响应报文中添加额外项X-cache,用于查看缓存是否命中

    add_header X-cache "$upstream_cache_status by $server_addr";
    $upstream_cache_status: 用于记录缓存是否命中的状态

    location / {
    proxy_pass http://webserver/;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_cache first;
    proxy_cache_valid 200 1m;
    }

    proxy_cache_valid 200 1m;
    表示为状态码为200的数据缓存1分钟

    查看缓存是否命中,在浏览器中按F12打开开发者模式,查看HTTP响应报文,可以看到X-cache:HIT by 10.1.1.1信息,表示缓存命中

    常用的3种缓存:
    open_log_cache:日志缓存,将日志先保存到内存,再同步到磁盘,降低磁盘IO
    open_file_cache:加快响应速度 
    fastcgi_cache

    rewrite:URL地址重写

    1、if指令

    if (condition) {......}

    {...}	代表条件为真时的nginx操作 	
    

    condition条件的写法:

    1. 变量名

      如果变量的值为空,或者为以"0"开头的任意字符串,条件为假,其他则为真

      if($slow) {....}

    2. 使用"="或者"!="比较变量的值

      if($request_method = POST) {.....}

    3. 使用正则表达式与变量的值进行匹配

      变量名与正则表达式间使用~, ~, !~, !~进行连接

      在正则表达式中使用()可以对字符进行分组,在{}中可以用$1....$9引用分组

      正则表达式写时不需要加双引号,但是如果正则表达式中含有}和;字符,则必须要使用双引号

      if ($http_user_agent ~ MSIE) {.....}

    4. 判断请求的文件是否存在

      if ( -f $request_filename) {.....}

      if (!-f $request_filename) {.....}

    5. 判断请求的目录是否存在 (-d, !-d)

    6. 判断请求的目录或文件是否存在 (-e, !-e)

    7. 判断请求的文件是否可执行 (-x, !-x)

    2、break指令

    该指令用于中断当前相同作用域中的其他 nginx配置 
    
    与该指令处于同一个作用域的nginx配置,位于break前的生效,位于break的配置无效 
    
    location / {
    	if ($slow) {
    		set $id $1
    		break 
    		limit_rate 10k;
    	}
    }
    

    3、return指令

    该指令用于完成对请求的处理,直接向客户端返回响应状态代码。
    处于该指令后的所有nginx配置都是无效的
    该指令可用于server, location, if段中 
    
    语法结构 :
    
    	return [ text ]
    	return code URL;
    	return URL;
    	
    		code 
    			为返回客户端的HTTP状态代码。范围是0---999 
    			非标准的444代码可以强制关闭服务器与客户端的连接而不返回任何响应信息给客户端 
    		text 
    			为返回给客户端的响应体内容,支持变量的使用
    		URL
    			为返回给客户端的URL地址 
    
    
    当code使用301, 302, 303, 307时,可以使用结构2将新的URL返回给客户端 
    
    除上面指定的代码,结构1指定text向客户端发送指定的内容 
    
    当返回状态码为302, 307时,可以使用结构3对URL进行配置。返回的URL中应该包括http://, https://或者直接使用变量$scheme指定 
    

    4、rewrite指令

    该指令通过使用正则表达式的使用来改变URI。
    可以同时存在一条或者多条,按顺序依次对URL进行匹配和处理 
    
    该指令可用于server, location中 
    
    语法结构: 
    
    	rewrite <REGEX> <REPLACEMENT> [FLAG]
    	
    		REGEX 	用于匹配URI的正则表达式 
    		
    		注意: 
    			1) rewrite接收到的URL地址不包括主机名称部分 
    			2) 不包括URL地址中的请求指令 
    			
    				https://reg.jd.com/reg/person?ReturnUrl=https%3A//sale.jd.com/act/r1z8LpvTcxkDbge.html
    
    	REPLACEMENT		
    		匹配成功后用于替换URI中被截取内容的字符串。默认情况下,如果字符串是以http://或者https://开头,则不会继续 向下对URI进行其他处理,而直接将重写后的URI返回给客户端 			
    		
    		支持变量的使用 
    		
    	FLAG 
    	
    		1) last 
    			终止继续在本location块中处理接收到的URI,并将此处重写的URI作为一个新的URI,使用各location块进行处理 
    			
    			location / {
    				rewrite ^(/myweb/.*)/media/(.*)..*$	$1/mp3/$2.mp3  last; 
    				rewrite ^(/myweb/.*)/audio/(.*)..*$	$1/mp3/$2.ra   last;
    			}
    			
    		2) break 
    			将此处重写的URI作为一个新的URI,在本块中继续进行处理。该标志将重写后的地址在当前的location块中执行,不会将新的URI转向到其他location块
    			
    			location /web/ {
    				rewrite ^(/myweb/.*)/media/(.*)..*$	$1/mp3/$2.mp3 break; 
    				rewrite ^(/myweb/.*)/audio/(.*)..*$	$1/mp3/$2.ra break;
    			}
    		
    		3) redirect 
    			将重写后的URI返回给客户端,状态代码为302,指明是临时重定向,主要用在replacement不是以http://或者https://开头的情况下
    		
    		4) permanent 
    		
    			将重写后的URI返回给客户端,状态代码为301,指明是永久重写向
    

    5、rewrite_log指令

    该指令配置是否开启URL重写日志的输出功能
    
    rewrite_log {on|off}
    
    如果为on时,URI地址重写的信息会以notice级别记录到error_log中
    

    6、set指令

    用于配置一个新的变量 
    
    set <variable> <value>
    	
    	变量名称要以$开头 
    

    7、uninitialized_variable_warm指令

    用于在使用未初始化的变量时,是否记录警告日志 
    
    uninitialized_variable_warm {on|off}
    

    Nginx变量

    1. $args

      存放URL中的请求指令

      https://reg.jd.com/reg/person?ReturnUrl=https%3A//sale.jd.com/act/r1z8LpvTcxkDbge.html

       ReturnUrl=https%3A//sale.jd.com/act/r1z8LpvTcxkDbge.html 
      
    2. $content_length

      存放请求报文中content_length字段内容

    3. $content_type

      存放请求报文中content_type字段内容

    4. $document_root

      存放针对当前请求的根路径

    5. $document_uri

      存放请求报文中的当前URI,并且不包括请求指令

      https://reg.jd.com/reg/person?ReturnUrl=https%3A//sale.jd.com/act/r1z8LpvTcxkDbge.html

       /reg/person		
      
    6. $host

      存放请求报文中的主机部分

      https://reg.jd.com/reg/person?ReturnUrl=https%3A//sale.jd.com/act/r1z8LpvTcxkDbge.html

       reg.jd.com		
      
    7. $http_user_agent

      存放客户端代理信息

    8. $http_cookie

      存放客户端的cookie信息

    9. $limit_rate

      存放nginx服务器对网络连接速率的限制,也就是ngnix配置文件中limit_rate指令的值

    10. $remote_addr

      存放客户端地址

    11. $remote_port

      存放客户端端口

    12. $remote_user

      存放客户端的用户名

    13. $request_body_file

      存放发给后端服务器的本地文件资源名称

    14. $request_method

      存放客户端请求资源的方法, GET, POST, PUT

    15. $request_filename

      存放当前请求的资源文件的路径名

    16. $request_uri

      存放当前请求的URI,并且带有请求指令

      https://reg.jd.com/reg/person?ReturnUrl=https%3A//sale.jd.com/act/r1z8LpvTcxkDbge.html

      /reg/person?ReturnUrl=https%3A//sale.jd.com/act/r1z8LpvTcxkDbge.html
      
    17. $query_string

      与变量$args含义相同

    18. $scheme

      存放客户端请求使用的协议,如果http, https

    19. $server_protocol

      存放客户端请求协议的版本 HTTP/1.0 HTTP/1.1

    20. $server_addr

      存放服务器地址

    21. $server_name

      存放了客户端请求到达的服务器的名称

    22. $server_port

      存放了客户端请求到达的服务器的端口号

    23. $uri

      与变量$document_uri含义相同

    rewrite应用:

    示例1:

    location / {
    root html;
    index index.html index.htm;
    rewrite "^/forum/(.*)" http://192.168.0.101/bbs/$1;
    }

    示例2:域名跳转

    server {
    listen 80;
    server_name jump.myweb.name;
    rewrite ^/ http://www.myweb.info/;
    }

    示例3:

    server {
    listen 80;
    server_name jump.myweb.name jump.myweb.info;
    if ($host ~ myweb.info$) {
    rewrite ^(.*) http://jump.myweb.name$1;
    }
    }

    示例4:

    server {
    listen 80;
    server_name jump1.myweb.name jump.myweb.name;
    if ($host ~ ^(.).myweb.name$) {
    rewrite ^(.
    ) http://jump.myweb.name$1;
    }

    WebDAV(Web-based Distributed Authoring and Versioning)
    一种基于HTTP 1.1协议的通信协议,它扩展了HTTP 1.1,在GET,POST,HEAD等几个HTTP标准方法以外添加了一些新的方法,使应用程序可直接对Web Server直接读写,并支持写文件锁定(Locking)及解锁(Unlock),还可以支持文件的版本控制。

    rpm httpd默认支持DAV功能
    通过此协议可以支持在Web Server上传文件

    Nginx读写分离

    前端:Nginx服务器  10.1.1.1 
    后端:Apache服务器	10.1.1.2   10.1.1.3(可在此服务器上传文件)
    

    确保10.1.1.3服务器开启DAV功能

    确保Apache配置文件加载了DAV相关模块

    vim /etc/httpd/conf/httpd.conf

    LoadModule dav_module modules/mod_dav.so
    LoadModule dav_fs_module modules/mod_dav_fs.so

    在相应网页根目录授权段中开启DAV
    <Directoy "/var/www/html">
    ....
    dav on

    确保运行httpd进程的apache用户对网页根目录拥有写入权限

    setfacl -m u:apache:rwx /var/www/html/

    测试在客户端可以向10.1.1.3服务器上传文件

    curl -T /etc/issue http://10.1.1.3

    前端Nginx服务器配置读写分离,读操作代理到10.1.1.2上,写操作代理到10.1.1.3上;

    vim /etc/nginx/nginx.conf

    location / {
    proxy_pass http://10.1.1.2;
    if ($request_method = "PUT") {
    proxy_pass http://10.1.1.3;
    }
    }

    测试nginx读写分离操作是否成功

    读取网页内容时,代理后10.1.1.2服务器上

    curl http://10.1.1.1

    Apache Page of 10.1.1.2

    上传文件时,代理到后端10.1.1.3服务器上

    curl -T /etc/fstab http://10.1.1.1

    201 Created

    Created

    Resource /fstab has been created.


    Apache/2.2.15 (Red Hat) Server at 10.1.1.3 Port 80

    后端两台服务器通过rsync+inotify进行数据同步,保证上传的数据可以同步到后端所有服务器上

    Nginx服务器高级配置

    1、针对IPV4内核的配置优化参数

    vim /etc/sysctl.conf

    net.core.netdev_max_backlog = 20000
    net.core.somaxconn = 20000
    net.ipv4.tcp_max_orphans = 20000
    net.ipv4.tcp_max_syn_backlog = 20000
    net.ipv4.tcp_timestamps = 0
    net.ipv4.tcp_synack_retries = 1
    net.ipv4.tcp_syn_retries = 1

    参数说明:

    1. net.core.netdev_max_backlog

      表示当每个网络接口接收数据包的速率比内核处理这些包的速率快时,允许发送到队列的数据包的最大数目。默认为128

    2. net.core.somaxconn

      用于调节系统同时发起的TCP连接数,一般默认值是128. 在存在高并发时,可将该值调大

    3. net.ipv4.tcp_max_orphans

      用于设置系统中最多允许存在多少TCP套接字不被关联到任何一个用户文件句柄上。
      如果超过这个数字 ,没有与用户文件句柄关联的TCP套接字将立即被复位,同时给出警告信息
      在内存比较充足的情况下可调大此值

    4. net.ipv4.tcp_max_syn_backlog

      用于记录尚未收到客户端确认信息的连接请求的最大值
      在内存比较充足的情况下可调大此值

    5. net.ipv4.tcp_timestamps

      用于设置时间戳,这可以避免序列号的卷绕
      默认情况下,TCP协议会让内核接收这种“异常(序列号一致)"的数据包
      针对nginx服务器而言,建议将其关闭

    6. net.ipv4.tcp_synack_retries

      用于设置内核放弃TCP连接前向客户端发送SYN+ACK包的数量
      一般赋值为1

    7. net.ipv4.tcp_syn_retries

      用于设置内核放弃TCP连接前,向客户端发送SYNC包的数量
      一般赋值为1

    2、针对CPU的配置优化

    1. worker_processes

      该指定用于设置nginx服务的工作进程数;建议设置为CPU个数的2倍
      针对双核CPU,可以设置为2或者4

    2. worker_cpu_affinity

      用于设置每个进行分配CPU的工作内核

      worker_cpu_affinity 0001 0100 1000 0010

       以上4组二进制数字分别对应worker_processes指定的4个工作进程 
       其中0001,代表第1个进程使用CPU的第1个核心进行处理,0100代表使用CPU第3个核心进行处理
      

    3、针对网络连接相关的配置参数

    1. keepalive_timeout

      用于设置长连接的超时时间
      该参数支持两个选项,不同的选项使用空格隔开,例如:
      keepalive_timeout 60 50;
      该设置表示nginx服务器与客户端的长连接活动时间为60s,60s后服务器与客户端断开连接;使用keep-alive消息头保持与客户端某些浏览器的连接时间为50s,50s后浏览器主动与服务器断开连接

    2. send_timeout

      该指令用于设置nginx服务器响应客户端的超时时间,这个超时时间仅针对客户端与服务器间建立连接后,某次活动的时间;如果这个时间后客户端没有任何活动,nginx服务器将会关闭连接

      send_timeout 10s;
      该设置表示nginx服务器与客户端建立连接后,某次会话中服务器等待客户端响应时间为10s,超过该时间,服务器则关闭连接

    3. client_header_buffer_size 4k;

      该指令用于设置nginx服务器允许的客户端请求头部的缓冲区大小,默认为1KB,此指令可根据系统分布大小来设置

      查看系统分页大小的方法:

      [root@localhost ~]# getconf PAGESIZE
      4096

    3、事件驱动模型相关的配置参数

    events {
    use epoll;
    worker_connections 65535;
    }

    1. use epoll

      设置nginx服务器默认使用的事件驱动模型

    2. worker_connections 65535;

      设置每个工作进程允许的最大连接数
      该数字的值的设置如果超过系统允许每个进程打开的文件句柄数,还需要调整该数字

      查看文件句柄:

      [root@localhost ~]# cat /proc/sys/fs/file-max
      186531
      [root@localhost ~]#

    Nginx服务器的压缩功能

    在nginx配置文件中可使用gzip压缩功能,对响应数据进行压缩,以节省网络带宽
    压缩相关的指令可用于http, server及location段中

    nginx服务器通过ngx_http_gzip_module, ngx_http_gzip_static_module和ngx_http_gunzip_module模块对这些指令进行处理

    由ngx_http_gzip_module模块处理的指令

    gzip  on;
    gzip_buffers 32 4k;
    gzip_comp_level 1;
    gzip_disable "MSIE [4-6].";
    gzip_min_length 1024;
    gzip_types text/plain application/x-javascript text/css text/html application/xml;
    gzip_vary on;
    

    参数说明:

    1. gzip on;

      该指令表示开启gzip压缩功能

    2. gzip_buffers 32 4k;

      该指定用于设置gzip压缩文件时使用缓存空间大小
      32表示向系统申请32个缓存空间的个数,4k表示每个缓存空间的大小

    3. gzip_comp_level

      用于设置压缩比,取值为1--9,1表示压缩比最低

    4. gzip_disable

      针对不同客户端浏览器类型不同,可选择开启或关闭gzip压缩功能

      该指令用于设置对哪些浏览器的访问禁用压缩功能

    5. gzip_min_length 1024;

      压缩对大数据的处理比较有效果,但是对于一些小文件,可能会出现越压缩文件越大的情况(压缩算法导致)
      该指令用于设置响应页面的字节数,超过1024字节再压缩

    6. gzip_types

      该指令用于设置针对哪些MIME类型进行压缩, 可针对mimes.type文件设置

    7. gzip_vary on

      该指令用于设置HTTP响应头部中是否带有头部信息,说明压缩

      on,在头部中会看到如下信息: Vary:Accept-Encoding

    由ngx_http_gzip_static_module模块处理的指令

    ngx_http_gzip_static_module模块主要负责搜索和发送经过gzip功能预压缩的数据。这些数据以.gz作为后缀名存储在服务器上。如果客户端请求的数据之前被压缩过,并且客户端浏览器支持gzip压缩,就直接返回压缩后的数据。
    

    参数说明:

    1. gzip_static on|off|always;

      on 开启该模块的功能
      off 关闭该模块的功能
      always 一直发送gzip压缩文件,而不检查客户端浏览器是否支持gzip压缩

    ngx_http_gunzip_module模块

    nginx服务器对数据支持压缩,对于客户端浏览器来说,必须有能力解压。如果客户端浏览器不支持压缩功能,就需要nginx服务器在向其发送数据前先将该数据解析
    
    ngx_http_gunzip_module模块便是用来针对不支持gzip压缩数据处理的客户端浏览器,对压缩数据进行解压处理的。
    

    参数说明:

    1. gunzip_statice on|off;

      on 开启该模块的功能
      off 关闭该模块的功能

    Nginx服务器反向代理

    1、proxy_pass指令

    用于指定后端服务器的主机名或者IP地址 
    
    	location / {
    		proxy_pass http://192.168.87.102;
    	}
    
    	
        location /server {
            proxy_pass http://192.168.87.102/;
        }
    	
    	
    	location /server {
            proxy_pass http://192.168.87.102;
        }
    	
    
        location /server {
            proxy_pass http://192.168.87.102/doc;
        }
    
    	locaiton /server/ {
    		proxy_pass http://192.168.87.102/doc/;
    	}
    

    2、proxy_hide_header

    该指令用于设置Nginx服务器在发送响应时,隐藏一些头域信息
    
    该指令可用在http, server, location块
    
    proxy_pass_header <field>
    
    默认情况下,nginx服务器在发送响应数据时,报文头中不包含“Date", "Server", "X-Accel"等来自后端服务器的信息
    该指令可以设置这些头域信息以被发送
    
    proxy_pass_request_headers {on|off}
    
    该指令用于配置是否将客户端请求的请求体发送给代理服务器
    默认为on
    

    3、proxy_set_header

    该指令可以更改nginx服务器接收到的客户端请求的请求头信息,然后将新的请求头发送给被代理服务器
    

    4、proxy_set_body

    该指令可以更改nginx服务器接收到的客户端请求的请求体信息,然后将新的请求体发送到被代理的服务器 
    

    5、proxy_bind

    在配置了多个基于名称或者基于IP的虚拟主机时,如果我们希望代理连接由指定的主机处理,就可以使用该指令进行配置 
    

    6、proxy_connect_timeout

    该指令配置nginx服务器与后端服务器尝试建立连接的超时时间,默认为60s
    
    proxy_connect_timeout <time>
    

    7、proxy_read_timeout

    该指令配置nginx服务器向后端被代理服务器发出READ请求后,等待响应的超时时间,默认为60s
    

    8、proxy_send_timeout

    该指定配置nginx服务器向后端服务器发出write请求后,等待响应的超时时间,默认为60s
    

    9、proxy_http_version指令

    该指令用于设置用于Ngnix服务器提供代理服务的HTTP协议及版本,默认为1.0版本 
    

    10、proxy_method

    该指令用于设置nginx服务器向后端代理服务器发送请求时使用的方法。一般为POST或者GET,
    

    11、proxy_ignore_client_abort {on|off}

    该指令用于设置在客户端中断网络时,nginx服务器是否中断对后端服务器的请求
    默认为off,当客户端中断网络请求时,nginx服务器中断对后端服务器的请求 
    

    12、proxy_ignore_headers

    该指令用于设置一些HTTP响应头的头域,nginx服务器接收到后端服务器的响应数据后,不会处理被设置的头域  
    

    13、proxy_redirect

    该指令用于修改后端服务器返回的响应头中的Location头域的refresh头域,与proxy_pass指令配合使用
    
    可以把代理服务器返回的地址信息更改为需要的地址信息 
    
    proxy_redirect <redirect> <replacement>
    	
    	假设后端服务器返回的响应头中的Location是"http://localhost:8081/proxy"
    	
    	proxy_redirect http://localhost:8081/proxy http://myweb/fronted
    	
    	nginx服务器会将location中的信息修改为如下:
    	
    	http://myweb/fronted 
    
    
    proxy_redirect <default>
    
    	default表示的意思是使用location块中的uri变量作为replacement,并使用Proxy_pass变量作为redirect
    	
    	location /server/ {
    		http://proxyserver/src/;
    		proxy_redirect default;
    	}
    	
    	nginx服务器会将location头域的信息修改为http://server 
    	
    	
    proxy_redirect <off>
    
    	off表示当前作用域下所有proxy_redirect指令无效
    

    14、proxy_intercept_errors {on|off}

    该指令设置一个状态是开启还是关闭。
    在开启该状态时,如果被代理的服务器返回的HTTP 400或者大于400状态码,则Nginx服务器使用自己定义的错误页
    如果关闭该状态,Nginx服务器直接将被代理服务器返回的HTTP状态返回客户端
    

    15、proxy_headers_hash_max_size

    该指令用于配置存放HTTP报文头的hash表的容量,默认为512个字符 
    nginx服务器为了能够快速检索HTTP报文头中的各项信息,使用hash表来存储这些信息。nginx服务器在申请存放HTTP报文头的空间时,通常以固定大小 为单位申请,该大小由proxy_headers_hash_bucket_size指令配置 
    

    16、proxy_headers_hash_bucket_size

    该指令用于配置nginx服务器申请存放HTTP报文头的hash表的容量的单位大小;默认为64个字符
    

    17、proxy_next_upstream ...

    该指令指定在发生哪些异常情况下,将请求顺序交由下一个upstream组内的服务器处理
    
    status:
    	error:在建立连接、向后端服务器发送请求或者读取响应头时发生连接错误 
    	timeout:在建立连接、向后端服务器发送请求或者读取响应头时发生连接超时
    	invalid_header:后端服务器返回的响应头为空或者无效
    	http_500 | http_502 | http_503 | http_504 | http_404
    	off:无法将请求发送给后端服务器
    

    18、proxy_ssl_session_reuse { on | off }

    该指令用于配置是否使用基于SSL的协议连接后端服务器 
    默认为开启状态;
    如果在错误日志中发现"SSL3_GET_FINISHED: digest check failed"的情况下,可以将该指令配置为关闭状态
    

    proxy buffer的配置

    工作原理:

    proxy buffer启用后,nginx服务器会异步地将被代理服务器的响应数据传递给客户端

    Nginx服务器首先尽可能地从被代理服务器那里接收响应的数据,放置在proxy buffer中. 如果在接收过程中,发现buffer中没有足够大的空间来接收一次响应的数据,nginx服务器会将部分接收到的数据临时存放在磁盘的临时文件中。一次响应数据被接收完成或者buffer装满后,nginx服务器开始向客户端传送数据。

    每个buffer装满后,在向客户端传送数据的过程中,它都处于BUSY状态,期间对它进行的其他操作都会失败

    参数说明:

    1. proxy_buffering {on|off}

      该指令用于配置是否启用或者关闭proxy buffer, 默认为开启状态

    2. proxy_buffer

      该指令用于配置接收一次后端服务器的响应数据的proxy buffer的个数和每个buffer的大小

      每个buffer的大小一般设置为内存页的大小

      proxy_buffers 8 4k;

    3. proxy_buffer_size

      该指令用于配置从后端服务器获取的第一部分响应数据的大小 ,该数据中一般包含HTTP响应头

      默认设置为4k或者8k

    4. proxy_busy_buffers_size

      该指令用于设置同时处于BUSY状态的proxy buffer总大小

      默认设置为8k或者16k

    5. proxy_temp_path [ level1 level2 level3 ]

      该指令用于配置磁盘上的一个文件路径,该文件用于临时存放代理服务器的接收的响应数据

    6. proxy_max_temp_file_size

      该指令用于配置所有临时文件的总大小 ,这样避免响应数据过大造成磁盘空间不足

      默认为1024MB

    7. proxy_temp_file_write_size

      该指令用于配置同时写入临时文件的数据量的总大小, 合理的设置该值可避免磁盘IO过重导致系统性能下降

      根据平台不同,一般设置为内存页的大小

    proxy cache的配置

    参数说明:

    1. proxy_cache | off;

      该指令用于配置一块公用的内存区域的名称,该区域可以存放缓存的索引数据

      默认的设置为off

    2. proxy_cache_bypass ...

      该指令用于配置nginx服务器向客户端发送响应数据时, 不从缓存中获取数据的条件

      这些条件会使用nginx的内置变量,例如:

      proxy_cache_bypass $cookie_nocache $arg_nocache $arg_comment $http_authorization;

    3. proxy_cache_key

      该指令用于设置nginx服务器在内存中为缓存数据建立索引时使用的关键字

      proxy_cache_key $shceme$proxy_host$uri$is_args$args;

    4. proxy_cache_lock {on|off}

      该指令用于设置是否开启缓存的锁功能;默认为关闭状态
      在缓存中,某些数据项可以同被多个请求返回的数据使用。开启该功能后,nginx服务器同时只能有一个请求填充缓存的某一个数据项,其他请求如果也想填充该数据项,必须等待该数据项的锁被释放

    5. proxy_cache_lock_timeout

      该指令用于设置缓存的锁功能开启后的超时时间,默认为5s

    6. proxy_cache_min_uses

      该指令用于设置客户端请求发送的次数,当客户端向后端服务器发送相同请求的次数超时该数字后,nginx服务器才会对响应数据进行缓存
      默认值为1

    7. proxy_cache_path [levels=] keys_zone=: [max_size=] [inactive=

      该指令用于设置nginx服务器存储缓存数据的路径及缓存索引相关的内容

      path,设置缓存数据存放的根路径
      levels= 用于设置相对于path路径来说,以几级目录的方式存放缓存数据
      keys_zone=: 设置存放缓存索引的内存区域的名称和大小
      max_size= 设置硬盘中缓存数据的大小限制;当缓存数据超过该容量时,会使用最近最少被访问的策略删除相应的缓存数据

      inactive=

      loader_files= 设置缓存索引重建进程每次加载的数据元素的数量上限,默认为100
      在重建缓存索引的过程中,进程通过一系列的递归遍历读取硬盘上的缓存数据目录及缓存数据文件 ,对每个数据文件中的缓存数据在内存中建立对应的索引,每建立一个索引为加载一个数据元素

      loader_sleep=

      loader_threshold=

      proxy_cache_path /nginx/cache/a levels=1 keys_zone=a:10m;
      proxy_cache_path /nginx/cache/b levels=2:2 keys_zone=b:100m;
      proxy_cache_path /nginx/cache/c levels=1:1:2 keys_zone=c:100m;

    8. proxy_cache_use_stale

      如果nginx在访问后端服务器的过程中出现不能访问的情况,nginx可以使用历史缓存来响应客户端
      该指令用于配置一些状态,设置当出现哪种状态时,以缓存数据响应客户端

      默认值为off

      proxy_cache_use_stale error | timeout | invalid_header | updating | http_500 | http_502 | http_503 | http_504 | http_404 | off;

    9. proxy_cache_valid [code1 code2]

      该指令可针对不同的响应状态码设置不同的缓存时间

      proxy_cache_valid 200 302 10m;
      proxy_cache_valid 301 1h;
      proxy_cache_valid any 1m;

    10. proxy_no_cache ...

      该指令用于设置在什么情况下不使用cache功能

      string可以是一个或者多个变量,当string的值不为空或者不为0时,不启用cache功能

    提供缓存的另外一种机制:proxy_store

    proxy_store机制

    它不提供缓存过期更新、内存索引建立等功能,不占用内存空间,对静态数据的效果比较好 
    
    proxy_store机制多用在后端服务器发生错误的情况下,用来缓存后端服务器的响应数据
    

    参数说明:

    1. proxy_store { on | off | }

      on 开启该功能,缓存文件会保存到alias指令或root指令设置本地路径下
      默认为off

      string 自定义缓存文件的存放路径

    2. proxy_store_access : ....

      该指令用于设置用户或者用户组对proxy store缓存的数据的访问权限

      users:可以是user, group, all
      permission:设置权限

    location写法:

    location [=||*|^~] URI地址 {
    ....
    ....
    }

    = 精确匹配URI地址

    location /bbs {
    ...
    ...
    }

    location = /bbs {
    ...
    ...
    }

    ~ 使用正则表达式匹配URI地址, 区分大小写

    location ~ /image/ {....}				
    

    ~* 使用正则表达式匹配URI地址, 不区分大小写

    location ~* /image {....}				http://10.1.2.1/IMAGES/
    
    location ~* .jpg$ {.....}
    
    location ~* .(jpg|gif|png|jpeg)$ {......}
    

    ^~ 不使用正则表达式表示URI地址

    location ^~ /image {.....}
    location /image {.....}
    

    优先级:

    =   --->   ^~ ----> ~ ------> ~* ------> /
    

    Nginx反向代理

    server {
    listen 80;
    server_name www.bj.com;
    location / {
    后端服务器;
    }
    }

    后端服务器:
    proxy_pass

    示例1:客户端通过http://192.168.122.101访问nginx时,以本地页面响应;通过http://192.168.122.101/forum访问时,代理到后端服务器

    	location / {
    		root   html;
            index  index.html index.htm;
    	}
    
        location /forum {
            proxy_pass http://192.168.122.102/;
        }
    

    注意:

    1) 如果location后写自定义的URI地址,在做反向代理时,必须要指定URI地址
    

    示例2:

    客户端http://192.168.122.101/discuz访问时,代理到后端服务器192.168.122.102的bbs目录下

        location /discuz {
            proxy_pass http://192.168.122.102/bbs;
        }
    

    特殊情况:

    如果在定义location时,加入了~ ~* 这样的模式匹配字符,proxy_pass在写时,只能写到服务器地址

        location ~ /discuz {
            proxy_pass http://192.168.122.102;
        }
    	
    注意: 后端服务器要存在相同名称的目录
    

    示例4: 配置nginx不再响应客户端访问请求,所有访问请求全部代理到后端服务器

        location / {
            proxy_pass http://192.168.122.102;
        }
    

    此时,对于后端服务器来说,access_log中记录的日志,客户端IP是nginx的IP

    192.168.122.101 - - [05/Jan/2017:21:39:22 +0800] "GET / HTTP/1.0" 403 4954 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)"

    配置proxy_set_header,实现后端服务器记录真实的客户端IP

        location / {
            proxy_pass http://192.168.122.102;
            proxy_set_header x-real-ip $remote_addr;
        }
    

    proxy_set_header x-real-ip $remote_addr;

    代理在httpd请求报文中加入x-real-ip段的内容,该内容是变量$remote_addr的值,即真实客户端的IP
    

    编辑后端服务器配置文件/etc/httpd/conf/httpd.conf,修改combined日志格式,将客户端地址%h换成%{x-real-ip}i,表示记录HTTP请求报文中X-Real-IP的内容

    LogFormat "%{x-real-ip}i %l %u %t "%r" %>s %b "%{Referer}i" "%{User-Agent}i"" combined

    刷新浏览器,再次查看后端服务器access_log,日志中记录的是真实客户端的IP地址192.168.122.1

    192.168.122.1 - - [05/Jan/2017:21:48:50 +0800] "GET /icons/poweredby.png HTTP/1.0" 304 - "http://192.168.122.101" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)"

    Nginx负载均衡

    算法:
    	roundrobin, rr, 轮询, 默认;     支持为后端服务器设置权重(weight)
    	ip_hash		相同IP地址的客户端请求,  nginx会代理同一台后端服务器 
    

    实现负载均衡:

    upstream <组名称> {

    [调度算法];
    server IP:port [weight=<number>] [max_fails=<number>] [fail_timeout=<number>];
    server IP:port [weight=<number>] [max_fails=<number>] [fail_timeout=<number>];
    server IP:port [weight=<number>] [max_fails=<number>] [fail_timeout=<number>] [backup];
    

    }

    weight=<number>					设置服务器的权重值 
    max_fails=<number>				检测失败的次数
    fail_timeout=<number>			检测的周期,单位为秒
    backup 							设置为备份服务器
    

    upstream的定义必须在server{..}外定义

    location / {
    proxy_pass http://<组名称>
    }

    示例1: 实现负载均衡

    upstream websrv {
        server 192.168.122.102 weight=1 max_fails=2 fail_timeout=2;
        server 192.168.122.103 weight=1 max_fails=2 fail_timeout=2;
    }
    
    location / {
        proxy_pass http://websrv;
        proxy_set_header x-real-ip $remote_addr;
    }
    

    提供sorry页面:

    upstream websrv {
        server 192.168.122.102 weight=1 max_fails=2 fail_timeout=2;
        server 192.168.122.103 weight=1 max_fails=2 fail_timeout=2;
        server 127.0.0.1:8080 backup;
    }
    

    虚拟主机配置:

    server {
        listen       127.0.0.1:8080;
        server_name  localhost;
    
        location / {
            root   /sorry;
            index  index.html index.htm;
        }
    }
    

    Nginx反向代理缓存

    缓存组成的两部分: 
    	共享内存: 存储键和缓存对象元数据
    	磁盘空间:存储数据
    

    定义缓存空间

    proxy_cache_path: 不能定义在server{}中
    

    proxy_cache_path /nginx/cache/first levels=2:1:2 keys_zone=first:20m max_size=1G

    levels=
    定义缓存目录子目录的级别,及每个子目录的名称字符个数; 最多只能有3级子目录
    levels=1:2:2,3级子目录,第1级目录字符个数为1,第2级目录字符个数为2,第3级目录字符个数为2,字符个数最多只能有2个
    keys_zone=name:size
    定义存储键的区域(定义共享内存的名称)
    max_size=1G
    指定/nginx/cache/first中的1G空间用于存储缓存数据

    Nginx缓存配置:

    定义缓存存放路径为/web/cache, 最多使用1G空间; 并定义键值区域名称为first,大小为20m

    proxy_cache_path /web/cache levels=1:2 keys_zone=first:20m max_size=1g;

    在location中开启缓存功能,指定使用键值名称为first的缓存
    在httpd响应报文中添加额外项X-cache,用于查看缓存是否命中

    add_header x-cache "$upstream_cache_status by $server_addr";

    $upstream_cache_status: 用于记录缓存是否命中的状态  (HIT, MISS, EXPIRED)
    
    $server_addr		服务器地址
    

    location / {
    proxy_pass http://webserver/;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_cache first; >>>>使用内存first中保存的缓存
    proxy_cache_valid 200 1m;
    }

    proxy_cache_valid 200 1m;

    表示为状态码为200的数据缓存1分钟 
    

    查看缓存是否命中,在浏览器中按F12打开开发者模式,查看HTTP响应报文,可以看到X-cache:HIT by 10.1.2.1信息,表示缓存命中

    URL重写 ----- rewrite

    1、if指令

    if (条件) {......}

    {...}	代表条件为真时的nginx操作 	
    

    condition条件的写法:

    1. 变量名

      如果变量的值为空,或者为以"0"开头的任意字符串,条件为假,其他则为真

      if ($slow) {....}

    2. 使用"="或者"!="比较变量的值

      if ($request_method = POST) {.....}

    3. 使用正则表达式与变量的值进行匹配

      变量名与正则表达式间使用~, ~, !~, !~进行连接

      在正则表达式中使用()可以对字符进行分组,在{}中可以用$1....$9引用分组

      正则表达式写时不需要加双引号,但是如果正则表达式中含有}和;字符,则必须要使用双引号

      if ($http_user_agent ~* MSIE) {.....}

    4. 判断请求的文件是否存在

      if ( -f $request_filename) {.....}

      if (!-f $request_filename) {.....}

    5. 判断请求的目录是否存在 (-d, !-d)

    6. 判断请求的目录或文件是否存在 (-e, !-e)

    7. 判断请求的文件是否可执行 (-x, !-x)

    WebDAV(Web-based Distributed Authoring and Versioning)
    一种基于HTTP 1.1协议的通信协议,它扩展了HTTP 1.1,在GET,POST,HEAD等几个HTTP标准方法以外添加了一些新的方法,使应用程序可直接对Web Server直接读写,并支持写文件锁定(Locking)及解锁(Unlock),还可以支持文件的版本控制。

    rpm httpd默认支持DAV功能

    通过此协议可以支持在Web Server上传文件

    Nginx读写分离

    前端:Nginx服务器  192.168.122.101 
    后端:Apache服务器 192.168.122.102   192.168.122.103(可在此服务器上传文件)
    

    确保192.168.122.103服务器开启DAV功能

    确保Apache配置文件加载了DAV相关模块

    vim /etc/httpd/conf/httpd.conf

    LoadModule dav_module modules/mod_dav.so
    LoadModule dav_fs_module modules/mod_dav_fs.so
    

    在相应网页根目录授权段中开启DAV
    <Directoy "/var/www/html">
    ....
    dav on

    确保运行httpd进程的apache用户对网页根目录拥有写入权限

    setfacl -m u:apache:rwx /var/www/html/

    测试在客户端可以向192.168.122.103服务器上传文件

    curl -T /etc/issue http://192.168.122.103

    前端Nginx服务器配置读写分离,读操作代理到192.168.122.102上,写操作代理到192.168.122.103上;

    location / {
    proxy_pass http://192.168.122.102;
    if ($request_method = PUT) {
    proxy_pass http://192.168.122.103;
    }
    }

    测试nginx读写分离操作是否成功

    测试读操作:

    [root@www ~]# curl http://192.168.122.101

    web-1 ON Apache

    测试写操作:

    [root@www ~]# curl -T /etc/fstab http://192.168.122.101

    201 Created

    Created

    Resource /fstab has been created.


    Apache/2.2.15 (CentOS) Server at 192.168.122.103 Port 80

    后端两台服务器通过rsync+inotify进行数据同步,保证上传的数据可以同步到后端所有服务器上

    2、rewrite指令 --------------- URL重写

    该指令通过使用正则表达式的使用来改变URI。
    可以同时存在一条或者多条,按顺序依次对URL进行匹配和处理 
    
    该指令可用于 server, location, if 中 
    
    语法结构: 
    
    	rewrite <正则表达式> <REPLACEMENT> [FLAG]
    	
    		REGEX 	用于匹配URI的正则表达式 
    		
    		注意: 
    			1) rewrite接收到的URL地址不包括主机名称部分 
    			2) 不包括URL地址中的请求指令 
    			
    				https://reg.jd.com/reg/person?ReturnUrl=https%3A//sale.jd.com/act/r1z8LpvTcxkDbge.html
    
    	REPLACEMENT		
    		匹配成功后用于替换URI中被截取内容的字符串。
    		默认情况下,如果字符串是以http://或者https://开头,则不会继续向下对URI进行其他处理,而直接将重写后的URI返回给客户端 			
    		
    		支持变量的使用 
    		
    	FLAG 
    	
    		1) last 
    			终止继续在本location块中处理接收到的URI,并将此处重写的URI作为一个新的URI,使用下一个location块进行处理 
    			
    			location / {
    				rewrite ^(/myweb/.*)/media/(.*)..*$	$1/mp3/$2.mp3  last; 	
    				rewrite ^(/myweb/.*)/audio/(.*)..*$	$1/mp3/$2.ra   last;
    			}
    			
    		2) break 
    			将此处重写的URI作为一个新的URI,在本块中继续进行处理。该标志将重写后的地址在当前的location块中执行,不会将新的URI转向到其他location块
    			
    			location /web/ {
    				rewrite ^(/myweb/.*)/media/(.*)..*$	$1/mp3/$2.mp3 break; 
    				rewrite ^(/myweb/.*)/audio/(.*)..*$	$1/mp3/$2.ra break;
    			}
    		
    		3) redirect 
    		
    			将重写后的URI返回给客户端,状态代码为302,指明是临时重定向,主要用在replacement不是以http://或者https://开头的情况下
    		
    		4) permanent 
    		
    			将重写后的URI返回给客户端,状态代码为301,指明是永久重写向
    

    示例1:

    location / {
        root   /web;
        index  index.html index.htm;
        rewrite ^/mp3 http://192.168.122.101/audio;
    }
    

    示例2:

        location / {
            root   /web;
            index  index.html index.htm;
            rewrite ^/mp3/(.*.html)$ http://192.168.122.101/audio/$1;
        }
    
    	
        location / {
            root   /web;
            index  index.html index.htm;
            rewrite ^/mp3/(.*.html)$ $scheme://$host/audio/$1;
        }
    

    示例3: 域名跳转

        location / {
            root   /web;
            index  index.html index.htm;
            rewrite ^/ http://www.jd.com;
        }
    

    示例04:防盗链

    server {
        listen 80;
        server_name www.d.org;
        location / {
            root /abc;
            index index.html;
            valid_referers none blocked www.d.org;
            if ($invalid_referer) {
                return 404;
            }
        }
    }
    

    [root@web01 ~]# cat /var/www/html/index.html

    <a href="http://www.d.org/1.html"> httpd hahahaha </a>
    

    Nginx变量

    1. $args

      存放URL中的请求指令

      https://reg.jd.com/reg/person?ReturnUrl=https%3A//sale.jd.com/act/r1z8LpvTcxkDbge.html

       ReturnUrl=https%3A//sale.jd.com/act/r1z8LpvTcxkDbge.html 
      
    2. $content_length

      存放请求报文中content_length字段内容

    3. $content_type

      存放请求报文中content_type字段内容

    4. $document_root

      存放针对当前请求的根路径

    5. $document_uri

      存放请求报文中的当前URI,并且不包括请求指令

      https://reg.jd.com/reg/person?ReturnUrl=https%3A//sale.jd.com/act/r1z8LpvTcxkDbge.html

       /reg/person		
      
    6. $host

      存放请求报文中的主机部分

      https://reg.jd.com/reg/person?ReturnUrl=https%3A//sale.jd.com/act/r1z8LpvTcxkDbge.html

       reg.jd.com		
      
    7. $http_user_agent

      存放客户端代理信息(浏览器)

    8. $http_cookie

      存放客户端的cookie信息

    9. $limit_rate

      存放nginx服务器对网络连接速率的限制,也就是ngnix配置文件中limit_rate指令的值

    10. $remote_addr

      存放客户端地址

    11. $remote_port

      存放客户端端口

    12. $remote_user

      存放客户端的用户名

    13. $request_body_file

      存放发给后端服务器的本地文件资源名称

    14. $request_method

      存放客户端请求资源的方法, GET, POST, PUT, DELETE, HEAD

    15. $request_filename

      存放当前请求的资源文件的路径名

    16. $request_uri

      存放当前请求的URI,并且带有请求指令

      https://reg.jd.com/reg/person?ReturnUrl=https%3A//sale.jd.com/act/r1z8LpvTcxkDbge.html

      /reg/person?ReturnUrl=https%3A//sale.jd.com/act/r1z8LpvTcxkDbge.html
      
    17. $query_string

      与变量$args含义相同

    18. $scheme

      存放客户端请求使用的协议,如http, https

    19. $server_protocol

      存放客户端请求协议的版本 HTTP/1.0 HTTP/1.1

    20. $server_addr

      存放服务器地址

    21. $server_name

      存放了客户端请求到达的服务器的名称

    22. $server_port

      存放了客户端请求到达的服务器的端口号

    23. $uri

      与变量$document_uri含义相同

    有志者,事竟成,破釜沉舟,百二秦关终属楚; 苦心人,天不负,卧薪尝胆,三千越甲可吞吴。 想到与得到中间还有两个字——做到。
  • 相关阅读:
    并查集 示例 : poj 1703 [Find them, Catch them 帮派之争]
    《Python 第五章》条件,循环和其他语句
    《Python 第一章》基础知识
    heapSort 堆排序 / 二叉堆
    并查集 hdu 1856 示例
    KMP / hdu 1711 [找到匹配的位置并返回]
    《Python 第四章》字典
    EnumChildWindows的使用
    C#查找指定窗口的子窗口的句柄
    C#里字符串取左边N个字符,右边N个字符,从中间取N个字符的函数
  • 原文地址:https://www.cnblogs.com/huoxc/p/12844941.html
Copyright © 2020-2023  润新知