Nginx

基础知识点

特点

1 Nginx是一个很牛的高性能Web和反向代理服务器,它具又很多非常优越的特性
2 在高连接并发的情况下,Nginx是Apache服务器不错的替代品,Nginx是做虚拟主机不错的软件平台之一
3 能够支持50000个并发连接数的响应,Nginx选择了epoll and kqueue作为开发模型

Nginx作为负载均衡服务器

既可以在内部直接支持和PHP程序对外进行服务,也可以支持作为HTTP代理服务器对外进行服务

Nginx采用C进行编写,不论是系统资源开销还是CPU使用效率都比Perlbal要好很多

优点

1. 高并发连接

    官方测试能够支撑5万并发连接,在实际生产环境中跑到2~3万并发连接数

2. 内存消耗少

    在3万并发连接下,开启的10个Nginx进程才消耗150M内存

3. 配置文件简单

    风格跟程序一样通俗易懂

4. 成本低廉

    Nginx为开源软件,可以免费使用

5. 支持Rewrite重写规则

    能够根据域名、URL的不同,将HTTP请求分发到不同的后端服务器群组

6. 内置的健康检查功能

    如果Nginx Proxy后端的某Web服务器宕机了,不会影响到前端访问

7. 节省带宽

    支持GZIP压缩,可以添加浏览器本地缓存的Header头

8. 稳定性高

    用于反向代理,宕机的概率微乎其微

9. 模块化设计

    模块可以动态编译

10. 外围支持好

    文档全、二次开发和模块较多

11. 支持热部署

    可以不停机重载配置文件

12. 支持事件驱动、AsynI/O、mmap等性能优化

Nginx常用用法

1. 使用Nginx结合FastCGI运行PHP、JSP、Perl等程序

    静态页面Nginx直接发送给客户端,动态页面通过FastCGI交给其他Web服务后端处理

    客户发送请求先到Nginx,Nginx将请求发给PHP,PHP处理完请求将结果发送给Nginx,Nginx最后再将结果发送给客户端,四次Nginx交互

2. 使用Nginx作反向代理、负载均衡、规则过滤

3. 使用Nginx运行静态页面HTML页、图片

4. Nginx与他新技术的结合应用

Nginx的模块和工作原理

组成

Nginx由内核和模块组成,其中,内核的设计非常微小和简洁,完成的工作也非常简单

仅仅通过查找配置文件将客户端请求映射到一个location block(location是Nginx配置中的一个指令,用于URL匹配)

而在这个location中所配置的每个指令将会启动不同的模块去完成相应的工作

Nginx模块

核心模块

    HTTP模块

    EVENT模块

    MAIL模块

    ...

基础模块

    HTTP Access模块

    HTTP FastCGI模块

    HTTP Proxy模块

    HTTP Rewrite模块

    ...

第三方模块

    HTTP Upstream模块

    Requests Hash模块

    Notice模块

    HTTP Access Key模块

    ...

Nginx模块分类

1. Handlers处理器模块

    此类模块直接处理请求,并进行输出内容和修改header信息等操作。handlers处理器模块一般只能有一个

2. Filters过滤器模块

    此类模块主要是对其它处理器模块输出的内容进行修改操作,最后由Nginx输出

3. Proxies代理类模块

    就是Nginx的HTTP Upstream之类的模块,这些模块主要与后端一些服务比如fastcgi等操作交互,实现服务代理和负载均衡等功能

官网文档 http://www.nginx.org

下载安装

下载Nginx源码包

1 wget http://nginx.org/download/nginx-1.12.2.tar.gz

解压

1 tar -zxvf nginx-1.12.2.tar.gz

查看版本变更修改

1 cd nginx-1.12.2/
2 vim CHANGES

查看源码安装定制参数

1 ./configure --help

重要依赖包安装

# 支持正则表达式包下载

yum install pcre-devel

创建用户

