Nginx 详细介绍以及常用模块使用

本贴最后更新于 1935 天前,其中的信息可能已经天翻地覆

Nginx 介绍

Nginx 简介与特性

  • Nginx 全称:engine X

  • 国内流行的 Nginx 分支:
    淘宝:Tengine---支持模块化动态装卸载
    Registry---陌陌在使用

  • Nginx 使用时调用以下库:
    libevent:高性能的网络库

Nginx 架构

image.png

Nginx 是 Master/Worker 架构

  • Master:主控进程;实现装载配置、平滑升级、管理 worker 进程

  • Worker:通过模块以流水线式方式完成各项功能处理

  • 通过 epoll 机制实现单个 worker 进程并发响应多个客户请求

  • 磁盘 IO:基于内核直接构建响应报文
    AIO:异步 IO
    mmap etc:内存映射

  • 网络 IO:第一节段实现异步 IO(非阻塞),第二阶段还是阻塞

Nginx 的特性

1、模块化设计、较好的扩展性
2、高可靠
  Nginx的组成:
     一个主控进程:master(主进程负责生成多个子进程worker)
	主控进程负责分析解析配置文件并启动子进程
	主要完成以下工作:读取并验证配置,绑定或创建套接字,以及启动终结维护子进程的个数,无需重启重载配置文件,平滑升级
      多个子进程:worker
	  负责响应用户请求
3、低内存消耗
	一个线程响应多个请求
4、热部署
	不停机更新配置文件、日志文件滚动、升级程序版本
5、支持事件驱动机制、支持异步AIO、支持内存映射机制(mmap)

Nginx 的基本功能

1、静态资源web服务器,能够缓存打开的文件描述符
2、http、smtp、pop3支持这三种协议的反向代理服务器
      反向代理服务器:建立在80端口上,但是不提供内容,代理进程解析判断客户端是否可以访问后端web服务器,如果可以访问,代理服务器将用户请求改为封装为另一个样子提交给web服务器;如果不允许则拒绝
3、缓存加速(在反向代理时实现)、负载均衡
4、支持FastCGI(fpm,LNMP);uWSGI协议(Pyhton)等
5、支持模块化(非DSO机制)、过滤器zip、SSI及图像的大小调整
6、支持SSL,从而实现https服务

Nginx 扩展功能

基于名称和 IP 的虚拟主机
支持 keepalived
支持平滑升级
定制访问日志、支持使用日志缓存区提供日志存储性能
支持路径别名
支持 url rewrite
支持基于 IP 及用户的访问控制
支持速度限制,支持并发数限制

Nginx 基本架构特性

一个 master 进程生成一个或多个 worker 进程
支持事件驱动:Linux 调用 epoll(边缘触发)、bs 调用 kqueue、server 调用/dev/poll
复用器:select,poll,rt signal
支持 sendfile,sedfile64
支持 AIO
支持 mmap

Nginx 工作模式

非阻塞、事件驱动、由一个 master 进程生成多个 worker 进程,每个 worker 响应 n 个请求

Nginx 模块类型

1、核心模块

2、标准的http协议模块

3、可选的http协议模块
4、邮件模块
5、第三发模块(编译Nginx时指定模块在何处,手动指定模块文件)

Nginx 安装方法

Nginx 没有收录到系统,但是收录到 epel 源中了

  • 方式 1、yum 安装

  • 方式 2、源码安装:编译安装

编译安装:
[root@localhost ~]# yum groupinstall "Development Tools" "Server Platform Development"
[root@localhost ~]# yum install pcre-devel openssl-devel zlib-devel
[root@localhost ~]# useradd -r nginx		//-r指定为系统用户
[root@localhost ~]# ./configure --prefix=/usr/local/nginx --conf-path=/usr/local/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 --lock-path=/var/run/nginx.lock --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-http_dav_module --with-http_stub_status_module --with-threads --with-file-aio
[root@localhost ~]# make && make install
  • 方式 3、制作好的程序包:rpm 包

Nginx 配置文件结构

  • main block:主配置段,也即全局配置段;主要配置 Nginx 进程的特性
	events {	>>>事件驱动相关的配置
	 	...
   	   	worker_connections  1024;
	}

http {	>>>http/https协议的相关的配置段;web在此段配置
	...
}

stream {	>>>四层反向代理配置段
	...
}

  • http 协议相关的配置结构
http {
	...   >>>各server段中要使用到的公共配置
	server {	>>>单个server段,即为一个虚拟主机
           listen     80; >>>监听的地址和端口,可监听端口\地址\主机名
           server_name  域名;
	     root   代码存放路径;
           location / URL {	>>>定义对某一个URL的访问特性
            	index  index.php index.html index.htm;
           }
	}
}

Nginx 配置文件以及模块使用

