Nginx简介

解决基于进程模型产生的C10K问题,请求时即使无状态连接如web服务都无法达到并发响应量级一万的现状,2006年由俄罗斯lgor sysoev编写,全称为engine X, 缩写为nginx,官方站点为http://nginx.org,2013年发出企业版本NginxPlus. 二次发行版本:Tengine, OpenResy….

Nginx特性

  • 1 模块化设计,较好的扩展性,早期不支持模块的动态装卸载

  • 2 高可靠性,基于master/worker模式

    • master:负责启动服务,分析配置文件,负责启动子进程和worker进程

    • worker: 真正响应用户请求进程

  • 3 支持热部署(平滑迁移):不停机更新配置文件,更换日志文件,更新服务器程序版本

  • 4 内存消耗低: 10K个keep-alive连接模式下的非活动连接仅消耗2.5M内存

  • 5 支持event-driven事件驱动模型,aio驱动机制,mmap内存映射机制

Nginx基本功能

  • 1 静态资源的web服务器,自身只能简单的接收和响应http

  • 2 http协议的反向代理服务器

  • 3 pop3,smtp imap4等邮件协议的反向代理

  • 4 能缓存打开的文件(元数据缓存:文件的描述符等信息),能加快文件的打开速度

  • 5 支持FastCGI(php-fpm),UWSGI(python web framwork框架)等协议机制,实现代理后端应用程序交互

  • 6 模块化(非DSO机制)

standard HTTP modules标准(核心)HTTP模块:自动编译进程序不止一个
Optional HTTP modules可选http模块
Mail modules邮件模块
3rd party modules第三方模块,在编译时需手动指明加载方式加载
  • 7 支持过滤器,例如ZIP,SSI(服务端包含)

  • 8 支持SSL加密机制

web服务相关的功能

  • 虚拟主机(server)

  • keepalive

  • 支持访问日志

  • 支持基于日志进行缓冲,以提高日志的存取性能

  • url rewrite

  • 路径别名

  • 基于IP及用户的访问控制

  • 支持速率限制(每客户端连接速度)

  • 支持并发数限制(每客户端的并发连接)

Nginx的基本架构:master/worker

master/worker模型:
  • 一个master进程可以生成一个或多个worker进程,每个worker基于事件驱动,linux(epoll),freeBSD(kqueue),solaris(/dev/poll)响应用户请求, 其支持sendfile,sendfile64,这两种支持的文件大小不同

  • master负责内容:

    • 加载配置文件

    • 管理worker进程

    • 平滑升级

  • worker负责内容

    • 响应客户端请求

    • 提供http服务

    • 提供http代理

    • 提供fastcgi代理

nginx工作原理图


Nginx编译安装配置

环境准备
  • yum install -y “Development Tools”

  • yum install -y “Server platform development”

  • yum install -y pcre-devel openssl-devel zlib-devel

  • useradd -r nginx

  • 检查Linux系统上epoll机制是否存在

Nginx的编译及安装
./configure --prefix=/usr/local/nginx --conf-path=/etc/nginx/nginx.conf --user=nginx --group=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 --with-http_ssl_module --with-http_stub_status_module --with-http_gzip_static_module --with-debug