1 useradd nginx -s /sbin/nologin

创建日志目录

1 mkdir -p /data/logs/nginx

编译安装(使用部分模块)

1 ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --http-log-path=/data/logs/nginx/access.log --error-log-path=/data/logs/nginx/error.log --with-http_ssl_module --with-http_realip_module --with-http_flv_module --with-http_image_filter_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_stub_status_module
2 make
3 make install 

自添加第三发模块

wget下载第三发模块,这里以echo输出模块为例

    wget https://github.com/openresty/echo-nginx-module/archive/v0.61.tar.gz

编译时追加参数

    --add-module=/usr/local/src/echo-nginx-module-0.61

配置文件解析

常用配置文件

nginx.conf 应用程序的基本配置文件

mime.types MIME类型关联的扩展文件

fastcgi.conf 与fastcgi相关的文件

proxy.conf 与proxy相关的文件

sites.conf 配置Nginx提供的网站,包括虚拟主机

配置文件结构

main 

    event

http协议级别

    server服务器级别

        location请求级别

配置文件管理

将管理work的配置从nginx.conf中分离出来,方便管理

    tail -84 nginx.conf > server.conf

在nginx.conf中导入子配置文件

    vim nginx.conf

        include server.conf;

nginx.conf主要控制nginx性能

server.conf主要控制业务相关以及映射关系

nginx.conf部分配置参数

main段

指定运行用户

    user nginx;

指定pid

    pid logs/nginx.pid;

指定工作进程数(一般等于核心数或很核心数-1,减少进程切换)

    worker_processes 4;  

绑定CPU和进程关系,避免抖动,带来的缓存频繁刷新(与工作进程数相关)

    worker_cpu_affinity 0001 0010 0100 1000;

修改worker进程最大打开的文件数

    worker_rlimit_nofile 65535;

修改worker进程的最大连接数

    event{
        worker_connections 20000;
    }

http段

Web页面的工作目录

    root /data/w3 

日志格式配置

    log_format  ...

访问日志相关参数配置(缓冲、缓存、压缩...)

    access_log ...

内存单独开辟数据空间,减少内核空间到用户空间的数据交互

    sendfile on;

http长连接

    keepalive 65;

gzip压缩相关

    gzip            on;

    gzip_min_length 1000;

    gzip_proxied    expired no-cache no-store private auth;

    gzip_types      text/plain application/xml;

    gzip_comp_level 6; #默认是1,最高是9

server段

监听端口

    listen 127.0.0.1:8000 default_server;

虚拟主机名

    server_name www.example.com; 

    server_name *.example.com;

    server_name ~^.example.com$;

location段

location优先级URL

=  ---> "绝对路径" --->  ^~  --->  ~ ---> ~*

精确匹配检查 = 

    location = / {
        root a;
    }

正则表达式模式匹配检查,区分大小写 ~

    location ~ /document/ {
        root b;
    }

正则表达式模式匹配检查,不区分大小写 ~*

    location ~* .php$ {
        fcgipass;
    }

URI前半部分匹配,不支持正则表达式 ^~

    location ^* /document/ {
        root d;
    }
root 工作起始路径

    如果server中定义了root而location中未定义,则默认使用server中定义的

    如果只写目录名(a),则默认以编译时prefix的路径为相对路径,即/usr/local/nginx/a

allow 访问控制(顺序匹配)

    allow 192.168.1.1/32;

deny 访问控制

    deny all;

error_page code [...] [=code] URI | @name

    根据http响应状态码来指明特用的错误页面

    error_page 404 /404_customed.html 

    [=code] 以指定的响应码进行响应,而不是默认的原来的响应,

定制访问日志

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                '$status $body_bytes_sent "$http_referer" '
                '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  logs/access.log  main;

SSL配置

自签名CA

    cd /etc/pki/CA

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

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

    touch serial index.txt

    echo 01 >> serial

