Nginx架构详解

Nginx

高性能的HTTP服务器程序,又是HTTP/IMAP/POP3协议的反向代理服务器

面对较高并发请求时,由于prefork机制上限并发请求最多为1024个,超过1024个连接请求时,不一定会有压力,因为,有些请求的响应速度非常快,例如一个请求在5毫秒ms内就能完成,1秒钟内可完成500个请求,此时并发请求可能会不止1024个;但再多请求上万个时就无法满足了,就有了C10k问题;nginx就能解决C10k的问题;能支持较大并发的服务器程序,突破了1万个请求;

二次开发:tengine,openresty

Nginx的特性

  • 模块化设计,较好的扩展性
  • 高可靠性
  • 基于master/worker架构设计
  • 支持热部署;可在线升级
  • 不停机更新配置文件、更好日志文件、更新服务器查询版本
  • 较低的内存消耗
  • 1万个keep-alive连接模式下的非活动连接仅消耗2.5M内存
  • event-driven机制:支持aio,mmap(内存映射)

Nginx基本功能:

  • 静态资源的web服务器
  • 可作为http协议的反向代理服务器
  • pop3/imap4协议反向代理服务器
  • 支持FastCGI(lnmp)、uWSGI等协议
  • 模块化(非DSO机制)机制,著名模块zip,SSL,...

web服务器相关的功能:

支持虚拟主机、keepalive、访问日志、url rewrite重写、路径别名、基于ip即用户的访问控制,支持速率限制及并发数限制,...

Nginx的程序架构

Nginx架构图

一个master进程,可生成一个或多个worker进程

  • master:负责加载分析配置文件、管理worker进程、平滑升级、...
  • worker:处理并响应用户请求

一个master有多个worker,每个worker可响应n个请求,每个worker有核心模块core和外围的诸多模块modules组成,为了实现http功能有http协议的ht_core模块,为了功能完善还有很多其它模块,如实现负载均衡的ht_upstream模块,ht_proxy反代模块,Fastcgi模块ht_fastcgi模块;

用到哪些功能编译哪些模块或载入哪些模块即可;基于每种模块,可以与后端的不同应用通信;例如基于ht_core模块可与web ;基于server通信,基于ht_fastcgi模块可与php通信;基于memcache模块可与mamcache通信;所以这是反代模型工作时的架构;

nginx是高度模块化的,nginx的woker进程中除了用于响应用户请求之外,还有实现管理的组件,如cache loader负责加载缓存、cache manager负责管理缓存,用到时可启用,否则可不启用;

基于在本地磁盘上与本地磁盘数据通信时,支持高级IO机制、sendfile机制、AIO机制、mmap机制等;

实现并发用户请求响应时,可基于kevent、epoll、select;

从完整视角看nginx的功能

worker进程接收客户端的请求,如果使用缓存功能,可把后端服务器的内容缓存到本地,还负责从缓存中加载数据,直接响应给客户端;如果客户端请求的内容没有,还代理客户端到后端服务器上取资源,如果后端服务器是http就使用http模块进行,如果是php服务器就使用FastCGI模块进行;即向客户端提供服务、向后端提供反代、又能将后端服务器内容在本地缓存下来以提高性能,能够基于kv结构在本地将数据存下来,检索性能是O1的恒定不变,把key(键)缓存在内存中,检索起来非常快;

mmap内存映射,如何文件要想被访问,都要先从磁盘载入(布置到)内存才能被访问;而内存映射指的是,在内存空间中找一段空间,并没有把数据复制过来,是可以直接通过这段内存加载数据,在有些场景中,为了避免打开文件复制内存中这个复制过程,直接把文件映射一下,能够完成某个文件被访问到;

Nginx模块类型

核心模块:core module
标准模块

  • Standard HTTP modules 标准http模块
  • Optional HTTP modules 可选http模块
  • Mail modules 邮件模块
  • Stream moudles 流模块:实现传输层代理(4层代理)

3rd party modules:第三方模块

每个模块都引入2个项目:第一,指令,有某个模块,就有相应的配置指令,没有编译的模块就没有这个配置指令;第二,还有内置变量,不同模块有不同变量;

Nginx的安装

解编译安装nginx

下载nginx源码包:http://nginx.org/en/download.html

其中,Pre-Built Packages为预编译好的包,下载后直接安装即可;预编译好的包通常由2种类型,一是rpm包,二是deb包(debian系统用的);

nginx的repo仓库源:

