• Nginx详解


    思维导图:

    1. Nginx简介

    1.1 nginx概述

    • 说明(C10K)
    • 程序架构(master/worker)
    • nginx的特性
      • 文件并发处理(异步、事件驱动)epoll / select
      • 文件IO(高级IO,异步 mmap)
    • 模块分类
      • 核心模块(core module)
      • 标准模块(HTTP modules、Stream modules、Mail modules)
      • 第三方模块(3rd party modules)
    • nginx的功能
      • 静态web资源服务器
      • 结合FastCGI、uwSGI等协议反代动态资源请求
      • http/https协议的反向代理
      • tcp/udp协议的请求转发
      • imap4/pop3协议的反向代理

    1.2 nginx的安装及程序环境

    • 安装
      • yum安装(添加nginx官方的yum仓库)
      • 编译安装(参数见 nginx -V)
    • 程序结构
      • 主程序文件:/usr/sbin/nginx
      • Unit File:nginx.service
      • 配置文件:/etc/nginx/nginx.conf、/etc/nginx/conf.d/*.conf
      • mime.type:支持的mime类型
    • Nginx工作原理图示

    1.3 零复制机制&五种IO模型

    1.3.1 零复制机制

    • zero-copy:mmap()
      • 将文件直接映射到用户程序的内存中
      • 这段内存空间可以用作进程间的共享内存空间,内核也可以直接操作这段空间
    • zero-copy:sendfile()
      • 借助文件描述符来实现数据拷贝
      • 将文件描述符in_fd的数据拷贝给文件描述符out_fd
    • zero-copy:splice()
      • 在两个文件描述符之间移动数据,且其中一个文件描述符必须是管道描述符
    • zero-copy:tee()
      • 在两个管道描述符之间复制数据
    • 写时复制(copy-on-write),COW

    1.3.2 五种IO模型

    • Blocking I/O:阻塞的IO
    • Non-Blocking I/O:非阻塞的IO
    • Multiplexing I/O:IO多路复用
    • Singal-driven I/O:信号驱动IO
    • Asynchronous I/O:异步IO

    1.4 nginx的基本配置

    • 主配置文件
    • nginx命令
      • -t:进行配置文件语法检查
      • -c:使用指定的配置文件启动nginx
      • -s reload:运行时重载配置文件
    • -s reload重载的原理:
      • 检查配置文件语法后,载入配置文件到内存中并解析,
      • 然后主进程fork一系列新的worker进程,并发送QUIT信号给旧的worker进程(graceful stop)
      • 旧的工作进程接收到QUIT信号后,会停止接收新的连接请求,并继续处理旧的连接直到请求处理完成才退出
    • http协议相关的配置结构

    2. Nginx配置详解

    2.1 main配置段详解

    2.1.1 正常运行的必备配置

    • user user [group];
    • pid /path/to/pid_file;
    • include file | mask;
    • load_module file;

    2.1.2 性能相关

    • worker_processes number | auto;
    • worker_cpu_affinity cpumask...
    • worker_priority number;
    • worker_rlimit_nofile number;

    2.1.3 调试、定位

    • daemon on | off;
    • master_process on | off;
    • error_log file [level];

    2.1.4 事件驱动相关

    定义在events{}中

    • worker_connection number;
    • use epoll;
    • accept_mutex on | off;
    • multi_accept off;

    2.2 http配置段详解

    2.2.1 与套接字相关的配置

    • server{...}
    • listen address[:port]
      • listen address[:port] [default_server] [ssl] [http2 | spdy] [backlog=number] [rcvbuf=size] [sndbuf=size]
    • server_name name;
      • 支持 * 通配任意长度的任意字符
      • 支持 ~ 起始的字符做正则表达式模式匹配

    三个重要的选项:

    • tcp_nodelay on | off;

    发送一个报文时,如果内容本身非常小(可能报文的首部都比报文内容本身大),在开启了持久连接的情况下,可以将多个很小的内容合并,然后统一封装到一个报文中进行统一发送。在这种情况下,本来第一个报文到达的时间点变成了最后一个报文到达的时间点。

    所以,在追求响应速度的情况下,可以关闭统一进行封装的功能,而让每一个小报文单独的立即响应。tcp_nodelay选项就是实现这一功能,所以应该将其开启。

    这个选项只有在开启持久连接功能时才有效,非保持连接情况下,无论关闭或开启都不会有效。

    • tcp_nopush on | off;

    利用完整的报文发送一个文件,而不是把一个文件分开来发送(一个报文发送一个文件)。

    在使用了sendfile的情况下,文件是分开来的:文件内容先发送出去,而首部随后到达。因为封装应用层首部只有特定的程序nginx进行封装,而内核是无法识别的应用层的。所以文件内容直接先发送出去,而文件的首部则在用户空间打包好后再到达内核空间,然后再发送出去。(至于sendfile,它是零复制机制中的一种,需要开启)

    一旦启动了tcp_nopush,那么就可以合并起来一起发送。文件内容会在内核空间等待应用层首部到达之后,再一并用一个完整的报文发送出去。

    • sendfile on | off;
    是否启用sendfile功能,sendfile是零复制机制zero-copy中的一种。
     
    • types_hash_max_size SIZE;

    在nginx内部,为了加速对某些资源的访问,如客户端在请求后,服务器要立即分析请求的资源类型、如何匹配等等,会将这些结果哈希后保存在内存中。types_hash_max_size就是设定在内存中启用多大的空间来保存这些哈希值。

    types_hash_max_size=2048;
    这里的2048表示的是条目,而非大小。

    2.2.2 定义路径相关的配置

    • location [ = | ^~ | ~ | ~* ] URI { ... }
      • =    :精确匹配
      • ^~   :对URI的左半部分做匹配检查,不区分字符大小写,禁用正则
      • ~    :对URI做正则匹配,区分字符大小写
      • ~*   :对URI做正则匹配,不区分字符大小写

    根据请求的URI来做对应的访问设置。

    "location / {}"是一种特殊的uri匹配,无论什么uri路径,都能往这里面装,可以认为它是默认匹配,当其它location都匹配不上时就会匹配它。

    location / {
        deny 10.0.0.202;
        allow all;
    }
    
    location ~* .(jpg|png)$ {
        deny 10.0.0.203;
        allow all;
    }

    优先级:=   >>   ^~   >>   ~/~*   >>   不带符号

    nginx先检查URI的前缀路径,在这些路径中找到最精确匹配请求URI的路径,然后nginx按在配置文件中的出现顺序检查正则表达式路径,匹配上某个路径后立即停止匹配并使用该路径的配置,否则使用最大前缀匹配的路径配置。

    location后面的URI对于root和alias选项的区别:root选项最右边的根对应于URI最左边的根,而alisa选项最右边的根对应于URI最右边的根

    • root path;
    • alias path;
    • index file;
    • error_page code ... [=[response]] URI
    error_page  404   /notfound.html ;   # 这里的也可以写成  404 =200  来冒充正常响应
    location = /notfound.html {
            root /data/nginx/error_pages;
    }

    2.2.3 定义客户端请求的相关配置

    • keepalive_timeout timeout [header_timeout];
    • keepalive_requests number;
    • keepalive_disable none | browser ...;
    • send_timeout time;
    • client_body_buffer_size size;
      • 用于接收客户端请求报文的body部分的缓冲区的大小,默认为16k
      • 超出此大小,将会被暂存到磁盘上由client_body_temp_path所定义的位置
    • client_body_temp_path path [level1 [level2 [level3]]];
    • client_max_body_size 20M;
      • 设定客户端PUT请求中报文内容的最大大小

    2.2.4 对客户端进行限制的相关配置

    • limit_rate rate;
    • limit_except method ... {}
    limit_except  GET  {
        allow  192.168.1.0/24;
        deny all;
    }

    2.2.5 文件操作优化的配置

    • aio on | off;
    • open_file_cache on | off;
      • open_file_cache max=N  [inactive=time]
    • open_file_cache_valid time;
    • open_file_cache_min_uses number;
    • open_file_cache_errors on | off;

    2.2.6 add_header添加响应首部字段

    向客户端进行响应时,给响应报文加上自定义首部或修改指定首部的值。

    server {
        add_header    RealPath   $realpath_root;
    }

    2.3 各种常用模块提供的功能

    2.3.1 ngx_http_access_module

    location  /  {
        deny  192.168.1.1;
        allow  192.168.1.0/24;
        allow  10.0.0.0/16;
        deny  all;
    }

    2.3.2 ngx_http_auth_basic_module

    location  /admin/  {
        auth_basic  "Admin Area";
        auth_basic_user_file   /etc/nginx/.ngxpasswd;
    }

    2.3.3 ngx_http_stub_status_module

    location  /basic_status {
        stub_status;
    }

    对于回显信息的说明:

    Active connections: 291 
    server accepts handled requests
            16630948 16630948 31070465 
    Reading: 6 Writing: 179 Waiting: 106         
    
    # Active connections: 活动状态的连接数;
    
    # accepts:已经接受的客户端请求的总数;
    # handled:已经处理完成的客户端请求的总数;
    # requests:客户端发来的总的请求数;
    
    # Reading:处于读取客户端请求报文首部的连接的连接数;
    # Writing:处于向客户端发送响应报文过程中的连接数;
    # Waiting:处于等待客户端发出请求的空闲连接数;

    2.3.4 ngx_http_log_module

    • log_format name string ...;
    • access_log path [ format [buffer=size] [gzip[=level]] [flush=time] [if=condition] ];
    • open_log_file_cache max=N [inactive=time] [min_uses=N] [valid=time];

    2.3.5 ngx_http_gzip_module

    • gzip on | off;
    • gzip_comp_level level;
    • gzip_min_length  NUM;
    • gzip_disable regex ... ;
    • gzip_buffers number size;
      • gzip_buffers 32 4k;
      • gzip_buffers 16 8k;
    • gzip_proxied off | expired | no-cache | no-store | private | no_last_modified | no_etag | auth | any …;
    • gzip_types mime-type ...;
    gzip  on;
    gzip_comp_level 6;
    gzip_min_length 64;
    gzip_proxied any;
    gzip_types text/xml text/css  application/javascript; 

    2.3.6 ngx_http_ssl_module

    • ssl on | off;
    • ssl_certificate file;
    • ssl_certificate_key file;
    • ssl_protocols [SSLv2] [SSLv3] [TLSv1] [TLSv1.1] [TLSv1.2];
    • ssl_session_timeout 30s;       
      • 设置客户端一侧的连接可以复用ssl session cache中缓存的ssl参数的有效时长
    • ssl_session_cache off | none | [builtin[:size]] [shared:name:size];
      • ssl_session_cache shared:sslcache:20m;

    Nginx使用Master / Worker 的方式工作,由Master进程接收请求,进而再通过轮流或抢占的策略将请求交由选定的Worker进程处理。

    因此在设置SSL时,就需要考虑多Worker进程环境下的SSL Session缓存的问题。最好设置为shared模式,也就是多个Worker之间共享SSL缓存

    ssl_session_cache shared:sslcache:20m;

    server {
            listen 443 ssl;
            server_name www.hgzerowzh.com;
            root /vhosts/ssl/htdocs;
            ssl on;
            ssl_certificate /etc/nginx/ssl/nginx.crt;
            ssl_certificate_key /etc/nginx/ssl/nginx.key;
            ssl_protocols sslv3 tlsv1 tlsv1.1 tlsv1.2;
            ssl_session_cache shared:sslcache:20m;
    }

    2.3.7 ngx_http_referer_module

    • valid_referers none | blocked | server_names | string …;
      • none:请求报文首部没有referer首部
      • blocked:请求报文的referer首部没有值
      • server_names:参数,其可以有值作为主机名或主机名模式

    valid_referers none blocked server_names *.hgzerowzh.com  hgzerowzh.*  ~.hgzero.;
    
    if($invalid_referer) {
            return http://www.hgzerowzh.com/invalid.jpg;
    }

    2.4 URL重写(rewrite)

    2.4.1 ngx_http_rewrite_module

    • rewrite regex replacement [flag]

    四个flag:

    • last:结束本轮循环而进行下一轮循环,类似于continue
    • break:跳出循环而进入后面的代码块
    • redirect:重写后以临时重定向302的方式发送新的URL给客户端
      • 不能以http://或https://开头
    • permanent:重写后以永久重定向301的方式发送新的URL给客户端
      • 不能以http://或https://开头
    # 格式:
    rewrite  正则匹配  替换  [flag]
     
    rewrite /(.*).png$ /$1.jpg  break;
    rewrite /(.*)$  https://bbs.hgzerowzh.com/$1  last;
     
    # http重写为https:
    server {
        listen 80; 
        rewrite (.*) https://bbs.hgzerowzh.com/$1;
    }
    • return code [URL]
    • rewrite_log on | off;
    • if (condition) {...}
    • set $variable value
    # 当使用IE浏览器访问时,重定向到/msie/目录下的对应文件
    if ($http_user_agent ~ MSIE) {
        rewrite ^(.*)$ /msie/$1 break;
    }
    
    # 当http请求的方法为POST,则直接返回405状态码,即Method not Allowed
    if ($request_method = POST) {
        return 405;
    }
    
    # 当请求的资源文件不存在,则直接退出当前匹配,并代理至本机,这种情况下由本机来提供服务,如提供错误页面
    if (!-f $request_filename) {
        break;
        proxy_pass http://127.0.0.1;
    }
    
    # 当访问的是hgzerowzh.com下任意主机,则重定向到www.hgzerowzh.com主机下的对应目录
    if ($http_host ~* "^(.*).hgzerowzh.com$") {
        set $domain $1;
        rewrite ^(.*) http://www.hgzerowzh.com/$domain/ break;
    }
    # 最后一种URL重写为一个新的主机名站点,但使用URL重写的效率比较低下,远不如直接为此站点独立定义一个虚拟主机

    3. nginx配置概览

    user  nginx;                # 定义worker进程的用户和用户组
    pid   /var/run/nginx.pid;   # 使用的pid文件
    load_module /path/to/file;  # 加载的模块
    include /path/to/file;      # 导入的配置文件
    
    worker_processes  auto;     # worker进程数
    worker_cpu_affinity auto;   # worker进程和cpu绑定
    worker_priority 0;          # 定义worker进程的nice值
    worker_rlimit_nofile 3600;  # 所有的worker进程能够打开的文件数量上限
    
    daemon on;                  # 是否守护进程模式
    master_process on;          # 是否启用master/worker模式
    error_log  /var/log/nginx/error.log   warn;   # 错误日志的记录位置及级别
    
    
    events {
        worker_connections  1024;   # 每个worker的最大并发连接数
        use epoll;                  # 使用的并发连接处理方法
        accept_mutex on;            # 是否启用互斥锁,On意味着由各worker轮流处理新请求,
            # Off意味着每个新请求的到达都会通知所有的worker进程
    }
    
    
    http {
    
            tcp_nodelay on;    # 在keepalived模式下的连接,多个报文不要合并一起发
            tcp_nopush on;     # 开启sendfile时,让数据包挤满到一定程度才发送,挤满之前被阻塞
            sendfile on;       # 启用零拷贝模式
    
            keepalive_timeout  65;           # 保持连接的超时时间,设置0为不开启
            keepalive_requests  100;         # 一次长连接的最大资源请求数
            keepalive_disable  none;         # 指定对哪种浏览器禁用长连接
            send_timeout time;               # 向客户端发送响应报文的超时时间,
                     # 指两次写操作之间的间隔时间
            
            client_body_buffer_size  16k;         # 指定接收客户端请求报文的body部分的缓冲区大小,
                     # 默认为16k,超出此大小就放到下面的临时路径中
            client_body_temp_path  /var/tmp/client_body  1 2 2;  
                                             # 设定用于存储客户端请求报文body部分的临时路径和子目录结构和数量
    
             
            aio on;                                # 是否开启aio功能
            open_file_cache max=2000 inactive=10;  # 缓存打开文件的元数据
            open_file_cache_valid 60s;             # 缓存有效性的检查频率,默认60s
            open_file_cache_min_uses 3;            # 指定在活动有效期内,最小的命中次数
        open_file_cache_errors on;              # 是否缓存查找时发生错误的文件一类的信息
            
            
            limit_rate 0;            # 限制客户端的传输速率(bytes/second)
            limit_except GET {       # 限制使用除了GET请求之外的方法时,允许的客户端
                    allow 192.168.1.0/24;
                    deny all;
            } 
            
            
            gzip on;            # 启用gzip压缩响应报文
            gzip_comp_level 6;  # 指定压缩比
            gzip_disable none;  # 对于指定的浏览器不启用压缩功能
            gzip_min_length 64; # 启用压缩功能的响应报文大小阈值
            gzip_buffers 32 4k; # 支持实现压缩功能时为其配置的缓冲区数量及每个缓冲区的大小
            gzip_proxied any;   # nginx作为代理服务器时,在何种条件下启用压缩功能
            # gzip_proxied off | expired | no-cache | no-store | private | no_last_modified | no_etag | auth | any ...;
            gzip_types mime-type;  # 压缩过滤器,仅对此处设定的MIME类型的内容启用压缩功能
            
            
            # 实现防盗链功能
            valid_refers none blocked server_names *.hgzero.com hgzero.* ~.hgzero.;  # 设置合法的referer来源
            # valid_refers none | blocked | server_names | string ...;     # none表示没有referer,blocked表示referer值为空
            if($invalid_referer){
                    return http://www.hgzero.com;
            }
            
            
            server {  # 定义一个虚拟主机,要注意虚拟主机的匹配规则
                    # listen IP:PORT  [default_server] [ssl] [http2|spdy] [backlog=NUM] [rcvbuf=size] [sndbuf=size];
                    listen 80;
                    
                    # 定义主机名加域名,即网站地址,注意这里的匹配机制顺序:精确匹配>左侧*通配符>右侧*通配符>正则匹配
                    server_name www.hgzero.com  *.hgzero.com  hgzero.*  ~^wwwd+.hgzero.com$;
                    
                    # 在响应首部中添加字段,这里添加了一个RealPath字段,值为变量realpath_root的值
                    add_header RealPath $realpath_root;    
                    
          
                    # 使用ssl(要在监听ip和端口后面加上ssl字段)
                    ssl on;
                    ssl_certificate cert.pem;                   # ssl证书的位置
                    ssl_certificate_key cert.key;               # 与证书匹配的私钥文件
                    ssl_protocols sslv3 tlsv1 tlsv1.1 tlsv1.2;  # 指定ssl协议版本,默认为tlsv1 tlsv1.1 tlsv1.2
                    # ssl_protocols [SSLv2][SSLv3][TLSv1][TLSv1.1][TLSv1.2];
                    ssl_session_cache shared:sslcache:20m;      # 设置ssl的session缓存
                    # ssl_session_cache off | none | [builtin[:size]]  [shared:name:size];
                    ssl_session_timeout 30s;           # 设置客户端一侧的连接可以复用ssl session cache中缓存的ssl参数的有效时长
                    
                       
                    #############################
                    location [ = | ^~ | ~ | ~*  ]  uri  {  # 要特别注意location容器的匹配规则
                            root /data/one/;
                    }
                    #############################
                    
                    location /images/  {
                            root /data/hgzero/;              # 站定根目录,相当于uri中左边的/
                            # alias /data/hgzero/;           # 定义站点别名,相当于uri中右边的/
                            index index.html index.php;      # 站点主页文件
                    }
                    
                    # 自定义错误页面
                    error_page  404  /notfound.html;
                    location = /notfound.html {
                            root /data/nginx/error_pages;
                    }
                    
                    # 实现用户访问控制
                    location /admin/ {
                            alias /webapps/app1/data/;
                            auth_basic "Admin Area";                     # 提示的字符串
                            auth_basic_user_file /etc/nginx/.ngxpasswd;  # 用户名及密码认证文件,可以用htpasswd生成
                    }
                    
                    # 获取nginx状态信息,这里最好要定义访问控制权限
                    location /basic_status {
                            stub_status;
                    }
                    
                    # 指定日志记录的格式
                    log_format main '$remote_addr' - $remote_user [$time_local] "$request"'
                            '$status $body_bytes_sent "$http_referer"'
                            '"$http_user_agent" "$http_x_forwarded_for"'';
                            # $remote_addr:客户端地址,如果有代理服务器,则要使用$http_x_forwarded_for
                            # $remote_user:远程客户端用户名称
                            # $time_local:记录访问时间和时区信息
                            # $request:记录用户访问时的url和http协议信息,如:"GET /favicon.ico HTTP/1.1"
                            # $status:记录客户端请求时返回的状态码
                            # $body_bytes_sent:记录服务器响应给客户端的主体大小
                            # $http_referer:记录此次请求是从哪个链接过来的
                            # $http_user_agent:记录客户端的浏览器信息
                            # $http_x_forwarded_for:记录每一级代理的信息
                    access_log /spool/logs/nginx-access.log  main;  # 指定日志文件的存放位置
                    # access_log /spool/logs/nginx-access.log gzip buffer=32k;
                    
                    open_log_file_cache max=2000;                   # 缓存各日志文件相关的元数据信息
                    # open_log_file_cache  max=N [inactive=time] [min_uses=N] [valid=time];
            }           
    }
    Nginx基本配置概览

  • 相关阅读:
    《这本书能让你戒烟》:野路子戒烟法。也许读者是否戒烟成功已经不重要了,重要的是这本书的销售非常成功。三星推荐
    《100种过度医疗大公开》:转译自日文版,日文版依据的是美国的“Choosing Wisely”项目。三星推荐
    《癌症·真相:医生也在读》:癌症新药专家的癌症防治科普,重点是免疫疗法。四星推荐。
    《抗癌前线:癌症研究的前沿进展》:肿瘤基因组学博士的肿瘤科普,三星推荐
    《医疗改革:给政策制定者的建议》:真的是给政策制定者看的,文风比较专业和枯燥,二星
    《120医生教您学急救》:内容还是偏专业,心肺复苏显然不应该是仅仅通过看书来学习的。三星推荐
    [TypeScript] Overload a Function with TypeScript’s Overload Signatures
    [TypeScript] Use TypeScript’s never Type for Exhaustiveness Checking
    [TypeScript] Represent Non-Primitive Types with TypeScript’s object Type
    [TypeScript] Define Custom Type Guard Functions in TypeScript
  • 原文地址:https://www.cnblogs.com/hgzero/p/12890859.html
Copyright © 2020-2023  润新知