make && make install
Nginx的配置文件
  • /etc/nginx/nginx.conf : 主配置文件

    • Include conf.d/*.conf

  • /etc/nginx/mime.types : 所支持的MIME类型列表

  • /etc/nginx/fastcgi_params : fastcgi的配置文件

  • /etc/nginx/fastcgi.conf : 与fastcgi_params一般只使用一个

  • /etc/nginx/uwsgi_params : 与uwsgi框架的配置文件

  • /etc/nginx/scgi_params : cgi的配置文件

  • /etc/nginx/proxy.conf : 代理的配置

  • /etc/nginx/sites.conf : 配置虚拟主机的

/etc/nginx/nginx.conf配置文件的一般格式:
  • 1 全局指令 : 放置于main block中,即文档根

  • 2 模块指令 : 由模块引用,其它必须放置于directive中

  • 3 Directive    Value1 [Value2,….]

  • 4 支持使用变量:

    • set variable value;

    • 内置变量: 由模块引入

    • 自定义变量(较新版本支持)

    • 引用 变量: $variable

  • 5 每条指令都以;号结束,否则就是语法错误

  • 6 主配置文件组织结构

      main block : 不能放在花括号中,正常运行必备的配置,优化性能相关的配置,用于调度,定位问题的配置.
    
      event {
          ...
      }       
    
      #事件驱动模块段,面向用户并发连接请求响应组织配置机制
    
      http {
          ...
      }
    
      #web模块相关配置
    
      mail {
          ...
      }
    
      #邮件模块相关配置, 编译时候默认无此模块
  • 7 Nginx HTTP configuration示意图:


主配置文件框架解析

Main配置段常用参数
  • (1) 正常运行必备的配置指令

    • 指定每个用户能够发往worker进程的信号的最大数量

    • 指定每个worker进程能打开的最大文件描述符数量(nofile: number of file)

    • 指定nginx进程的PID文件路径, 默认为:pid /var/runl/nginx/nginx.pid

    • 指定用于运行worker进程的用户和组,默认是nginx用户,nginx组

    • uesr USERNAME [GROUPNAME];

    • pid /path/to/pid_file;

    • worker_rlimit_nofile #;

    • worker_rlimit_sigpending #;

  • (2) 性能优化相关的配置

    • [-20,19],worker进程的优先级, 默认为0

    • 将worker进程与指定的CPU进行绑定,这种绑定不能隔离CPU,CPU还可能会响应其它进程请求.

      示例:
        worker_cpu_affinity 00000001 00000010 00000100;
    • worker进程的个数,通常应该为物理CPU核心数量减1或者减2,worker_processes auto;可以根据物理CPU自动设定. worker不使用进程或线程处理请求, 而是直接将worker绑定到CPU上, 这样就没有进程切换的说法了.

    • woker_processes #;

    • worker_cpu_affinity CPUMASK CPUMASK...;

    • worker_priority NICE;

  • (3)调试定位问题的配置

    • 错误日志文件及级别, 出于调试的需要,可以设定为debug,但在debug级别在编译时使用—with-debug选项时才有效

    • 是否以master/worker模型运行nginx,off后,只单个进程启动Nignx.

    • 是否以守护进程方式启动nginx

    • daemon [off|on];

    • master_process [on | off];

    • error_log /path/to/error_log Level;

event配置段常用参数
  • worker_connections #;

    • 每个worker进程所能够响应的最大并发请求数量, 请求的最大上限为:worker_processes * worker_connections

  • use [epoll | rgsig | select | poll]]

    • 定义使用的事件模型, 建议让nginx自动选择

  • accept_mutex [on | off];

    • 定义内部调用请求至worker时请求的互斥锁文件(各worker接收用户的请求的负载均衡锁),on:能够让多个worker轮流地,序列化的响应新请求

  • lockfile /path/to/lockfile

    • 锁文件定义位置

http配置段常用参数
  • server {}

    • 定义一个虚拟主机,server可以出现一次或多次

      server {
        listen [IP:]PORT;
        server_name NAME;
        root /path/to/documentroot;
      }
  • listen address [:port] [default_server] [[ssl] [http2 | spdy]]

  • listen port [default_server] [ssl] [http2 | spdy]

    • default_server:设置默认虚拟主机, 当用户使用IP地址访问时,就返回default_server的虚拟主机, 如果未定义default_server时,第一个虚拟主机将做为默认的主机

    • ssl : 用于限制只能通过SSL连接提供服务,不是以端口确认其协议的, 故需要启用ssl,需要在监听的端口后面, 添加ssl选项

    • spdy : spdy protocol(google研发的http协议,比http/1.1性能要好, 全称为speedy),在编译时编译了spdy模块的情况下,用于支持spdy协议

    • http2 : http version2,在编译时需要开启http2协议支持

  • server_name NAME [....]; : 指明主机名称

    • (1) 先做精确匹配,例如:www.zhenping.me

    • (2) 左侧通配符,例如:*.zhenping.me

    • (3) 右侧通配符,例如:www.zhenping.*

    • (4) 正则表达式匹配,例如:~^.*.zhenping.me$

    • default_server

      nginx默认工作法则: 先将域的匹配规则,先做hash计算,把计算的结果放置进内存,下次访问请求过来时, 直接做对比
    • servername后可跟一个或多个主机名, 名称还可以使用通配符和正则表达式(~),域名匹配顺序

  • tcp_nodelay [on | off];

    • 对keepalive模式下的连接是否使用tcp_nodelay选项,默认关闭.其功能为:把多个小报文合并为一个报文,一起发送. 此机制可以提高带宽利用率,将发往同一个主机很小的TCP报文合并成一个,实际生产对于用户请求即使浪费带宽也不能合并请求

  • tcp_nopush [on | off];

    • 是否启用tcp_nopush(FreeBSD)或tcp_cork(linux)选项,仅在sendfile为on时有用, 其功能:尝试将多个报文首部压缩成一个发送, 默认为off,不启用该功能

  • sendfile [on | off];

    • 是否启用sendfile功能,静态文件直接在内核中封装响应,而不是从内核空间到用户空间封装后,再发往内核空间.

  • roo /PATH/TO/Directory;

    • 设置web资源的路径映射,用于指明请求的URL所对应的文件的目录路径,可用于server或location中.

      ```
      示例:
       server {

        ...
        root /www/html;

      }

      http://www.zhenping.me/images/logo.jpg → /www/html/images/logo.jpg

    server {
        ...
        server_name www.zhenping.me;
        location /images/ {
            root /www/html;
            ...
        }
    }

    http://www.zhenping.me/images/logo.jpg --> /www/html/images/logo.jpg
```
  • location [ = | ~ | ~* | ^~ ] url { ...}

  • location @name {...}

    • = : URI的精确匹配

    • ~ : 做正则表达式匹配,区分字符大小写

    • ~* : 做正则表达式匹配,不区分字符大小写

    • ^~ : URI的左半部分匹配,不区分字符大小写

    • 允许根据用户请求的URI来匹配定义的各location,匹配到时, 此请求将被相应的location块中的配置所处理, 简言之:用于为需要用到专用配置的uri提供特定配置.

    • 当匹配多次时,其匹配优先级为:精确匹配=,^~,~或~*,不带符号的URL, 如果优先级都一样, 就匹配最精确的规则

      location = / {
        [configuration A]
      }
      
      location / {
        [configuration B]
      }
      
      location /documents/ {
        [configuration C]
      }
      
      location ^~ /images/ {
        [configuration D]
      }
      
      location ~* \.(gif|jpg|jpeg)$ {
        [configuration E]
      }
  • alias

    • 只能用于location配置段,用于定义路径别名

      location /imags/ {
        root /data/imgs/;
      }
      
      location /imags/ {
        alias /data/imgs/;
      }
      
      注意: root指令:给定的路径对应location的"/",这个URI
            /imags/test.jpg --> /data/imgs/imags/test.jpg
          alias指令:路径为对应的location的"/url/"这个URI
              /imags/test.jpg --> /data/imgs/test.jpg
  • index

    • 设置默认主页(nginx_http_index_module模块引入), 可以带上变量,如$geo根据不同IP地址来设置不同的语言主页,应用上下文为:http,server,location

      index index.html index.php;
  • error_page code ...[=[response]] uri;

    • 自定义错误页面,根据http状态码重写向错误页面

      示例:
        1) 指明错误页面
            error_page 404 /404.html;
            error_page 500 502 503 504 /50x.html;
            location = /50x.html {
                root html;
            }
        2) 根据指定的响应状态码进行响应
            error_page 404 = 200 /404.html;
  • try_files file... uri;

  • try_files file... =code;

    • 可用于server,location中, 以指定的顺序检查文件的存在性响应

    • 尝试查找第1至第N-1个文件,第一个即为返回给请求者的资源,若1至N-1文件都不存在, 则跳转至最后一个uri(必须 不能匹配至当前location,而应该匹配至其它location,否则会导致死循环)

      示例:
        server {
            listen 80 default_server;
            server_name www.zhenping.me;
            root /data/imgs/;
            index index.html;
            location /images/ {
                try_files index.html /images/test1.html /images/test2.html /images/test3.html;
            }
      
            location = /images/test3.html {
                expires 10s;
            }
面向客户端请求相关的配置
  • keepalive_disable none | browser;

    • 禁止那些浏览器使用keepalive功能,如: keepalive_disable msie6

  • keepalive_timeout #s;

    • 设定keepalive连接的超时时长,0表示禁止长连接,默认启用为75s

  • keepalive_requests #;

    • 在keepalive连接上所允许请求的最大资源数量,默认为100;

  • send_timout #;

    • 发送响应报文的超时时长,默认为60s;

  • client_body_buffer_size SIZE(8k | 16k);

    • 接收客户请求报文body的缓冲区大小, 默认为16k(64位系统,32位系统为8K),超出指定大小时将被移存于磁盘上.

  • client_body_temp_path [Level1 [level2 [level3]]]

    • 设定用于存储客户端请求body的临时存储路径及子目录结构和数量

      client_body_temp_path /var/tmp/client_body 2 2;
      
        表示一级子目录用2字符表示,二级子目录下用2字符表示,每级目录都有256个文件夹. 其是采用16进制的表示文件,1个字符最多表示16,2字符表示256
对客户端请求进行限制
  • limit_except METHOD {...};

    • 对指定范围之外的其它方法进行访问控制,应用于location上下文

      limit_except GET {
        allow 172.16.0.0/16;
        deny all;
      }
  • limit_rate SPEED;

    • 限制客户端每秒种所能够传输的字节数, 默认为0,表示不限制,应用于http,server,location,if in location上下文中

      server {
        ...
        if ($slow) {
            set $limit_rate 4k;
        }
      }
  • limit_rate_after SIZE;

    • 超出SIZE的值, 就限制速度,应用于http,server,location,if in locataion上下文中

      location /flv/ {
        flv;
        limit_rate_after 500k;
        limit_rate 50k;
      }
文件操作优化相关的配置
  • aio on | off;

    • 是否启用异步IO模式, 应用于http, server,location上下文中

  • directio size | off;

    • 是否启用直接IO操作, 不在内存中缓冲, 直接从硬盘加载使用(当大于指定的size),应用于http,server,location

  • open_file_cache off | max=N [inactive=time];

    • (1) 文件描述符

    • (2) 文件大小

    • (3) 最近一次的修改时间

    • (4) 打开的目录的结构

    • (5) 没有找到或者没有权限操作的文件的相关信息

    • 对打开的文件进行缓存 ,nginx可以缓存以下三种信息

    • max=N : 可缓存的最大条目上限,一旦达到上限, 则会使用LRU算法从缓存中删除最近最少使用的缓存项

    • inactive=time : 在此处指定的时长内没有被访问过的缓存项识别为非活动缓存项, 因此直接删除

  • open_file_cache errors on|off;

    • 是否缓存找不到其路径的文件,或没有权限访问的文件相关信息

  • open_file_cache_valid time;    

    • 每隔多久检查一次缓存中缓存项的有效性,默认为60秒

  • open_file_cache_min_uses number;

    • 缓存项在非活动其限内最少应该被访问的次数

ngx_http_access_module模块的配置(基于IP的访问控制)

  • allow address | CIDR | unix: | all; 允许

  • deny address | CIDR | unix: | all; 拒绝

    • 应用上下文件:http,server,location,limit_except

      示例:
        location / {
            deny 192.168.1.1;
            allow 192.16.1.0/24;
            allow 10.1.1.0/16;
            allow 2001:0db8::32;
            deny all;
        }