主配值段的指令

  • 正常运行的必备配置:
1、user USERNAME [GROUPNAME]    >>>指定运行worker进程的用户和组
2、pid /path/to/pid_file  >>>指定Nginx守护进程的pid文件
3、worker_rlimit_nofile  >>>指定一个worker进程所能打开的最大文件句柄数(文件数量)
  • 性能优化相关的配置:放在主配置段下
worker_processes 数字;

    所能够打开worker进程的个数;通常少于cpu物理核心数

worker_cpu_affinity auto [cpumask];
    优点:能够提升cpu的缓存命中率 
    cpumask:cpu掩码(每一颗CPU用8位二进制表示)
			0000 0000	
			0000 0001	第一颗CPU	
			0000 0010	第二颗CPU
        	 	0000 0100	第三颗CPU
	注意:1在哪个位就代表第几颗cpu  0011表示第一颗和第二颗
   	context switch:会产生cpu不必要的消耗

timer_resolution;
  	计时器解析度:降低此值,可减少gettimeofday()系统调用的次数

worker_priority number;
	指明worker进程的nice值设定worker进程优先级,优先调度使用CPU;
	nice值范围:-20到19   默认值为0对应120
 
	-20对应100 
	19对应139

worker_rlimit_nofile number;
	单个worker进程可以打开的文件数量上限;一个文件打开就需要维持1个套接字文件;注意:该值的设置必须大于等于worker_processes和worker_connections的乘级