[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/mainline/OS/OSRELEASE/$basearch/
gpgcheck=0
enabled=1
[root@VM_0_2_centos ~]# yum info nginx
Loaded plugins: fastestmirror, langpacks
Repository epel is listed more than once in the configuration
Loading mirror speeds from cached hostfile
Available Packages
Name        : nginx
Arch        : x86_64
Epoch       : 1
Version     : 1.12.2
Release     : 3.el7
Size        : 531 k
Repo        : epel/7/x86_64
Summary     : A high performance web server and reverse proxy server
URL         : http://nginx.org/
License     : BSD
Description : Nginx is a web server and a reverse proxy server for HTTP, SMTP, POP3 and
            : IMAP protocols, with a strong focus on high concurrency, performance and low
            : memory usage.

编译安装nginx选项:

--prefix=/etc/nginx 安装路径
--sbin-path=/usr/sbin/nginx 指明nginx程序文件安装路径
--conf-path=/etc/nginx/nginx.conf 主配置文件安装位置
--error-log-path=/var/log/nginx/error.log 错误日志文件安装位置
--http-log-path=/var/log/nginx/access.log 访问日志文件安装位置
--pid-path=/var/run/nginx.pid 指明pid文件安装位置
--lock-path=/var/run/nginx.lock 锁文件安装位置
--http-client-body-temp-path=/var/cache/nginx/client_temp 客户端body部分的临时文件存放路径,如果服务器允许客户端使用put方法提交大数据时,临时存放的磁盘路径
--http-proxy-temp-path=/var/cache/nginx/proxy_temp 作为代理服务器,服务器响应报文的临时文件存放路径
--http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp 作为fastcgi代理服务器,服务器响应报文的临时文件存放路径
--http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp 作为uwsgi代理服务器,服务器响应报文的临时文件存放路径
--http-scgi-temp-path=/var/cache/nginx/scgi_temp 作为scgi反代服务器,服务器响应报文的临时文件存放路径
--user=nginx 指明以那个身份运行worker进程,主控master进程一般由root运行
--group=nginx
--with-http_ssl_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_random_index_module
--with-http_secure_link_module
--with-http_stub_status_module
--with-http_auth_request_module
--with-threads
--with-stream
--with-stream_ssl_module
--with-http_slice_module
--with-mail
--with-mail_ssl_module
--with-file-aio
--with-http_v2_module
--with-ipv6

编译安装nginx

下载nginx-1.8.1.tar.gz源码包

[root@VM_0_2_centos ~]# tar xf nginx-1.8.1.tar.gz
[root@VM_0_2_centos ~]# cd nginx-1.8.1/
[root@VM_0_2_centos ~]# ./configure --help

其中,--with都是表示要把指定模块编译进来,表示要启用指定的模块;--without表示不编译指定的模块,即禁用指定的模块;

安装编译环境包组

[root@VM_0_2_centos ~]# yum -y groupinstall "Development Tools" "Server Platform Development"

如果用ssl模块,要安装openssl开发包;如果用url重写模块,要安装pcre的开发包;默认有可能都没安装;

[root@VM_0_2_centos ~]# yum -y install openssl-devel pcre-devel zlib-devel
[root@VM_0_2_centos ~]# ./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_gzip_static_module --with-debug --with-http_stub_status_module
[root@VM_0_2_centos ~]# make && make install
[root@VM_0_2_centos ~]# ls /usr/local/nginx/
html  sbin 安装完成后只有2个文件,html是测试页,sbin是主程序;
[root@VM_0_2_centos ~]# ls /usr/local/nginx/sbin/
nginx 只有一个程序文件;
[root@VM_0_2_centos ~]# ls /usr/local/nginx/html/
50x.html  index.html 测试网页;
在启动nginx之前还需要添加nginx用户组,否则会提示:
nginx: [emerg] getpwnam("nginx") failed
[root@VM_0_2_centos ~]# useradd -r -M  nginx
[root@VM_0_2_centos ~]# /usr/local/nginx/sbin/nginx -t 测试nginx语法错误;
[root@VM_0_2_centos ~]# /usr/local/nginx/sbin/nginx -h 查看帮助选项;
-c filename 指定配置文件(default: /etc/nginx/nginx.conf)
-s signal 发送信号给master进程,signal可为:stop, quit, reopen, reload;
-g directives 在命令行中指明全局指令;
[root@VM_0_2_centos ~]# /usr/local/nginx/sbin/nginx -s stop 停止nginx;
[root@VM_0_2_centos ~]# /usr/local/nginx/sbin/nginx 启动nginx;
此时,在win7浏览器输入192.168.255.2,可见测试欢迎网页;
[root@VM_0_2_centos ~]# ps aux
可见nginx的主控进程master和worker进程启动的个数,都是可以定义的;
[root@VM_0_2_centos ~]# cp /etc/nginx/nginx.conf{,.bak}
[root@VM_0_2_centos ~]# ls /etc/nginx/
fastcgi.conf 支持fastcgi的配置文件,与php结合要编辑此文件;
fastcgi.conf.default 默认配置
fastcgi_params 支持fastcgi的配置文件,与php结合要编辑此文件;
fastcgi_params.default
koi-utf 支持语言的配置文件
koi-win 支持语言的配置文件
mime.types 支持的MEMI类型的配置文件
mime.types.default
nginx.conf 主配置文件
nginx.conf.bak
nginx.conf.default
scgi_params 支持scgi的配置文件
scgi_params.default
uwsgi_params 支持uwsgi的配置文件,与params结合要编辑此文件;
uwsgi_params.default
win-utf
导出命令至PATH环境变量,使用就不需要绝对路径了:
[root@VM_0_2_centos ~]# vim /etc/profile.d/nginx.sh
export PATH=/usr/local/nginx/sbin:$PATH
[root@VM_0_2_centos ~]# chmod +x /etc/profile.d/nginx.sh
退出shell,重新登录即可生效;

Nginx选项

[root@VM_0_2_centos ~]# nginx -h
nginx version: nginx/1.12.2
Usage: nginx [-?hvVtTq] [-s signal] [-c filename] [-p prefix] [-g directives]

Options:
  -?,-h         : this help
  -v            : show version and exit
  -V            : show version and configure options then exit
  -t            : test configuration and exit   测试检查语法
  -T            : test configuration, dump it and exit
  -q            : suppress non-error messages during configuration testing
  -s signal     : send signal to a master process: stop, quit, reopen, reload   -s reload 重载
  -p prefix     : set prefix path (default: /usr/share/nginx/)
  -c filename   : set configuration file (default: /etc/nginx/nginx.conf)
  -g directives : set global directives out of configuration file

Nginx配置文件

配置文件的组成部分:

  • 主配置文件:nginx.conf
    include conf.d/*.conf
  • fascfgi,scgi,uwscgi的相关配置
  • mime.types

主程序文件:/usr/sbin/nginx
Unit File:nginx.service

Nginx配置指令:必须以分号结尾;
directive value1 [value2 ...];

支持使用变量:

  • 内置变量:是由模块引入,可直接引用;
  • 自定义变量:set variable_name value;
    引用变量:$variable_name
[root@VM_0_2_centos ~]# vim /etc/nginx/nginx.conf
worker_processes  2; 
启用worker的进程数,设置为auto时,启动worker的数量为当前主机的cpu核心数;

可使用lscpu查看;

[root@VM_0_2_centos ~]# lscpu
Architecture:          x86_64
CPU op-mode(s):        32-bit, 64-bit
Byte Order:            Little Endian
CPU(s):                1
On-line CPU(s) list:   0
Thread(s) per core:    1
Core(s) per socket:    1
Socket(s):             1
NUMA node(s):          1
Vendor ID:             GenuineIntel
CPU family:            6
Model:                 79
Model name:            Intel(R) Xeon(R) CPU E5-26xx v4
Stepping:              1
CPU MHz:               2394.446
BogoMIPS:              4788.89
Hypervisor vendor:     KVM
Virtualization type:   full
L1d cache:             32K
L1i cache:             32K
L2 cache:              4096K
NUMA node0 CPU(s):     0
worker_cpu_affinity 0010 0100; 指定第1和第2颗cpu为worker运行
[root@VM_0_2_centos ~]# ps axo command,pid,psr 
...
nginx: master process /usr/   5157   1
nginx: worker process         5158   0  表示工作在第0号cpu上;

查看worker工作在哪颗cpu上,cpu编号是从0开始;
使用cpumask标识,有几颗cpu就用几位二进制数标识使用cpu的个数;

例如:有八颗cpu,用8个位二进制
0000 0000 - 1111 1111
0000 0001 表示第0号cpu
0000 0010 第1号cpu
0000 0100 第2号cpu
0000 1000 第3号cpu
0001 0000 第4号cpu
... ...

使用命令ps axo command,pid,psr,ni 可查看优先级
worker_priority -5; 指定优先级nice值为-5;

events {
    worker_connections  1024; 每个worker进程支持的最大并发数
}
    server { 一个server定义一个虚拟主机
        listen       80;
        server_name  localhost;
    }

Nginx配置文件结构

main block:全局配置(对http及mail模块均有效);
  event {
     ...
  }:事件驱动的相关配置;
http {
  ...
}:http/https协议的相关配置;
mail {
   ...
}:mail相关配置;
Stream {
   ...
}

http相关的配置

http {
   ...
   ...:各server的公共配置
   server {
      ...
   }: 各server用于定义一个虚拟主机;
    server{
      ...
      listen   
      server_name 当前主机名
      root 根文档路径
      alias 别名
      location [OPERATOR] URL { 定义类似于别名的映射;
         ...
         if CONDITION {
               ...
         }
     }
}

main block:就是配置核心模块,在http://nginx.org/en/docs/ngx_core_module.html官方文档中都有使用配置说明;

配置指令的类别

  • 正常运行必备的配置
  • 优化性能的配置
  • 用于调试、定位问题的配置

正常运行必备的配置

1、user USERNAME [GROUPNAME];
指定用于运行worker进程的用户和组;组可省略;
user nginx nginx;

2、pid /PATH/TO/PID_FILE;
指定nginx进程的pid文件路径;
pid /var/run/nginx.pid;

3、worker_rlimit_nofile number;
单个worker进程所能打开的最大文件数,默认1024个;

4、include file | mask;
指明包含进来的其他配置文件片段;

5、load_module file;
指明要装载的动态模块;

性能优化相关的配置

1、worker_processes number | auto;
指明worker的进程数,通常应该等于或小于当前主机物理CPU核心数;
auto:当前主机物理CPU核心数;

2、绑定nginx使用固定哪颗cpu
worker_cpu_affinity cpumask ...;
worker_cpu_affinity auto [cpumask];

CPUMASK:掩码
0000 0001:0号CPU
0000 0010:1号CPU

3、worker_priority number;
nice:[-20,19],nice值越小,优先级越高;
优先级:[100-139],nice值为0时,优先级为120;

4、work_rlimit_nofile number;
work进程所能够打开的文件数量上限;

调试、定位问题

1、daemon on|off;
是否以守护进程方式启动nginx进程;
只有调试时才关闭,改为off;

2、master_proces on|off;
是否以master/worker模型启动nginx进程;
只有调试时才关闭,改为off;

3、error_log file | stderr | syslog:server=address[,parameter=value] | memory:size [debug | info | notice | warn | error | crit | alert | emerg];
错误日志文件的记录方式及其日志级别;其中debug,依赖于编译时要使用--with-debug选项;

方式:
file /PATH/TO/SOME_LOG_FILE;指定日志文件路径,也可以使用syslog记录日志;
stderr:发送到错误输出;
syslog:server=address[,parameter=value]:发送给syslog服务器;要指明服务器IP或参数;
memory:size 记录到内存中;性能好,断电会消失,磁盘IO压力大;一般打开日志缓冲,缓解IO压力;

日志级别:
debug依赖于configure时的--with-debug选项;

事件驱动相关配置

events{
      ...
}

1、worker_connections numbers;
每个worker进程所能够并发打开的最大连接数;
只能用在events上下文;
每一个进程所能够打开是数量是受限于(worker_rlimit_nofile设置)它所能够打开的文件数量的;不能超出worker_rlimit_nofile的数值,很多时候需要手动指明;

当前nginx主机所能响应的最大并发连接数=worker_processes*worker_connections

例如:

events {
          worker_connections  1024;
 }

2、use method;
指明并发连接请求处理时使用的方法;
支持的方法有:select、poll、kqueue、epoll、/dev/poll、eventport
use epoll;

3、accept_mutex on|off;
互斥功能,是否打开负载均衡锁,启用时,表示用于让多个worker进程轮流地、序列化的响应新请求;

4、lock_file file;
nginx使用锁机制实现互斥功能,并且序列化的让各worker访问这段共享内存;因此,锁在哪,叫什么需要自己定义;

http协议相关配置

http{
      ...
}
ngx_http_core_module模块
定义套接字相关功能

1、server {...}
配置一个虚拟主机;基于ip和主机名没显著区别;
只能用于http上下文中;

server {
         listen PORT;
         server_name HOSTNAME;
         root /PATH/TO/DOCUMENTROOT;
         ...
}

注意:
(1)基于port的虚拟主机:
listen指令需要使用不同的端口;
(2)基于HOSTNAME的虚拟主机:
server_name指令指向不同的主机名;
(3)基于IP的虚拟主机;
listen IP:port
ip要使用不同的地址;

2、listen定义方法有3种:
listen address[:port] [default_server] [ssl] [backlog=number] [rcvbuf=size] [sndbuf=size]; 指明地址,默认端口为80;

listen port [default_server] [ssl] [backlog=number] [rcvbuf=size] [sndbuf=size];指定端口的所有地址,即本机所有可用地址的端口;

listen unix:path [default_server] [ssl] [backlog=number] [rcvbuf=size] [sndbuf=size];套接字有3类:ipv4套接字、ipv6套接字,unix socket套接字,使用套接字文件实现通信,客户端和服务端都是本机进程,使用本地回环接口进行通信,特点就是不会经由协议栈发送数据;

注意:如果iptables规则,input,output默认为drop,从本机客户端到服务端是不允许的,要使用:放行本机通信;

iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT

default_server:设置默认虚拟主机;
基于ip地址的虚拟主机用户使用了主机名访问,或基于主机名的虚拟主机用户使用了主机名访问;用户使用的主机名都不匹配,就设置默认响应;
ssl:限制只能通过ssl连接提供服务;端口要为443;
backlog:后援队列的长度;例如并发最大为100个,来了200请求,就要排队,如果排队也满了就靠后援队列,后援队列也满了就有可能超时了;
rcvbuf:接收缓冲区大小;
sndbuf:发送缓冲区大小;

3、server_name name ...;
为虚拟主机指明当前server的主机名;可为多个,后可跟一个或空白字符分隔的多个主机名;
支持使用*通配任意长度的任意字符;
支持使用~起始的正则表达式模式字符串;

应用策略:(优先级)由高到底:
(1)首先精确匹配;
(2)左侧*通配符匹配;
(3)右侧*通配符匹配;

(4)正则表达式模式匹配;

例如:服务器名称为www.magedu.com
servername www.magedu.cmm;
server_name *.magedu.com;
server_name www.magedu.*;
server_name ~^.*.magedu..*$;

用户访问:mail.magedu.com(能匹配第2,4条), www.magedu.com

4、tcp_nodelay on|off;
客户端请求有小数据时,服务端立即发送;默认on,只对keepalived模式下的连接是否启用TCP_NODELAY选项;

tcp协议有个特性,自动优化:
tcp特性每次都要3次握手,4次断开,如果两主机间通信时,某次在保持连接的通信上,服务器只发送很小的时数据给客户端,会浪费带宽(开销比数据大),tcp会自动等待很小的报文增多时一起发送,这就要delay;如果客户端只请求了这个很小的数据,必然会等待很长时间才能得到响应,此时就要启用tcp_nodelay模型,客户端请求有小数据时,服务端也立即发送;

5、tcp_nopush on|off;
在senfdfile模式下,是否启用TCP_CORK选项;

6、sendfile on|off;
是否启用sendfile功能,即在内核中直接封装响应报文响应用户的请求;默认是关闭的,需要手动启用;
(把用户所请求的数据直接在内核中封装响应发送给客户端)

定义路径相关配置

1、root path;
设置web资源的路径映射;用于指明用户请求的url所对应的本地文件系统上的文档所在目录路径;
可用的上下文:

  • http:表示对所有server都生效;
  • server:表示只对当前一个server生效;
  • location:表示只对server定义的location中的URL生效;
  • if:表示仅对条件判断生效;

注意:在将来工作中网页文件的路径一定要是标准化的,运维管理几十台或上百台服务器时,就使用固定标准的位置;运维要求第一要稳定,第二标准化,第三自动化;

标准化:操作系统标准化,在应用时编写自动化很多应用程序会很方便;同类应用中硬件配置标准化、应用程序版本标准化、配置文件标准化、各种路径标准化;只有标准化了才能做到流程化,流程化降低工作量的保证,也是基于自动化执行脚本的保证;

例如:把root放在http内或server内*

[root@VM_0_2_centos ~]# vim /etc/nginx/nginx.conf
root /web/html;
[root@VM_0_2_centos ~]# mkdir -pv /web/html
[root@VM_0_2_centos ~]# vim /web/html/index.html

Nginx Server

访问浏览器193.112.32.203就显示Nginx Server内容

例如:基于主机名的虚拟主机:

[root@VM_0_2_centos ~]# vim /etc/nginx/nginx.conf
server {
      listen       80;
      server_name  www1.stu11.com;
      root /web/host1;    
}
server {
      listen 80;
      server_name www2.stu11.com;
      root /web/host2;
}   

[root@VM_0_2_centos ~]# cd /web
[root@VM_0_2_centos web]# mv html/ host1
[root@VM_0_2_centos web]# cp -r host1/ host2
[root@VM_0_2_centos web]# vim host2/index.html

Nginx Server2

[root@VM_0_2_centos ~]# nginx -t [root@VM_0_2_centos ~]# nginx -s reload

在浏览器输入:www1.stu11.com显示Nginx Server1
在浏览器输入:www2.stu11.com显示Nginx Server2

另一种创建虚拟主机的方法:

[root@VM_0_2_centos ~]# mkdir /etc/nginx/conf.d
[root@VM_0_2_centos ~]# vim /etc/nginx/conf.d/host2.conf

server {
          listen 80;
          server_name www2.stu11.com;
          root /web/host2;
} 

[root@VM_0_2_centos ~]# vim /etc/nginx/nginx.conf
include conf.d/*.conf;

此方式可实现快速添加、删除虚拟主机,非常方便;

2、location 有2种方式:
location [ = | ~ | ~* | ^~ ] uri { ... }
location @name {...}

根据用户请求的URI来匹配定义的多个location,匹配到时,此请求将被相应的location块中的配置指令所处理;有点类似于if的功能;

符号 匹配
= URI精确匹配;用户给定的URI与location中的完成一样
^~ 对URI左半部分做匹配检查,不区分字符大小写
~ 做正则表达式模式匹配,区分字符大小写
~* 做正则表达式模式匹配,不区分字符大小写

匹配优先级:=、^/~*、不带符号;

例如:

location = / { 
             [ configuration A ]
}

location / { 
             [ configuration B ]
}

location /documents/ {
             [ configuration C ]
}

location ^~ /images/ {
             [ configuration D ]
}

location ~* \.(gif|jpg|jpeg)$ {
             [ configuration E ]
}

客户端请求是http://www.magedu.com/,能匹配A和B,最终第1个精确匹配应用配置A;

请求的是http://www.magedu.com/index.html,能匹配A和B,不能精确匹配,最终第2个应用配置B;

请求的是http://www.magedu.com/documents/abc.jpg,能匹配B、C、E,根据优先级,最终应用配置E;

请求的是http://www.magedu.com/documents/document.html,能匹配B、C,匹配最长的,最终应用配置>

请求的是http://www.magedu.com/images/abc.jpg,能匹配D、E,最终应用配置D;

客户端请求的主机名被server匹配,于是就检查server中的各location是否与客户提供的URI有匹配的,如果有就用到相应的location上,没有就使用默认配置;

如果用户请求的URI被server中的代码块中多个location都能匹配到,应用则按照优先级;

例如:http://www.magedu.com
在server下定义了根文档路径
root /web/host1;
/web/host1/images/1.jpg
访问资源时路径:http://www.magedu.com/images/1.jpg
其中:/images/1.jpg就被称为uri;

location可以对某特定资源类型加以限制,例如用户访问的都是以txt结尾,压缩以后发送;此时就必须标识出那些资源以txt结尾,来作出额外处理:

location ~*\.txt {
     gzip on;
}

location引入了新的上下文,可有指令,但仅对location能匹配到的uri资源生效;所以在一个server中location可出现多次,分别用来实现对不同类型资源做特定处理功能;location中还可嵌套location;

server {
   ...
   location {
        ...
   }
   location{
         ...
   }
}

3、alias path;
定义路径别名,也是文档映射的一种机制,只能用在location上下文;

在http中,定义别名,例如:
alias /bbs/ /web/forum/

请求资源:http://www.magedu.com/bbs/a.jpg
对应资源:http://www.magedu.com/web/forum/a.jpg
文件路径:/web/forum/a.jpg

在nginx中,定义别名,例如:

location /bbs/ {
     alias /web/forum/;
}

相当于访问的是:/web/forum/a.jpg;

有时常用法,例如:

location /bbs/ {
      root /web/forum/;
}

相当于访问的是:/web/forum/bbs/a.jpg

注意:
root指令:给定的路径对应于location中/uri/左侧的/;包含uri本身;
alias指令:给定的路径对应于location中的/uri/右侧的/(这个url),而不包含uri本身;

例如:

[root@VM_0_2_centos ~]# vim /etc/nginx/nginx.conf
在同一server下:
location / {
         root /web/host1;
}

location /bbs/ {
         root /web/forum/;
}

[root@VM_0_2_centos ~]# mkdir -pv /web/forum/
[root@VM_0_2_centos ~]# vim /web/forum/index.html

/web/forum

[root@VM_0_2_centos ~]# mkdir /web/forum/bbs [root@VM_0_2_centos ~]# vim /web/forum/bbs/index.html

/web/forum/bbs/

浏览器访问:http://www1.stu11.com/bbs/
显示:/web/forum/bbs/

配置文件改为别名:

[root@VM_0_2_centos ~]# vim /web/forum/index.html
location /bbs/ {
      alias /web/forum/;
}
[root@VM_0_2_centos ~]# nginx -t
[root@VM_0_2_centos ~]# nginx -s reload

浏览器访问:http://www1.stu11.com/bbs/
显示:/web/forum

4、index file ...;
可用位置:http,server,location;
设置默认主页;在不同的location可指定不同的主页;

5、error_page code...[=[response]] url;
自定义错误页面,根据用户请求的资源的http响应的状态码实现错误页重定向;

错误页面位置在:安装路径:/usr/local/nginx/html/:
50x.html index.html

例如:客户端请求http://www.magedu.com/hello.html
先匹配server_name为www.magedu.com的配置项;
再里面匹配的location配置项;只有2个location,能匹配第一个;
就在location里定义的root根文档路径去找hello.html;
如果没有,则匹配error_page被重定向到/404.html;
因为资源不存在而被改为:
http://www.magedu.com/404.html
又算是一个新请求,再次判断资源属于哪个server_name、location等过程;一个URL被处理的2次,最终把错误页面响应给用户;

定义错误页:

[root@VM_0_2_centos ~]# vim /etc/nginx/nginx.conf
error_page  404              /404.html;

[root@VM_0_2_centos ~]# vim /web/host1/404.html                  

Error_Page

用错误页面响应时,响应码是404;
也可以定义响应码,例如让客户端显示错误页面时的响应码为200,则:

[root@VM_0_2_centos ~]# vim /etc/nginx/nginx.conf
error_page  404  =200       /404.html;

在浏览器输入:http://www1.stu11.com/hello.html
显示:Error_Page

编译时没有自动创建:/var/run/nginx/nginx.pid
解决办法:
sudo nginx -c nginx.conf
sudo nginx -s reload

服务器端错误页面:可定义多个响应码

error_page   500 502 503 504  /50x.html;
location = /50x.html {
     root   html;
 }

6、try_files file ... uri;
用于server、locaton上下文;
表示当用户请求资源不存在时,尝试try_files真第一的文件资源;

当在某个location请求某url时,如果不存在,则尝试查找第一个到第n-1个文件来响应客户端,到如果对应的路径没有第一个文件,就找第二个,所有路径都没有文件资源时,才用最后一个uri;最后一个url就是跳转页面了;

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

1、keepalive_timeout timeout [header_timeout];
设定保持连接的超时时长,0表示禁止使用长连接,默认为75秒;

2、keepalive_requests number;
在一次长连接上所允许请求的资源的最大数量,默认100个;

3、keepalive_disable none|browser...;
对哪种浏览器禁用长连接;none表示不禁用;

4、send_timeout time;
向客户端发送响应报文的超时时长,默认60秒;特别地,是指两次写操作之间的间隔时长;

5、client_body_buffer_size size;
用于接收客户端请求报文的body部分的缓冲区大小,默认为16k,超出此大小时,其将被暂存到磁盘上;

6、client_body_tmp_path path[level1 [level2 [level3]]];
设定用于存储客户端请求报文的body部分的临时存储路径及子目录结构和数量;

每一个客户端请求报文的body大小为16k,并发连接的请求量有很多;因此,如果每一个请求量都大于了16k,都应该缓存到磁盘上,如果请求数量有2万个,就意味着在这个目录下有2万个文件,从这2万个文件中找一个在某个时刻是特别慢,为了加速这个过程,就实现分级存储;

例如:/var/tmp/body/{1,2,3}创建3个一级子目录,还可在1下再创建{a,b,c}二级子目录;

在文件存储时,可以按级存储,好处在于可以按级查找文件;把每个用户请求的URL,把URL做md5编码,编码后首字母是0-15之间的数字,所以就看第一位是什么,第一位是0就放在0目录下,是1就放在1目录下...;然后再找第二位,是a就放在a目录下,是b就放在b目录下...;
由于使用的是16个数字,就意味着可以把2万个文件平均在16个子目录下,第一次查找就可以缩减了15倍,在二级子目录下查找又可以缩减15倍;
因此,这里分级的意义,就是用来指明,创建多少一级子目录,创建多少二级子目录,多少三级子目录;
这里的[level1 [level2 [level3]的代表一个数字,表示十六进制数的个数;

例如:

/var/tmp/body 2 表示在body目录下使用两个十六进制字符创建一级子目录,一个十六进制是4位二进制数,两个十六进制数就是8位二进制数;因此,一共有256中变化,即:
00-ff 可创建256个一级子目录;

/var/tmp/body 2 1 表示在每一个一级子目录下,使用一个十六进制数创建二级子目录,即可创建16个二级子目录;
00-ff 可创建256个一级子目录;
0-f 可创建16个二级子目录;

/var/tmp/body 2 1 2 表示在每个二级子目录下有两个十六进制数创建三级子目录,即可创建256了三级子目录;
00-ff 可创建256个一级子目录;
0-f 可创建16个二级子目录;
00-ff 可创建256个三级子目录;
所以,这样查找一个文件只需前5个字符,就可以第一次缩减256倍,第二次缩减16倍,第三次又缩减256倍;就是28+24+2^8,只需3次查找就基本可以定位到文件的位置了;

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

1、limit_rate rate;
限制服务器端每秒钟响应给客户端的传输速率,单位是字节/秒,bytes/second,0表示无限制;只用于http,server,location,if;

例如:

[root@VM_0_2_centos ~]# vim /etc/nginx/nginx.conf
location /download/ {
      limit_rate 20480;
      root /web/host1;
}

[root@VM_0_2_centos ~]# mkdir /web/host1/download
[root@VM_0_2_centos ~]# dd if=/dev/zero of=/web/host1/download/test.img bs=1M count=50       
[root@VM_0_2_centos ~]# nginx -s reload
[root@VM_0_2_centos ~]# vim /web/host1/download/index.html

download

在本机测试:

[root@VM_0_2_centos ~]# wget http://192.168.255.2/test.img   

浏览器测试:http://www1.stu11.com/download/test.img
显示:下载对话框;速度非常慢;

2、limit_except method... {...};
限制对指定的请求方法之外的其它方法的使用客户端;

例如:

表示除了GET方法以外的其它方法仅允许192.168.1.0/32中的主机使用

limit_except GET {
       allow 192.168.1.0/32;
       deny all;
}

表示除了GET(自动包含HEAD)和POST之外的其它方法仅允许172.18.0.0/16中的主机使用

limit_except GET POST{
    allow 172.17.0.0/16;
    deny all;
}

表示除了GET之外的其它方法仅允许172.18.100.67的主机使用

[root@VM_0_2_centos ~]# vim /etc/nginx/nginx.conf
location /download/ {
   limit_except GET {
       allow 172.18.100.67;
       deny all;
    }
     root /web/host1;
}

在172.18.200.2主机测试:

[root@VM_0_2_centos ~]# sudo apt-get install curl
[root@VM_0_2_centos ~]# curl http://172.18.100.67/download/index.html

显示:download

[root@VM_0_2_centos ~]# curl -I http://172.18.100.67/download/index.html :只显示响应报文首部信息;
[root@VM_0_2_centos ~]# curl -X PUT http://172.18.100.67/download/index.html

显示:403 Forbidden等信息;

删掉:

limit_except GET {
     allow 172.18.100.67;
     deny all;
}

[root@VM_0_2_centos ~]# curl -X PUT http://172.18.100.67/download/index.html

显示:405 Not Allowed等信息;

文件操作优化的配置

1、aio on|off|threads[=pool];
是否启用aio功能;默认关闭;指明使用多少个线程;不指定就是用多少启用多少线程;
可用在http, server, location;

2、directio size|off;
是否启用直接IO;启用多大的IO空间;
直接IO就是写请求的时候,数据不在内存中缓存而是直接刷到磁盘上去,这就是直接IO;对性能有影响,对数据可靠性比较高;

3、open_file_cache off;
open_file_cache max=N[inactive=time];
有助于提高性能;对打开的文件是否缓存下来,nginx缓存的是文件的元数据;

nginx可以缓存以下三种信息:
(1)文件的描述符、文件大小和最近一次的修改时间;
(2)打开的目录结构;
(3)没有找到的或没有权限访问的文件的相关信息;

  • off:表示不缓存;
  • max=N:可缓存的缓存项上限;达到上限后会使用LRU算法实现缓存管理;
  • inactive=time:缓存项的超时时长,在此处指定的时长内未被命中的缓存项即为非活动项;

4、open_file_cache_errors on|off;
是否缓存,查找时发生错误的文件一类的信息;open_file_cache的功能是否有效,取决于此处指令;

5、open_file_cache_min_uses number;
缓存项在非活动期限内,最少应该被访问的次数;
哪些文件被认为是非活动项:在open_file_cache中指定的时长内没有被访问的项就叫非活动项;其实,非活动项是有最小门槛限制的;在指定的时长内,至少要访问多少次,才认为是活动项,少于此处指定的次数才认为是非活动项,而不是0次;

在open_file_cache中指定的时长内没有被访问的项就叫指令的inactive参数指定的时长内,在至少命中此处指定的次数方可不被归类到非活动项;

6、open_file_cache_valid time;
缓存项有效性的检查频率;默认为60秒;
能改善nginx的性能,nginx很多地方都能用到缓存,而缓存的管理方法都是近似的;理解了这一个,其它就很容易了;

一旦发现文件是非活动期限,超出非活动时长,或在指定时长内,访问次数小于min_uses指定的次数,就应该把该文件删除;此处就是设置,每隔多久检查一次文件的非活动期限;

ngx_http_access_module模块

实现基于客户端ip的访问控制功能;跟http基于ip实现访问控制是一类法则;

1、allow address|CIDR|unix:|all;
2、deny address|CIDR|unix:|all;

可用上下文:http,server,loaction,limit_except

例如:

location / {
     deny 192.168.11.1;
     allow 192.168.1.0/24;
     allow 10.1.1.0/16;
     allow 2001:0db8:/32;
     deny all;
}
ngx_http_auth_basic_module模块

基于用户认证的模块

例如:

location / {
       auth_basic           "closed site";
       auth_basic_user_file conf/htpasswd;
}

1、auth_basic string|off;
使用basic机制进行用户认证;
用户为虚拟用户,要指明账号、密码的位置;

2、auth_basic_user_file file;
认证用的账号密码文件

文件格式:
name:password:comment
例如:
name1:passwd1
name2:passwd2:comment
name3:passwd3
...

密码格式:
htpasswd命令
(或使用crypt()函数进行加密)

例如:创建账号、密码文件

[root@VM_0_2_centos ~]# yum -y install httpd-tools
[root@VM_0_2_centos ~]# htpasswd -c -m /etc/nginx/.nginxpasswd tom 给tom用户设定密码
输入:tom的密码;
[root@VM_0_2_centos ~]# htpasswd -m /etc/nginx/.nginxpasswd jerry 给jerry用户设定密码
输入:jerry的密码;

[root@VM_0_2_centos ~]# vim /etc/nginx/nginx.conf
location /admin/ {
     auth_basic "Admin Area";
     auth_basic_user_file /etc/nginx/.nginxpasswd;
}

把root /web/host1;指令放在location外面

[root@VM_0_2_centos ~]# mkdir /web/host1/admin
[root@VM_0_2_centos ~]# vim /web/host1/admin/index.html

Admin

[root@VM_0_2_centos ~]# nginx -t [root@VM_0_2_centos ~]# nginx -s reload

在浏览器输入:http://www1.stu11.com/admin
显示:需要进行身份验证

ngx_http_stub_status_module模块

能够启用nginx自带的状态页面,用于输出nginx的基本状态信息;

1、stub_status;

例如:

[root@VM_0_2_centos ~]#vim /etc/nginx/nginx.conf
location /status {
    stub_status;
}

在浏览器输入:http://www1.stu11.com/status
显示为:
Active connections: 2
server accepts handled requests
19 19 44
Reading: 0 Writing: 1 Waiting: 1

解释:
Active connecttions:处于活动状态的客户端连接的数量;(包括等待客户端发来请求、开始建立连接的客户端但已经处于等待客户端发请求、或正在处理客户端请求、正在给客户端发响应报文)

accepts:服务器已经接受客户端请求的总数;(包括已经处理完、正在处理)
handled:已经处理完成的客户端请求的总数;(接收的大于处理完成的数量;)
requests:客户端已经发来的请求总数;(包含拒绝的请求)

Reading:正处于读取客户端请求报文首部的连接数量;
Writing:正处于向客户端发送响应报文过程中的连接数;
Waiting:正处于等待客户端发出请求的空闲连接数;如果启用保持连接功能,客户端请求资源后没再请求就处于空闲状态;如果waiting状态数量很多,表示大量客户端处于空闲状态,有可能是keep allive timeout设置时间太长所导致;

ngx_http_referer_module模块

基于引用做访问控制;表示从哪个链接跳转到当前页面;

1、valid_refers none|blocked|server_names|string...;
定义合法的referer数据;
可实现防盗链拒绝访问,拒绝来自某链接到本网页等功能;

none:请求报文首部没有referer首部;
blocked:请求报文的referer首部没有值;
server_names:其值是主机名;一般是自己的域名;

string:有2种
arbitrary string:直接字符串,可以使用*通配符;
regular expression:被指定的正则表达式模式匹配到的字符串,要使用~开头;

例如:使用主机名;

valid_referers none blocked server_names *.magedu.com magedu.* ~\.magedu\.;

if($invalid_referer){
   return 403;
}

其中,$invalid_referer是内嵌变量,表示只有不能被valid_refers指令匹配到的头被归类到invalid_referer;直接调用$invalid_referer变量即可;

ngx_http_ssl_module模块

官方文档:http://nginx.org/en/docs/http/ngx_http_ssl_module.html
默认关闭

1、ssl on|off;
是否启用当前虚拟主机的ssl
手动测试时,可临时关闭;
基于ip地址的ssl会话,在一个ip上进行只能一个虚拟主机ssl会话;

2、ssl_certificate file;
当前虚拟主机使用的PEM格式的证书文件;

3、ssl_certificate_key file;
指明私钥文件;当前虚拟主机使用的证书文件中的公钥配对儿的私钥文件路径,PEM格式;

4、ssl_protocols [SSLv2] [SSLv3] [TLSv1] [TLSv1.1] [TLSv1.2];
指明使用的ssl协议版本;最好使用TLSv1以上的版本;

5、ssl_session_cache off | none | [builtin[:size]] [shared:name:size];
ssl会话创建非常消耗资源,能缓存下来对同一主机的多次请求,在有效时间内可不用建立ssl会话,基于缓存来实现;
指明ssl会话的缓存机制;

off:禁止使用会话;坚决禁止;
none:禁止使用会话;温和禁止;告诉客户端会话有可能被重用,但并不保证;

builtin:使用openssl(加密的库)内建的缓存机制,此为各worker独占;
为每个worker进程在自己的空间中加载ssl相关库,各worker是不共享的;每个worker自己独立管理自己的ssl会话缓存;缺陷:同一个用户请求,第一个请求调度在第一个worker响应,第二个请求有可能被调度到第二个worker响应,这样缓存有可能无法被命中;

shared:相对于builtin而言,ssl缓存是由各worker共享的缓存;缓存空间需要定义name,size等,每个共享必须有名字;共享的缓存由nginx进程所管理的一段内存空间,对于nginx,共享内存空间非常多,所以共享内存空间要有名字和空间大小;
name:缓存空间的名称;每一段空间间必须有一个名字;
size:字节为单位的缓存空间的大小,每1MB内存空间可缓存4000个会话;10M空间就可缓存4万个会话;
一般只使用共享,效率会高些;多个虚拟主机可使用同一段缓存空间来缓存自己的ssl会话;

6、ssl_session_timeout;
ssl会话超时时长,指ssl会话缓存中缓存条目的有效时长(即非活动期限的有效时长);默认是5分钟;

7、ssl_prefer_server_ciphers on | off;
当使用SSLv3和TLS协议时,优先使用服务器端的加密算法;倾向于使用服务器端的加密算法;

8、ssl_verify_client on | off | optional | optional_no_ca;
是否验证客户端证书;一般不会验证客户端证书;

ssl_ciphers ciphers;
加密算法,必须是Openssl所支持的加密算法才可以;
!(叹号)表取反,+表示包含的算法;
使用openssl ciphers命令,可查看openssl支持哪些加密算法;

nginx配置虚拟主机使用https示例:centos7系统

server {
    listen       443 ssl; 强制ssl会话
    server_name  localhost; 虚拟主机名

    ssl_certificate      cert.pem; 证书
    ssl_certificate_key  cert.key; 私钥

    ssl_session_cache    shared:SSL:1m; 共享ssh缓存大小
    ssl_session_timeout  5m; 会话ssl的超时时长

    ssl_ciphers  HIGH:!aNULL:!MD5; ssl的加密算法
    ssl_prefer_server_ciphers  on; 倾向于使用服务器端的加密算法
    location / {
        root   html;
        index  index.html index.htm;
}

创建私钥:

[root@VM_0_1_centos ~]# mkdir ssl
创建签署证书请求:
[root@VM_0_1_centos ~]# (umask 077;openssl genrsa -out ssl/nginx.key 1024)
[root@VM_0_1_centos ~]# openssl req -new -key nginx.key -out nginx.csr -days 365
输入:
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:Beijing
Locality Name (eg, city) [Default City]:Beijing
Organization Name (eg, company) [Default Company Ltd]:MageEdu
Organizational Unit Name (eg, section) []:Ops
Common Name (eg, your name or your server's hostname) []:www1.stu11.com
Email Address []:[email protected]

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
其它可留空;

创建私有CA:


[root@VM_0_2_centos ~]# cd /etc/pki/CA/
创建CA私钥:
[root@VM_0_2_centos ~]# (umask 077;openssl genrsa -out private/cakey.pem 2048)
创建CA自签证书:
[root@VM_0_2_centos ~]# openssl req -new -x509 -key private/cakey.pem -out cacert.pem -days 365
输入:
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:Beijing
Locality Name (eg, city) [Default City]:Beijing
Organization Name (eg, company) [Default Company Ltd]:MageEdu
Organizational Unit Name (eg, section) []:Ops
Common Name (eg, your name or your server's hostname) []:ca.magedu.com 
Email Address []:[email protected]

创建CA必要文件:
[root@VM_0_2_centos ~]# touch index.txt
[root@VM_0_2_centos ~]# echo 01 > serial
CA签署证书请求:
[root@VM_0_2_centos ~]# openssl ca -in /etc/nginx/ssl/nginx.csr -out /etc/nginx/ssl/nginx.crt -days 365

[root@VM_0_2_centos ~]# vim /etc/nginx/nginx.conf
    server {
        listen       443 ssl;
        server_name  www1.stu11.com;

        ssl_certificate      /etc/nginx/ssl/nginx.crt;
        ssl_certificate_key  /etc/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   html;
            index  index.html index.htm;
        }
    }

[root@VM_0_2_centos ~]# nginx -t
[root@VM_0_2_centos ~]# nginx -s reload

在浏览器输入:https://www1.stu11.com

ngx_http_log_module模块

用于实现以指定格式记录用户请求日志;
在httpd设置日志格式时,有4种:combined、common、referer、agent等;但日志记录的信息越丰富,对并发较高的场景中,对磁盘IO压力越大;

1、access_log path[format[buffer=size[flush=time]][if=condition]];
path:可指明日志文件路径;
format:日志格式;
buffer=size日志缓存大小;(磁盘刷写频率过高时应调大此值);
flush=time:多长时间从内存刷写至磁盘上一次;

2、access_log path format gzip[=leve][buffer=size][flush=time][if=condition];
指明日志文件压缩存放时的gzip压缩比;
access_log syslog:server=address[,parameter=value] [format[if=condition]];
向指定的日志服务器发送日志;
**access_log off; **
关闭访问日志;

3、log_format name string...;
定义日志格式,指明名称和字符串;与httpd定义略有区别,在httpd中使用%u等宏定义,而对nginx则使用内建的变量来定义格式;

nginx的内置变量 功能
$bytes_sent 发送的字节数
$connection 连接的序列号
$connection_requests 连接请求
$msec 毫秒
$pipe p表示基于管道,.表示otherwise
$request_length 请求报文的长度
$request_time 请求时间
$status 响应码
$time_iso8601 时间格式
$time_local 本地时间

例如:

log_format compression '$remote_addr - $remote_user [$time_local] '
       '"$request" $status $bytes_sent '
       '"$http_referer" "$http_user_agent" "$gzip_ratio"';

access_log /spool/logs/nginx-access.log compression buffer=32k;
compression 日志格式类型
$remote_addr 是nginx某个模块引入的内建变量,表示远程地址
$remote_user 远端用户名
$request 客户端发出的请求
$http_referer 上一级跳转的页面
$http_user_agent 浏览器类型
$gzip_ratio 压缩比

使用access_log调用compression即可;
如果想要定义httpd中的combined日志格式,自己要找相关的变量;nginx默认的日志格式为combined;
只是定义不同,在nginx里使用变量定义,而在httpd里使用宏定义;

4、open_log_file_cache max=N[inactive=time][min_uses=N][valid=time];
open_log_file_cace off; 关闭此功能

定义缓存空间,用来存储文件描述符,对Linux系统,任何文件在内核中都能基于某个数字来追踪这个文件,这个数字就是引用这个文件的唯一标识;称为fd(file descriptors)叫做文件描述符;
可理解为内核打开文件引用的临时映射的数字标识;
多个server虚拟主机打开的文件不止一个,日志的每一次写操作都要临时通知内核,打开一个文件,写完之后就关闭了,再写时还得再找,这样太慢了;可以把打开的文件缓存下来,每个文件打开后用一个描述符映射,随时用随时找这个描述符就可以;

max=N:最大缓存条数,默认10个;能缓存多少条打开的文件,在一个缓存中能缓存多少个打开的文件条目;如果超过设置条目,使用基于LRU算法最近最少使用算法,进行换进换出做缓存管理;

inactive=time:非活动时长;缓存下来在指定时间没有用过,或者使用次数少于设定的次数,默认为10秒钟,就认为是非活动状态,可基于LRU算法换出;

min_uses=N:最少使用次数;缓存下来后在指定时间内默认10秒,最少使用多少次,默认1次;即如果默认在10秒,使用少于1次就标记为非活动状态;判断非活动除了使用时长还有使用次数;

valid:验证缓存条目有效性的频率;检查缓存文件的路径有效性,默认60秒;

ngx_http_rewrite_module模块

用于实现将用户请求的URI基于正则式转换为其它URI机制;并且以重定向方式默认返回给客户端,让客户端对新的URI重新再次发起请求;

处理步骤:

在server当中,使用rewrite指令定义的重写机制是自上而下逐条进行处理的,类似于iptables的规则都是自上而下应用设置的;如果被第一条处理,下面不会再检查;因为处理过了已经返回给客户端,客户端已经再次请求新URI了;

执行过程会重复如下操作:
基于用户请求的URI去搜索location;
在一个location内部的指令,是从上而下逐条检查;
如果URI被重写循环重复,但不会超过10次;

用户请求到达nginx服务器端时,服务端有多个server虚拟主机,映射到哪个server,取决于用户请求的server name,根据用户请求的server name最终被判断到底请求的是哪个server,从而判断属于哪个server,每个srever内部还有多个location,每个location用来定义URL到本地文件系统路径的映射方式以及内部处理机制;因此,还有根据用户请求的URL去匹配location;
所以,这里有2步操作,第一步,根据server name匹配是哪个server,第二步,根据用户请求的URL去匹配server内部的location;在一个location内部可能存在多个rewrite指令,rewrite指令作用就是把用户请求的URL换成其它的URL;

例如:
用户请求的是http://server2/hello.html
被匹配到第二个srever上,其中location中如果第一条rewrite指令,指明了把hello.html指向了hi.html;则返回给客户端去请求http://server2/hi.html,而后客户端要重新再次发请求,依然自上而下去匹配属于哪个server、哪个location;如果hi.html被第三location匹配则被location中的指令处理;

如果用户请求是http://server2/images/1.jpg,匹配第二个location中有两条规则是:
(.*)\.jpg$ --> $1.html;
(.*)\.html$ --> $1.jpg;
这样就出现了循环重写;

所以,写的规则次序很重要:第一,根据用户请求的主机名来判断是哪个server;确定server后,根据location完成搜索,根据location中的重写规则完成重写,重写后,返回客户端一个新的URL,客户端再次发请求;如果中间出现循环最大循环10此;

URL重写可实现跨server,例如请求http://server2/images/1.jpg,改写为http://images/$1.html,这个images可能是其它虚拟主机,甚至还可能是另一台物理服务器;
所有URL重写,可在一个主机上的一个server内只把URL部分重写,但有时可以把server重写,实现镜像服务器;把里面的服务器地址改了,但是URL没改;
URL重写可把对应动态资源的请求转换为静态的URL地址;
因此,这个结果可被搜索引擎收录,还可被缓存服务器缓存;可理解为把动态资源静态化的效果;
如果用户访问的php动态资源,很多时候缓存服务器是不缓存这个结果的,但是如果动态资源生成的结果不会再变化可以缓存服务器缓存下来时(静态的存下来),可以给静态URL;这种机制可在nginx的rewrite功能来实现;

但用到正则式就要启动正则表达式引擎,这样会消耗更多资源;因此,尽量不使用;

1、rewrit regex replacement[flag];
用于实现重写操作;
把用户请求的URI基于regex做检查,匹配到时,这个URI将替换为replacement指定的字符串;
在同一location中存在多个rewrite规则会自上而下逐个被检查(循环);可使用flag控制此循环功能;
如果replacement是以http://或https://开头,则替换结果会直接以重定向方式返回给客户端;

查找时可使用模式,替换为的内容不能使用模式,但可使用后向引用,在nginx中不使用\1,是使用$1来表示引用;

如果一个替换为的字符串是以http://或https://开头,处理立即停止,不再检查后面的其它规则,替换结果会直接以重定向方式返回给客户端;
如果不是以http://或https://开头,将会按次序,依次读取规则,所有规则都处理完成后,把最终结果返回客户端,而不是被某条规则重写后立即返回客户端;
rewrit指令的执行次序,就是写明的次序,可使用flag中的break退出循环,

例如:重写规则顺序
1 1.txt --> 1.html
2 1.html --> 1.jpg
如果用户请求都是1.txt最终返回给用户的1.jpg;

例如:出现重写循环
(.*)\.jpg$ --> $1.html;
(.*)\.html$ --> $1.jpg;
用户请求a.jpg时,第一次请求被转换为a.html,第二次被转换为a.jpg如此循环;在内部是自上而下逐条处理的;如果想改变默认循环,则要使用break;

假如一个location中有3条rewrite规则,
1 ... last或break
2 ...
3 ...
如果被第一条有last匹配了,意味着新的URI会重新做一次请求,nginx会在内部自动重新检查,如果又被这个location匹配,还会再检查一遍;最终将资源加载后返回给客户端;
如果被第一条有break匹配了,rewrite停止在第一条中的新URI上,意味着不再被执行重写指令即跳出循环,nginx会在内部而继续执行此location内的其它指令;最终将资源加载后返回给客户端;
last和break都是nginx自动的在内部进行后续处理;
如果第一条有redirect匹配,直接将新URL返回给客户端,浏览器自动对新URL发请求,这个新URL有可能还是本机中location,再解析匹配检查,所以,redirect直接返回的不是资源,而是一个新的URL;

但redirect和permanent,表示当用户请求的URL被重定向时,直接返回用户新的URL,让用户自己重新请求,只不过这两者的区别为,redirect是临时重定向,permanent是永久重定向;

[flag]: 标志位,用来查找替换工作过程

  • last:重写完成后,停止对当前URI在当前location中的后续其它重写操作,改为对新URI的新一轮处理;类似于提前结束本轮循环,进入下一轮;理解为continue;重新匹配可能匹配到其它location中;

  • break:重写完成后,停止对当前URI在当前location中的后续其它重写操作;

  • redirect:重写完成后以临时重定向方式直接返回重写后生成的新URL给客户端,由客户端对新URL进行请求;(重定向响应码302)

  • permanent:重写完成后以永久重定向方式直接返回重写后生成的新URL给客户端,由客户端对新URL进行请求;(重定向响应码301)

例如:

[root@VM_0_2_centos ~]# vim /usr/local/nginx/html/test.html

TEST.html

[root@VM_0_2_centos ~]# vim /etc/nginx/nginx.conf 添加:break location / { root html; index index.html index.htm; rewrite (.*)\.txt$ $1.html break; }

览器输入:www1.stu11.com/test.txt
此时,响应码为200;

如果把break改为redirect,
浏览器输入:www1.stu11.com/test.txt
此时,响应码为302;
浏览器地址被改为了:www1.stu11.com/test.html;

如果改为permanent;
浏览器输入:www1.stu11.com/test.txt
此时,响应码为301;
浏览器地址被改为了:www1.stu11.com/test.html;

例如:

[root@VM_0_2_centos ~]# vim /etc/nginx/nginx.conf
添加:循环重定向中,添加break;
location / {
            root   html;
            index  index.html index.htm;
            rewrite (.*)\.txt$ $1.html break;
        }

location ~* \.html {
            root   html;
            index  index.html index.htm;
            rewrite (.*)\.html$ $1.txt break;
        }

2、rewrite_log on | off;
是否启用重写日志;启用时,日志信息被发往错误日志;

3、if(condition){...}
条件判断机制,在条件满足时,执行配置块中的配置;
引入了一个新的配置上下文;通常对nginx的变量做判断;

condition 条件比较表达式:

模式
==,!= 等值比较和不等值比较
~ 模式匹配,左侧字符串是否能被右侧模式匹配,区分字母大小写
~* 模式匹配,左侧字符串是否能被右侧模式匹配,不区分字符大小写
!~ 模式不匹配,左侧字符串是否不能被右侧模式匹配,区分字符大小写
!~* 模式不匹配,左侧字符串是否不能被右侧模式匹配,不区分字符大小写

文件及目录存在性判断:

模式
-f|!-f 存在且类型为文件,叹号表示取反
-d|!d 判断为目录
-e|!-e 判断存在
-x|!-x 判断执行权限

例如:

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

表示:判断用户的浏览器是否能被MSIE匹配,$http_user_agent是其它模块引入的变量;无论请求的是什么,都转换为msie目录下,且为break;

if ($http_cookie ~* "id=([^;]+)(?:;|$)") {
    set $id $1;
}

表示:$http_cookie模块引入的变量,表示请求报文中的cookie首部的值,做模式匹配,不区分大小写,设定id变量的值为第一个分号出现之前的所有内容;如果用户请求报文中没有cookie,则设定id变量不会执行;

if ($request_method = POST) {
    return 405;
}

表示:如果用户使用的方法是POST,则拒绝用户使用此方法(提交表单);

if ($invalid_referer) {
    return 403;
}

表示:定义非法请求变量,如果是非法请求,则拒绝响应,定义在状态码为403;

可在ngx_http_core_module模块中,查看定义的变量;$remote_addr、$remote_port、$remote_user、$request_uri、$uri等等;

例如:

[root@VM_0_2_centos ~]# vim /etc/nginx/nginx.conf
添加:
if ($uri ~* .*admin.*) {
    return 403;
}
请求资源中包含admin字符串,就拒绝;还可使用deny、allow定义;
[root@VM_0_2_centos ~]# nginx -t
[root@VM_0_2_centos ~]# nginx -s reload
[root@VM_0_2_centos ~]# vim /usr/local/nginx/html/admin.html
admin

浏览器输入:www1.stu11.com/admin.html
显示403 Forbidden;

4、return:停止处理,直接用返回响应码给客户端;可以直接指定响应码的同时,指明一个重定向的目标URL,或者直接指明响应报文的body部分;
return code [text]; 只返回响应状态码+一个文本
return code URL; 返回响应状态码+一个URL
return URL; 只返回一个URL

例如:

[root@VM_0_2_centos ~]# vim /etc/nginx/nginx.conf
添加:
if ($uri ~* .*admin,*) {
    return 403 "go away";
}

浏览器输入:www1.stu11.com/admin.html
显示:go away,响应码还是403;

5、set$variable value;
用户自定义变量;在nginx中变量无论在定义还是引用都要使用$符号;

ngx_http_gzip_module模块

过滤器,对指定类型的资源压缩传输以节约带宽;但消耗了cpu资源;
1、gzip on|off;
是否启用gzip压缩响应报文;不是所有浏览器都支持压缩机制;

2、gzip_comp_level level;
指定压缩比,1-9,默认为1;数越大压缩比越大;

3、gzip_disable regex ...;
regex是匹配客户端浏览器类型的模式,表示对所有匹配到的浏览器不执行压缩响应;因为有些浏览器类型不支持压缩;

4、gzip_min_length length;
触发启用压缩功能的响应报文的最小长度;

5、gzip_types mime-type ...;
压缩过滤器,指定仅执行压缩的资源内容类型;默认为text/html;

6、gzip_buffers number size;
支持实现压缩功能时为其配置的缓冲区数量及每个缓存区的大小;

7、gzip_proxied off | expired | no-cache | no-store | private | no_last_modified | no_etag | auth | any ...;
nginx作为代理服务器接收到从被代理服务器发送的响应报文后,在任何条件下启用压缩功能的;

  • off:对代理的请求不启用
  • expired:如果响应报文首部包含expired字段并有值,其值即是有有效期的但过期了,因为禁用了缓存机制,则启用压缩;
  • no-cache,no-store,private:表示从被代理服务器收到的响应报文首部的Cache-Control的值为此三者中任何一个,则启用压缩功能

示例:

gzip on;
gzip_http_version 1.0;
gzip_comp_level 6;
gzip_disables msle6;
gzip_min_length 2;
gzip_type text/plain text/css text/xml applicatin/x-javascript application/xml application/json application/java-script;

例如:

[root@VM_0_2_centos ~]# vim /etc/nginx/nginx.conf
开启:gzip功能;
[root@VM_0_2_centos ~]# cp /var/log/messages /usr/local/nginx/html/messages.html
[root@VM_0_2_centos ~]# chmod 644 /usr/local/nginx/html/messages.html

浏览器输入:https://www1.stu11.com/messages.html
按F12,打开开发代码窗口,查看Network栏里的Headers选项卡中Response Headers可见为gizp;

你可能感兴趣的:(Nginx架构详解)