CA端NginxSSL文件

    cd /usr/local/nginx/conf

    mkdir ssl

    (umask 077;openssl genrsa -out nginx.key 1024)

    openssl req -new -key nginx.key -out nginx.csr

CA对NginxSSL文件进行签发

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

编辑server.conf文件中https段

    ssl_certificate      /usr/local/nginx/conf/ssl/nginx.crt;
    ssl_certificate_key  /usr/local/nginx/conf/ssl/nginx.key;
View Code

基于用户认证

Auth_basic

    auth_basic "Welcome nuc"

Auth_basic_user_file 

    auth_basic_user_file "/usr/local/nginx/conf/vipuser"

        生成一个密钥串

            htpasswd -bc /usr/local/nginx/conf/vipuser aaa 123456

        vim /usr/local/nginx/conf/vipuser

            aaa:$apr1$ojbCkPri$OObek39XPEpxpoCLvPMne/

        useradd aaa 
View Code

安全状态页面

location /status {
    stub_status on;
}

参数解析

    Active connection 3 当前所有处于打开状态的连接数

    server accepts handled requests 

    100 120 402 

    100个连接 120创建握手 111个请求

    Reading:0 Writing:1 Waiting:2

    Reading:nginx读取到客户端的Header信息数

    Writing:nginx返回给客户端的Header信息数

    Waiting:开启keep-alive的情况下,这个值等于active - ( reading + writing ) Nginx已经处理完成正在等候下一次请求指令的驻留连接
View Code

Rewrite用法

功能:实现URL重写,用户请求重定向

语法:rewrite regex replacement flag;

flag

    last

        如果用户的URL被重写后,后续将不被其它rewrite规则匹配

        而是由User Agent重新对重写后的URL再一次发起请求,并从头开始执行类似的过程

        如果再被匹配则继续

    break

        此rewrite重写完成之后,由User Agent对新的URL重新发起请求

        且不在会被任何rewrite规则检查

    redirect

        以302响应码(临时重定向)返回新的URL

    permament

        以301响应吗(永久重定向)返回新的URL

例子:

    rewrite ^/images/(.*.jpg)$ /imgs/$1 break;
View Code

if使用

语法:if(condition){...}

应用段:server、location

condition

    1. 变量名

        变量值为空串、以零开始则为false

    2. 以变量为操作数构成的表达式

        可以使用=、!=、<、>等操作符

    3. 正则表达式的模式匹配操作

        ~ 区分大小写的模式匹配检查

        ~* 不区分大小写的模式匹配检查

        !~和!~* 以上两种取反

    4. 测试目标为文件

        -f filename

        !-f 

    5. 测试指定路径为目录

        -d

        !-d

    6. 测试文件的存在性

        -e

        !-e

    7. 检查文件是否有执行权限

        -x

        !-x

    例子:判断客户端浏览器是否为IE

        if($http_user_agent ~* MSIE){
            rewrite ^(.*)$ /msie/$1 break;
        }
View Code

防盗链

只要不是example.com域名的引用,皆为不合法引用

location ~* .(jpg|gif|jpeg|png)${
    valid_referer none  blocked www.example.com;
    if($valid_referer){
        rewrite ^/ http://www.example.com/403.html;
    }
}
View Code

网络连接相关配置

1. keepalive_timeout #;

    长连接的超时时长,默认75S

2. keepalive_requests #;

    在一个长连接上所能够允许请求的最大资源数

3. keepalive_disable [msie6|safari|none]

    为指定类型的User Agent禁用长连接

4. tcp_nodelay on|off

    合并小资源请求,将多个小资源合并成一个大资源在响应给客户端,缺点,客户端请求资源周期延长,一般禁用

5. client_header_timeout #;

    读取http请求报文首部的超时延长,如果我们的服务器很繁忙那么就应该延长点时间等待客户端