[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conf

image.png

worker_connections 值;
	设定单个worker进程所能够处理的最大并发连接数量worker_connections 乘以 worker_processes

  • 用户用于调试、定位问题:
deamon {on | off}
	是否以守护进程方式运行Nginx

master_process {on | off}
	是否以master/worker模型来运行nginx;默认为on;调试时设置为off;适用于二次开发

error_log_file [level]
	指明日志文件,并指明level
	事件相关的配置:放在events段

accept_mutex {off | on};
	master调用用户请求至各worker进程时使用的负载均衡锁;
	on表示能让多个worker轮流地、序列化地去响应新请求;【起点公平】
	off表示每个新请求的到达都会通知所有worker进程,谁抢到谁处理【结果公平】

lock_file file;
	accept_mutex用到的锁文件路径

use [epoll | rtsig  | select | poll]
	指明使用的事件模型;建议让Nginx自行选择

worker_connections 值;
	设定单个worker进程所能够处理的最大并发连接数量worker_connections 乘以 
worker_processes

  • 核心模块 ngx_http_core_module
    http{ }:由 ngx_http_core_module 模块所引入,像 httpd 一样静态 web 服务器
配置框架:
	http {
	upstream {		>>>负载均衡;反向代理
	}
	server {
	location URL {
	root   "本地文件系统路径"
	} //类似于httpd中的<Location>,用于定义URL与本地文件系统的映射关系,一个server中可以有多个location
	location URL {
	 if ... {	>>>条件判断功能
		  ....
	}
	}
	} //每个server段类似于httpd中的虚拟主机<VirtualHost>;
	}

#注意:与http相关的指令仅能够放置于httpd、server、location、upstream、if上下文,但有些指令仅应用于这5种上下文中的某些种
一个http段中可以有多个server段,每个server段中可以有多个location段
2个server不能使用同一个套接字

#注意:在http段下可以引用外部的配置文件,操作如下

image.png

配置参数:
1、定义一个虚拟主机: //在http段下添加一个server段
server {
	listem 端口号;
	server_name 网站名称;
	root  web网页存放路径;
		location / {
            index  index.html index.htm;
         }
 }

2、listen:指定监听的地址和端口
设置IP的地址和端口,或服务器将在其上接受请求的unix域套接字的路径。地址和端口都可以指定,或者只能指定地址或端口。例如,地址也可以是主机名
 listen 网址[:端口号];或者listen 端口号;

示例:
   listen 127.0.0.1:8000;
   listen 127.0.0.1;
   listen 8000;
   listen *:8000;
   listen localhost:8000;

3、server_name 主机名称 ...;
指明虚拟主机的主机名称;后可跟多个由空白字符分隔的字符串

支持通配符*匹配任意长度的任意字符,例如: server_name  *.baidu.com   www.baidu.*

支持~起始的字符做正则表达式模式匹配,例如: server_name  ~^www\d+\.baidu\.com$

\d+:相当于数字0-9或[0-9]; +号表示至少匹配一个字符
\. :匹配点本身的,点表示匹配任意单个字符
$:表示以此符号前的字符结尾的

匹配机制优先级:
(1)字符串精确匹配
(2)左侧*号通配符匹配
(3)右侧*号通配符匹配
(4)正则表达式匹配

4、tcp_nodelay    {on | off};   //添加在http段中
仅对保持连接的http有效
 

5、tcp_nopush     {on | off};
只有当sendfile为on时有用(上图中的sendfile)
作用:
	在Linux和FreeBSD 4上,在一个数据包中发送响应头和文件的开头*;
	以完整数据包发送文件

6、keepalive_timeout  65;
保持连接的超时时间

7、keepalive_requests number;
在保持连接的超时时间内(keepalive_timeout)可以访问多少个资源;如果超过该设置的值,即便没有超过保持连接设置的超时时间也会断开连接

8、types_hash_max_size 值;
设定保存类型的哈希表的最大值;默认值为1024
types_hash_max_size影响散列表的冲突率。

types_hash_max_size越大,就会消耗更多的内存,但散列key的冲突率会降低,检索速度就更快。
types_hash_max_size越小,消耗的内存就越小,但散列key的冲突率可能上升。

image.png

  • 定义路径的相关配置
1、root  网站路径;
默认值: root     html;

设置web资源路径映射,用于指明用户请求的url所对应的本地文件系统上的文档所在目录路径

可定义的段: http段, server段, location段, if in location


2、location [ = | ~ | ~* | ^~ ] uri { ... }
    location @name { ... }

根据请求的uri做请求响应的访问限制

=:对URI做精确匹配;

例如:www.baidu.com/   www.baidu.com/index.html

location = / {	>>>那么上面的2地址则会匹配到第一个
   ...
}

~:对URI做正则表达式模式匹配,区分字符大小写
~*:对URI做正则表达式模式匹配,不区分字符大小写
^~:对URI的左半部分做匹配检查,不区分字符大小写
不带符号:默认只有 / 匹配起始于此URI的所有URI

匹配优先级:
    =, ^~, ~与~*, 不带符号

可定义的上下文范围: server段, location段
  • 定义客户端请求的相关配置
以下参数可以定义的上下文段为: http, server, location

keepalive_timeout 75;
	设定保持连接的超时时间;0表示禁止长连接,默认值为75s

keepalive_disable none | browser ...;
	对哪种浏览器禁用长连接		

keepalive_requests 数值;
	在长连接超时时间内所允许请求资源的最大数量,默认值为100

send_timeout time;
	向客户端发送响应报文的超时时长,此处是指两次写操作之间的间隔时长

client_body_buffer_size size;
	用于接收客户端请求报文的body部分的缓存区大小;默认为16k;超出此大小时,其将被暂存到磁盘上的由client_body_temp_path指令指定的位置;
	只有允许客户端上传大文件时就需要进行调整该值;如果是一个电商平台只是简单的交易操作和登入操作,那么此值默认即可

client_body_temp_path path [一级 [二级 [三级]]];
	设定用与存储客户端请求报文的body部分的临时存储路径以及子目录结构和数量

加速文件查找
	对URI进行hash计算
	示例:对地址做md5sum校验
	[dqz@localhost ~]$ echo www.baidu.com | md5sum 
	ed6322bc931d5aba9cc72b63f0f03a82  -
	
16进制的数字:
	示例:client_body_temp_path /var/tmp/client_body 2 1 1
	 1:表示用一位16进制的数字表示一级子目录;0-f     256个一级目录
 	2:表示用2位16进制的数字表示二级子目录;00-ff   256x16=4096 二级目录
 	2:表示用2位16进制的数字表示三级子目录;00-ff   256x16x16=65536三级

  • 对客户端进行限制的配置
limit_rate rate;
	
限制响应客户端的传输速率,单位为bytes/second,默认值0表示无限制;
	可以定义的上下文段为:http, server, location, if in location

limit_except method ... { ... }
	限制对指定的请求方法之外,使用其他方法的客户端

 	示例
	limit_except GET {
   	 	allow 192.168.1.0/32;
    		deny  all;
	}
	可以定义的上下文段为:location
  • 文件操作优化的配置
以下参数可以定义的上下文段为:http, server, location

aio on | off | threads[=pool];
	是否开启aio功能;极大优化系统访问时被阻塞在IO

directio size | off;
	在Linux主机启动O_DIRECT标记,此处意味文件大于等于给定的大小时使用,例如dlrectio 4m;

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

	max=N:可缓存的缓存项上限;达到上限后会使用LRU算法实现缓存管理
	inactive=time:缓存项的非活动时长,在此处指定的时长内未被命中或命中的次数少于open_file_cache_min_uses命令指定的次数的缓存项即为非活动项


open_file_cache_valid time;
	缓存项有效性的检查频率;默认为60s

open_file_cache_min_uses number;
	在open_file_cache指令的inactive参数指定的时长内,至少应该被命中多少次方可被归类为活动项

open_file_cache_error on | off;
	是否缓存查找时发生错误的文件等一类信息

访问控制模块

(1)基于 IP 访问限制 ngx_http_access_module

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

按顺序检查规则,直到找到第一个匹配项。在此示例中,仅允许IPv4网络访问 10.1.1.0/16并且192.168.1.0/24 不包括地址192.168.1.1,以及IPv6网络2001:0db8::/32。如果有很多规则, 最好使用 ngx_http_geo_module模块变量。


可定义的上文段位:http,server,location,limit_except

允许访问指定的网络或地址。如果unix:指定了特殊值(1.5.1),则允许访问所有UNIX域套接字
句法:	allow address | CIDR | unix: | all;

拒绝访问指定的网络或地址。如果unix:指定了特殊值(1.5.1),则拒绝所有UNIX域套接字的访问
句法:deny address | CIDR | unix: | all;

(2)基于用户的访问控制 ngx_http_auth_basic_module

示例:
location / {
    auth_basic           "提示信息";	  //弹出提示信息
    auth_basic_user_file  密码文件路径;  //账号密码文件
}

账号密码文件创建:
使用命令htpasswd;该命令由httpd-tools提供
语法:htpasswd [-cmdpsD]  密码文件名  用户名
[root@localhost ~]# yum -y install httpd-tools
[root@localhost ~]# htpasswd -c -m /usr/local/nginx/ngxpasswd dqz
New password: //设置密码
Re-type new password: //再次确认密码
Adding password for user dqz
 

参数详解:
-c:创建密码文件
-m:使用md5加密(默认)

#nginx配置文件更改
[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conf
 
[root@localhost ~]# nginx -t
[root@localhost ~]# nginx -s reload
[root@localhost ~]# mkdir /web/vhost1/admin/
[root@localhost ~]# vim /web/vhost1/admin/index.html

浏览器进行访问测试:

image.png

输入账号密码
 

image.png

状态页模块 ngx_http_stub_status_module

用于输出 nginx 的基本状态信息

进行源码编译安装时需要带上该模块,如下所示
]# ./configure --prefix=/usr/local/nginx --with-http_stub_status_module

配置示例:
location = /basic_status {
    stub_status;
}

浏览器访问:

image.png

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

#通过awk取指定值
[root@localhost ~]# curl --silent 192.168.66.51/ngxstatus | awk '/^Active/{print $3}'

日志管理模块 ngx_http_log_module

定义日志格式
log_format name string..

access_log path [format [buffer=size] [gzip[=level]] [flush=time] [if=condition]];

访问日志文件路径,格式及相关的缓冲的配置;
	buffer=size
	flush=time
	access_log off;	//关闭

	可配置的段: http, server, location, if in location, limit_except

open_log_file_cache max=N [inactive=time] [min_uses=N] [valid=time];					
open_log_file_cache off;
	缓存各日志文件相关的元数据信息;
	max:缓存的最大文件描述符数量;
	min_uses:在inactive指定的时长内访问大于等于此值方可被当作活动项;
	inactive:非活动时长;
	valid:验正缓存中各缓存项是否为活动项的时间间隔;

压缩传输模块 ngx_http_gzip_module
	gzip on | off;
	开启/关闭

	默认值为off

	可配置的段: http, server, location, if in location

	
gzip_comp_level level;
	压缩节点
	默认值1;范围1-9
	可配置的段:http, server, location

gzip_disable regex ...;
	禁止压缩功能
	可配置的段: http, server, location

gzip_buffers number size;
	支持实现压缩功能时为其配置的缓冲区数量及每个缓存区的大小;
	默认值:gzip_buffers 32 4k|16 8k;
	可配置的段:http, server, location

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

	no-cache, no-store,private:表示从被代理服务器收到的响应报文首部的Cache-Control的值为此三者中任何一个,则启用压缩功能;

gzip_types mime-type ...;
	压缩过滤器,仅对此处设定的MIME类型的内容启用压缩功能;
	默认值: gzip_types text/html;
	可配置的段: http, server, location

#示例:
	gzip  on;
	gzip_comp_level 6;
	gzip_min_length 64;
	gzip_proxied any;
	gzip_types text/xml text/css  application/javascript;

Nginx 作为 https 服务器

ngx_http_ssl_module
默认情况下不构建此模块,应使用--with-http_ssl_module 配置参数启用它

ssl on | off;
	定义ssl引擎,开启

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

ssl_certificate_key file;
	当前虚拟主机上与其证书匹配的私钥文件;

ssl_protocols [SSLv2] [SSLv3] [TLSv1] [TLSv1.1] [TLSv1.2];
	支持ssl协议版本,默认为后三个;
						
ssl_session_cache off | none | [builtin[:size]] [shared:name:size];
	builtin[:size]:使用OpenSSL内建的缓存,此缓存为每worker进程私有;
						
[shared:name:size]:在各worker之间使用一个共享的缓存;
						
ssl_session_timeout time;
	客户端一侧的连接可以复用ssl session cache中缓存 的ssl参数的有效时长;
						
#配置示例:
server {
	listen 443 ssl;
	server_name www.geekdqz.com;
	root /vhosts/ssl/htdocs;
	ssl on;
	ssl_certificate /etc/nginx/ssl/nginx.crt;
	ssl_certificate_key /etc/nginx/ssl/nginx.key;
	ssl_session_cache shared:sslcache:20m;
}

#操作步骤:
1、先建立一个CA服务器【node1服务器做CA服务器】
[root@localhost ~]# cd /etc/pki/CA/
[root@localhost CA]# ls
certs  crl  newcerts  private

#创建私钥
[root@localhost CA]# (umask 077;openssl genrsa -out private/cakey.pem 2048)
 

[root@localhost CA]# ll private/
 

#建立自签证书
[root@localhost CA]# openssl req -new -x509 -key private/cakey.pem -out cacert.pem -days 365

You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN		//国家
State or Province Name (full name) []:shenzhen	//省份
Locality Name (eg, city) [Default City]:shenzhen	   //城市
Organization Name (eg, company) [Default Company Ltd]:geekdqz   //公司
Organizational Unit Name (eg, section) []:devops     //部门
Common Name (eg, your name or your server's hostname) []:web.geekdqz.com	//服务器主机名
Email Address []:

[root@localhost CA]# touch index.txt
[root@localhost CA]# echo 01 > serial
 

2、nginx服务器创建私钥
[root@nginx-web ~]# mkdir /etc/nginx/ssl
[root@nginx-web ~]# cd /etc/nginx/ssl/
[root@nginx-web ssl]# (umask 077;openssl genrsa -out nginx.key 2048)
 
 

#制作CA请求文件
[root@nginx-web ssl]# openssl req -new -key nginx.key -out nginx.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:shengzhen
Locality Name (eg, city) [Default City]:shengzhen
Organization Name (eg, company) [Default Company Ltd]:geekdqz
Organizational Unit Name (eg, section) []:devops
Common Name (eg, your name or your server's hostname) []:www.geekdqz.com 	//注意需要跟CA服务器的域名一样,不然无法访问
Email Address []:dqzboy@163.com

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

#拷贝证书请求文件至CA服务器
[root@nginx-web ssl]# scp nginx.csr root@192.168.66.50:/etc/pki/CA/

3、CA服务器进行签署
[root@localhost CA]# openssl ca -in nginx.csr -out /etc/pki/CA/certs/nginx.crt -days 365

Certificate is to be certified until May 11 07:19:27 2020 GMT (365 days)
Sign the certificate? [y/n]:y

1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated

#拷贝签署的CSR文件到nginx服务器
[root@localhost CA]# scp certs/nginx.crt root@192.168.66.51:/etc/nginx/ssl

[root@nginx-web ]# vim /etc/nginx/nginx.conf
       listen       443  ssl;
       server_name  www.geekdqz.com;  
	 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:SSL:10m;
 

[root@nginx-web ]# nginx -t 
[root@nginx-web ]# nginx -s reload

#浏览器访问:
https://www.geekdqz.com

域名重定向模块 ngx_http_rewrite_module

将源网站重定向至新的网站域名

可定义的段:server,location,if
语法格式:
	rewrite 匹配规则  重定向的位置;	//匹配规则正则支持正则,重定向不支持正则的写法

配置示例:
server {
        listen     80; 
        server_name  www.geekdqz.com;
        rewrite /(.*)\.png$     /$1.jpg;	//所有匹配到.png结尾的都重定向至.jpg(重定向的域名或文件必须存在不然返回404); $1表示前面(.*)所匹配到的内容改为 .jpg结尾的 
        #charset koi8-r;
        #access_log  logs/host.access.log  main;
        root   /web/vhost1;
        location / { 
            index  index.html index.htm;
        }   
    
        location ~* \.(jpg|png)$ {
                allow all;
        }   

浏览器访问测试:

image.png

四个 rewrite 标志位
rewrite 匹配规则	重定向至  last;
多个规则会以上向下进行匹配;当用户请求URI后,如果该配置段中有多个rewrite,第一次URI匹配到某一条rewrite那么重写为新的URI,如果重写后的URI可以被该段中其他rewrite匹配到那么重新再次匹配所有的rewrite

nginx内部有一个机制,如果URI连续改了10次还在写,那么Nginx则返回内部错误,避免发生死循环

  • rewrite 匹配规则 重定向至 break;
    多个 rewrite 中匹配到某一条规则后就直接执行下面的操作

  • rewrite 匹配规则 重定向至 redirect;
    redirect 为临时重定向,给客户端发送 302 状态码,然后告诉客户端新的 URI 再次进行访问=

image.png
image.png
image.png

  • rewrite 匹配规则 重定向至 permanent;
    永久重定向
    image.png
    image.png

Nginx 反向代理

ngx_http_proxy_module模块:
	server {
	listen 端口;
	location / {
    proxy_pass http://192.168.x.x:80;
}
	}

面向服务:实现反代
	1、http
	2、FastCGI
	3、memcache
	4、每个协议都有专用的协议客户端
 

Nginx的优势在于反向代理
httpd既能做正向也能做反向

代理模块 ngx_http_proxy_module
1、proxy_pass uri;
设置代理服务器的协议和地址,以及应将位置映射到其上的可选URI。作为协议,可以指定http或https。地址可以指定为域名或IP地址,以及一个可选端口。

可定义的段: location, if in location, limit_except

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

 

注意1: 如果proxy_pass后面的路径没有带URI的话,访问时就会将location的URI传递给后端服务器

server {
	listen 80;
	server_name HOSTNAME;
	location /uri/ {
		proxy_pass http://hos[:port];
	}
}

访问http://HOSTNAME/uri --> http://host/uri

#示例:192.168.66.50为nginx反向代理服务器;192.168.66.51为httpd服务器;
#修改配置文件location添加URI
 
#后端httpd服务器添加此处指定的URI路径[web]
[root@nginx-web conf]# cd /var/www/html	//注意此处为httpd默认网页存储路径
[root@nginx-web html]# mkdir web
[root@nginx-web html]# cd web/
[root@nginx-web web]# vim index.html
[root@nginx-web web]# cat index.html 
this is http server

浏览器进行访问:http://www.ilinux.com/web

image.png

注意2: proxy_pass后面的路径是一个uri时,其会将location的uri替换为proxy_pass的uri;
					
server {
	...
	server_name HOSTNAME;
	location /uri/ {
		proxy_pass http://host/new_uri/;
	}
	...
}
					
http://HOSTNAME/uri/ --> http://host/new_uri/

#示例:修改反代服务器Nginx配置文件
 
#浏览器进行访问:http://www.ilinux.com/web
 

注意3:如果location定义其uri时使用了正则表达式的模式,或在if语句或limt_execept中使用proxy_pass指令,则proxy_pass之后必须不能使用uri; 用户请求时传递的uri将直接附加代理到的服务的之后;
server {
	...
	server_name HOSTNAME;
	location ~|~* /uri/ {
	proxy_pass http://host;
	}
	...
}
					
访问http://HOSTNAME/uri/ --> http://host/uri/;

2、proxy_set_header field value;
设定发往后端主机的请求报文的请求首部的值;
客户端向服务端发送的请求报文

可设定的段:	http, server, location
#示例:
修改代理服务器Nginx的配置文件
[root@nginx-proxy ~]# vim /usr/local/nginx/conf.d/web.conf
添加proxy_set_header模块,定义首部记录格式名称
 
X-Real-IP: 为自定义的首部定义名称
$remote_addr: 此为nginx内建变量,该变量记录的为客户端地址

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

#修改后端服务器httpd配置文件
[root@httpd-web ~]# vim /etc/httpd/conf/httpd.conf
将默认的LogFormat记录格式注释掉,然后复制一行将默认首部记录格式 %h 改为代理服务器nginx配置文件中(上图)所定义的X-Real-IP的名称
 
[root@httpd-web ~]# httpd -t		//检查配置文件
[root@httpd-web ~]# systemctl restart httpd

#查看后端服务器httpd的访问日志
 
记录的是真正访问的服务端的客户端的IP地址,而不再记录的是代理服务器的地址
3、ngx_http_headers_module 模块

向由代理服务器响应给客户端的响应报文添加自定义首部,或修改指定首部的值;

服务端向客户端发送自己的响应报文

(1)add_header name value [always];
添加自定义首部;

add_header X-Via  $server_addr;		//X-Via可自定义名称
add_header X-Accel $server_name;

#示例:
配置代理服务器Nginx配置文件
[root@nginx-proxy ~]# vim /usr/local/nginx/conf.d/web.conf 
 
[root@nginx-proxy ~]# nginx -t
[root@nginx-proxy ~]# nginx -s reload

浏览器访问网站并 F12 打开调试页面查看

image.png

(2) expires [modified] time;
	expires epoch | max | off;
				
	用于定义Expire或Cache-Control首部的值;
4、缓存模块 proxy_cache_path

代理服务器可实现在本地启用缓存功能;由后端服务器取得的内容缓存下来,基于本地磁盘响应给客户端请求

架构

image.png

访问请求多的时候,网络I/O比磁盘I/O更慢

缓存的存储方式:
	1、放在内存的哈希表
	2、磁盘的目录结构

开启缓存
	注意: 缓存空间需要先定义,再在location中调用
	proxy_cache zone | off;
	可定义的配置段: http, server, location

浏览器可使用shift+f5强制刷新,不加shift,请求则可以从缓存中获取内容响应客户端,加shift则不能使用缓存中获取内容响应给客户端

注意:nginxh将缓存都缓存在了磁盘中,基于hash方式;Nginx在用户访问连接上更加高效

定义缓存
在http段中进行定义;默认10分钟清理缓存(非活动时间)

官方配置: 
Syntax: 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];


[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conf
http {
....
	proxy_cache_path /usr/local/nginx/cache levels=1:1:1 keys_zone=pcache:10m m    ax_size=2g;
...
	server {
		...
		location {
			...
		}
	}
}
 
参数解释:
proxy_cache_path    //定义缓存文件路径,需要保证缓存目录存在

levels=1:1:1   //levels指明子目录,并指明每级子目录多少字符;1表示每级子目录16个字符; 

keys_zone=名称:大小   //定义缓存名称以及内存分配多少空间保存hash表

max_size=大小;	//磁盘空间最大使用容量

[root@localhost ~]# mkdir /usr/local/nginx/cache	//创建缓存目录
[root@localhost ~]# nginx -t
[root@localhost ~]# nginx -s reload
[root@localhost ~]# ls /usr/local/nginx/cache/

#使用缓存
如果某个站点使用了代理,那么该站点下就可以使用缓存
[root@nginx-proxy ~]# vim /usr/local/nginx/conf.d/web.conf
server{
	...
	proxy_cache 缓存名称;   //此处缓存名称为keys_zone定义的名称
	proxycache_key $requesst_uri;	//定义键
	proxy_cache_valid 200 302 10m;	  //定义各类响应码可缓存的时间
	proxy_cache_use_stale  http_502;  //根据后端服务器状态进行响应
	
	
	localtion {
		...	
	}
}
 

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

#浏览器访问
http://www.ilinux.com/web/

#查看缓存目录
 
[root@nginx-proxy cache]# tree
.
└── 1	//一级子目录
└── 8	    //二级子目录
        └── 2	//三级子目录
            └── 50d3e5509ac52e81e4ecbc30ed112281
此处标黄:1表示一级子目录   8表示二级字母	2表示三级子目录

#查看缓存文件内容
 

Nginx 负载均衡

Nginx 实现 7 层负载均衡
ngx_http_upstream_module模块
可定义的段: http上下文段中

upstream name { ... }
	定义后端服务器组,会引入一个新的上下文;Context: http
			
hhtp {
....
	upstream uri {
		server ...
		erver ...
		...
	}
	server {
		listem 80;
		server_name www.ilinux.com;
		location / {
			proxy_pass http://uri
		}
	}
}
 

#计算通信的方式:单播、组播、广播
    组播:向一个组播域内的主机进行通信
#负载均衡集群:
	硬件: F5 BigIP,A10.NetScaler
	软件:
	    四层调度:lvs, Nginx(伪四层,使用stream模块nginx在1.9.0增加了stream 模块), haporxy(需工作在tcp模式下)
	    七层调度:nginx(http_upstream_module), haporxy(需工作在http模式下), httpd

#session sticky(粘性):
	会话绑定;Nginx工作在http层可通过cookie进行绑定
#session 会话集群
	通过组播(多播)的方式传给集群中与之该session服务器在同一组播域中的其他session服务器
#存储集群
	用户---获取会话---检查存储集群---获取数据---返回给用户

	存储集群解决方案:redis、Memcached;都是内存级存储,每秒事务(tps)数量50-100万个,普通X86服务器就可以实现
	   1、memcached:缓存系统,不支持持久化,宕机后所有会话都会丢失
	   2、redis:支持持久化、主从集群

负载调度算法
  • RR 轮询(默认,权重默认为 1) 一次一个的来(理论上的,实际实验可能会有间隔)

  • weight 权重(加权轮询) 权重高多分发一些 服务器硬件更好的设置权重更高一些

upstream URI {
server  ip[:port]	 weight=nember;
server  ip[:port]	 weight=nember;
...
}
 
 可在命令进行检测:
[root@localhost~ ]# for i in {1..10};do curl www.xxx.com;done
示例:

image.png

image.png

  • ip_hash 等价于 hash $remote_addr;同一个 IP,所有的访问都分发到同一个 web
服务器;只要第一次请求被绑定在后端的某台服务器,则IP地址则一直访问为同一服务器
注意:此方法不推荐;使用此方法后 同一组中的backup不可用 

image.png

image.png

  • hash
 hash $remote_addr;	//同一ip请求全部分发到同一个后端服务器

 hash $request_uri;	//把同一URI请求绑定在同一个后端服务器上



*	相关参数设置

*	max_conns    最大并发连接数(最大调度给后端服务器多少的请求)

*	max_fails=number	  健康状态检测;定义失败多少次后将该服务定义为超时,默认1次;0表示不做健康状态机制

*	fail_timeout=time	  每隔多长时间检测一次,默认超时周期时间10s

*	backup  当所有服务器都挂了之后,定义backup的服务才会上线

#官方示例:
upstream backend {
    server backend1.example.com weight=5;
    server 127.0.0.1:8080     max_fails=3  fail_timeout=30s;
    server unix:/tmp/backend3;
    server backup1.example.com  backup;
}

Nginx 实现 4 层负载均衡

ngx_stream_core_module 模块

注意:如果不提供http服务,则不需要定义在http上下文中,直接定义为stream上下文中

官方示例:
worker_processes auto;

error_log /var/log/nginx/error.log info;

events {
    worker_connections  1024;
}

stream {
    upstream backend {
        hash $remote_addr consistent;

        server backend1.example.com:12345 weight=5;
        server 127.0.0.1:12345            max_fails=3 fail_timeout=30s;
        server unix:/tmp/backend3;
    }

    upstream dns {
       server 192.168.0.1:53535;
       server dns.example.com:53;
    }

    server {
        listen 12345;
        proxy_connect_timeout 1s;
        proxy_timeout 3s;
        proxy_pass backend;
    }

    server {
        listen 127.0.0.1:53 udp reuseport;
        proxy_timeout 20s;
        proxy_pass dns;
    }

    server {
        listen [::1]:12345;
        proxy_pass unix:/tmp/stream.socket;
    }
}


实现Nginx 4层反代
   	 ngx_stream_proxy_module
 

实现Nginx4层负载均衡
	ngx_stream_upstream_module
 
Nginx 装载模块方式

1、编译安装:
前提:开发环境,包括 nginx 编译要启用的功能依赖到的开发库;

[root @nginx-proxy~]# yum groupinstall "Development Tools" "Server Platform Development"
[root @nginx-proxy~]# yum -y pcre-devel openssl-devel
			
编译过程:
	[root @nginx-proxy~]# useradd -r nginx
	[root @nginx-proxy~]# cd nginx-1.15.9
	[root @nginx-proxy~]#./configure --prefix=/usr/local/nginx --sbin-path=/usr/sbin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --user=nginx --group=nginx --with-http_ssl_module --with-http_stub_status_module --with- http_flv_module --with-http_mp4_module --with-threads --with-file-aio
	[root @nginx-proxy~]# make && make install

2、添加模块:
使用—add-module 进行重新编译,注意编译完后千万不要进行 make install,不然会被覆盖掉
[root @nginx-proxy~]# cd nginx-1.15.9
[root @nginx-proxy~]# ./configure --prefix = / usr / local / nginx --with-http_ssl_module --with-http_sub_module --with-http_gzip_static_module --with-http_stub_status_module --add-module=/data/software/ngx_http_substitutions_filter_module --add-module=/数据/软件/ngx_http_google_filter_module
[root @nginx-proxy~]# make

3、替换二进制文件:

# cp /usr/local/nginx/sbin/nginx  /usr/local/nginx/sbin/nginx.bak # cp /root/nginx-1.15.9/objs/nginx  /usr/local/nginx/sbin/
默认配置文件详解
#user  nobody;
worker_processes auto; >>>所能够打开worker进程的个数;通常少于cpu物理核心数;auto表示自动

events {	>>>配置事件驱动模型;可实现单进程响应多个进程
    worker_connections  1024;	 >>>单进程响应1024个进程;修改此参数可以增加访问并发数;当前主机一共可以并发响应的进程数为worker_processes数乘以worker_connections的乘级
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    #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;

    sendfile        on;	>>>可以提升性能
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;	>>>保持连接启用,超时时间65s

#gzip  on;
server {
        listen       80;
        server_name  localhost;
        #charset koi8-r;
        #access_log  logs/host.access.log  main;
        location / {
            root   html;
            index  index.html index.htm;
        }
	     #以下为自定义错误页
	     #error_page  404              /404.html;
        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
	}
}

  • NGINX

    NGINX 是一个高性能的 HTTP 和反向代理服务器,也是一个 IMAP/POP3/SMTP 代理服务器。 NGINX 是由 Igor Sysoev 为俄罗斯访问量第二的 Rambler.ru 站点开发的,第一个公开版本 0.1.0 发布于 2004 年 10 月 4 日。

    311 引用 • 546 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
  • visus

    “标题少个字母哟”
    “你少个男朋友唷”

  • 其他回帖
  • someone
    作者

    哈哈,真的是,感谢!

  • csfwff 1

    huaji 标题少个字母哟

    1 回复