6. client_body_timeout #;

    读取http请求报文body部分的超时延长,如果我们的服务器很繁忙那么就应该延长点时间等待客户端

7. send_timeout #;

    发送响应报文的超时时长

Work进程作用

1. 响应用户请求

2. 为后端Web服务器做反向代理

3. 从本地缓存加载内容

Cache Loader作用

1. 使用缓存元数据建立内存数据库

2. 检查缓存存储的中的数据对象

3. 加载缓存数据

Cache manager作用

1. 清理过期失效的缓存

Nginx核心(core)模块

反馈给用户获取资源的类型

    # 自定义响应首部

    add_header

        server {
            add_header X-Via $server_addr;
            add_header X-Cache $upstream_cache_status;
            ...
        }
View Code

Nginx反向代理(proxy)模块

官方文档:http://nginx.org/en/docs/http/ngx_http_proxy_module.html

location / {
    proxy_pass       http://localhost:8000;
    proxy_set_header Host      $host;
    proxy_set_header X-Real-IP $remote_addr;
}

例子

    1. 直接映射

        location /monitor {
            proxy_pass       http://192.168.1.254:8080/cmdb;
            proxy_set_header Host      $host;
            proxy_set_header X-Real-IP $remote_addr;
        } 

    2. 正则模式匹配,非URL映射

        location ~* .(jpg|png|gif|css|js)$ {
            proxy_pass       http://192.168.1.1:8000;
            proxy_set_header Host      $host;
            proxy_set_header X-Real-IP $remote_addr;
        }

proxy_ssl_* 

    内网HTTPs

proxy_connect_timeout

    与后端服务器的超时时长

proxy_hide_header

    由代理服务器响应客户端时,隐藏的首部

proxy_buffer*

    应用服务器发送响应信息到代理服务器需要缓冲的信息大小

proxy_cache_bypass string

    设置在何种情况下nginx将不从cache取数据:$cookie_nocache $arg_nocache $http_authorization

代理缓存

    重要

        定义缓存路径

            proxy_cache_path path [levels=levels] [use_temp_path=on|off] keys_zone=name:size [inactive=time] [max_size=size]
            
                [manager_files=number] [manager_sleep=time] [manager_threshold=time] [loader_files=number] [loader_sleep=time]
                
                [loader_threshold=time] [purger=on|off] [purger_files=number] [purger_sleep=time] [purger_threshold=time];

        使用缓存区域

            proxy_cache zone | off;

        缓存请求方法定义

            proxy_cache_methods GET | HEAD | POST ...;

        资源最少请求几次就加入缓存

            # Default:    proxy_cache_min_uses 1;

            proxy_cache_min_uses number;

        修剪缓存请求

            # 后端服务器中加入了新的资源,需要清除旧的资源

            proxy_cache_path /data/nginx/cache keys_zone=cache_zone:10m;

            map $request_method $purge_method {
                PURGE   1;
                default 0;
            }

            server {
                ...
                location / {
                    proxy_pass http://backend;
                    proxy_cache cache_zone;
                    proxy_cache_key $uri;
                    proxy_cache_purge $purge_method;
                }
            }

        重新验证过期缓存

            proxy_cache_revalidate on | off;

        如何处理被拿来响应的过期缓存

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

        自定义缓存时间

                proxy_cache_valid [code ...] time;

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

    实例:

        http{
            proxy_cache_path /data/cache/nginx/ levels=1:1 keys_zone=my_cache:32m;  
        }
        
        makdir -pv /data/cache/nginx

        chown nginx:nginx 

        location /monitor {
            proxy_cache mycache;
            proxy_cache_valid 200 1d;
            proxy_cache_valid 301 302 10m;
            proxy_cache_valid any 1m;
            proxy_cache_use_stale error timeout http_500 http_502 http_503 http_504;
            proxy_pass       http://192.168.1.254:8080/cmdb;
            proxy_set_header Host      $host;
            proxy_set_header X-Real-IP $remote_addr;
        }
View Code

Nginx负载均衡(upstream)模块

官方文档:http://nginx.org/en/docs/http/ngx_http_upstream_module.html

# 可定义服务器组

    proxy_pass, fastcgi_pass, uwsgi_pass 

# 只能定义在http中

upstream backend {
    server backend1.example.com       weight=5;
    server backend2.example.com:8080;
    server unix:/tmp/backend3;

    server backup1.example.com:8080   backup;
    server backup2.example.com:8080   backup;
}

server {
    location / {
        proxy_pass http://backend;
    }
}

调度算法

    默认加权轮询

    sh算法

        upstream backend {
            ip_hash;
        }

        sticky

            基于cookie的方式

                sticky cookie srv_id expires=1h domain=.example.com path=/;

            基于路由的方式使用

                route ...

            基于交互行为判定

                learn ... 

    wlc算法

        least_conn

健康检查参数(跟在server后)

    max_fails=; # 检查失败的次数大于几次就标识Server主机不可达,并移除

    fail_timeout=; # 检查失败的超时时长

    down; # 标记Server主机不可用(维护)

    backup; # 备用服务器(升级中)

对于后端不同的资源类型使用保活状态

    # 后端服务器是apache时,不建议开启keepalive功能

    upstream backend {
        keepalive 32;
    }

外部模块health_check健康检测

    # 只能应用于location中

    # 建议关闭访问日志

    定时检测

        interval=time

    失败次数限定(状态:正常--->失败)

        fails=number

    通过次数

        passes=number

    指明请求的资源

        uri=uri

    关键性资源检测

        match=name

    例子:

        location / {
            proxy_pass http://backend;
            health_check match=welcome;
        }

        match welcome {
            status 200;
            header Content-Type = text/html;
            body ~ "Welcome to nginx!";
        }

        # status is not one of 301, 302, 303, or 307, and header does not have "Refresh:"
        match not_redirect {
            status ! 301-303 307;
            header ! Refresh;
        }

        # status ok and not in maintenance mode
        match server_ok {
            status 200-399;
            body !~ "maintenance mode";
        }
View Code

Nginx_fastcgi模块

官方文档:http://nginx.org/en/docs/http/ngx_http_fastcgi_module.html

部分参数解析及使用

    fastcgi缓存path定义,http only 

        fastcgi_cache_path /data/nginx/cache levels=1:2 keys_zone=one:10m inactive=3m max_size=1g;

    location中调用fastcgi_cache_path

        location ~ .php$ {
            fastcgi_cache one;
            ...
        }

    缓存允许的请求方法

        fastcgi_cache_methods GET HEAD;

    至少使用几次资源就将该资源加载至缓存

        fastcgi_cache_min_uses 1;

    设置cache状态码对应的有效时长

        fastcgi_cache_valid 200 302 10m;

        fastcgi_cache_valid 404      1m;

    是否使用已过期的cache

        fastcgi_cache_use_stale error | timeout | invalid_header | updating | http_500 | http_503 | http_403 | http_404 | http_429 | off ...;

    请求速率限制

        fastcgi_limit_rate rate;

    当fastcgi处理产生的数据非常大时,需要一个临时缓存目录存储数据(一般不推荐使用,会影响效率。最好加大fastcgi_buffer大小)

        fastcgi_temp_path path [level1 [level2 [level3]]];

实例:LNMP基础上使用

    yum install -y php-fpm php-mysql

    location ~ .php$ {
        root           html;
        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_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  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;

    并在所支持的主页面格式中添加php格式页面

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

测试抗压能力

    # 2000个请求并发为100个

    ab -n 2000 -c 100 http://192.168.1.1/test.php
View Code

淘宝开源Web项目tengine

1 官方文档:http://tengine.taobao.org/
2 中文文档,功能强大
原文地址:https://www.cnblogs.com/cq146637/p/8525548.html