Nginx

发布时间:2024年01月24日

一、Nginx介绍

Nginx:engine X,2002年开始开发,2004年开源,2019年3月11日,Nginx公司被F5 Networks以6.7亿美元收购。

Nginx则是免费的、开源的、高性能的HTTP和反向代理服务器、邮件代理服务器、以及TCP\UDP代理服务器 解决C10K问题(10K Connections)

Nginx官网:https://nginx.org

Nginx商业版本为Nginx Plus:https://www.nginx.com/products/nginx/

  • nginx的其他的二次发行版:

    • Tengine:由淘宝发起的Web服务器。它在Nginx的基础上,针对大访问量网站的需求,添加了很多高级功能和特性。Tengine的性能和稳定性已经在大型的网站如淘宝网,天猫商城等得到了很好的检验。它的最终目标是打造一个高效、稳定、安全、易用的web平台,从2011年12月起,Tengine成为一个开源的项目,官网http://tengine.taobao.org/

      curl -I www.taobao.com	#查看淘宝使用的 服务器为Tengine
      
    • OpenResty:基于Nginx与Lua语言的高性能Web平台,章亦春团队开发,官网:http://openresty.org/cn/

二、Nginx功能介绍

  • 静态的web资源服务器html,图片,js,css,txt等静态资源
  • 结合FastCGI/uWSGI/SCGI等协议反向代理动态资源请求
  • http/https协议的反向代理
  • imap4/pop3协议的反向代理
  • tcp/udp协议的请求转发(反向代理)

基础特性

  • 模块化设计,较好的扩展性
  • 高可靠性 远远超过apache
  • 支持热部署:不停机更新配置文件,升级版本,更换日志文件
  • 低内存消耗:10000个keep-alive连接模式下的非活动连接,仅需2.5M内存
  • event-driven,aio,mmap(内存隐射),sendfile
  • nginx实现网络通讯时使用的是IO多路复用机制:epoll模型,

web服务相关功能

  • 虚拟主机(server)
  • 支持keep-alive和管道连接(利用一个连接做多次请求)
  • 访问日志(支持基于日志缓冲提高其性能)
  • url rewrite
  • 路径别名
  • 基于IP及用户的访问控制
  • 支持速率限制及并发数限制
  • 重新配置和在线升级而无须终端客户的工作进程

nginx实现网络通讯时使用的是IO多路复用机制:epoll模型,

Nginx的模块从结构上分为核心模块、基础模块和第三方 模块。

核心模块:HTTP模块、EVENT模块和MAIL模块

基础模块: HTTP Access模块、HTTP FastCGI模块、HTTP Proxy模块和HTTP Rewrite模块

第三方模块: HTTP Upstream Request Hash模块、Notice模块和HTTP Access Key模块及用户自己开发的模块

三、Nginx架构和进程

Nginx架构

在这里插入图片描述

Nginx进程结构

  • web请求处理机制

    • 多进程方式:服务器每接收到一个客户端请求就有服务器的主进程生成一个子进程响应客户端,直到用户关闭连接,这样的优势是处理速度快。子进程之间相互独立,但是如果访问过大会导致服务器资源耗尽而无法提供请求。
    • 多线程方式:与多进程方式类似,但是每收到一个客户端请求会有服务进程派生出一个线程来跟客户方进行交互,一个线程的开销远远小于一个进程,因此多线程方式在很大程度减轻了web服务器对系统资源的要求,但是多线程也有自己的缺点。即当多个线程位于同一个进程内工作的时候,可以相互访问同样的内存地址空间,所以他们相互影响,一旦主进程挂掉则所有子线程都不能工作了,IIS服务器使用了多线程的方式,需要间隔一段时间就重启一次才能稳定。
  • Nginx是多进程组织模型,而且是一个由Master主进程和Worker工作进程组成。但是其实Nginx里也有线程
    在这里插入图片描述

  • 主进程(master process)的功能:

    • 对外接口:接收外部的操作(信号)
    • 对内转发:根据外部的操作的不同,通过信号管理worker
    • 监控:监控worker进程的运行状态,worker进程异常终止后,自动重启worker进程
    • 读取Nginx配置文件并验证其有效性和正确性
    • 建立、绑定和关闭socket连接
    • 按照配置生成、管理和结束工作进程
    • 接受外界指令,比如重启、升级及退出服务器等指令
    • 不中断服务,实现平滑升级,重启服务并应用新的配置
    • 开启日志文件,获取文件描述符
    • 不中断服务,实现平滑升级,升级失败进行回滚处理
    • 编译和处理perl脚本
  • 工作进程(worker process)的功能:

    • 所有Worker进程都是平等的
    • 实际处理:网络请求,由Worker进程处理
    • Worker进程数量:在nginx.conf 中配置,一般设置为核心数,充分利用CPU资源,同时,避免进程数量过多,避免进程竞争CPU资源,增加上下文切换的损耗
    • 接受处理客户的请求
    • 将请求依次送入各个功能模块进行处理
    • I/O调用,获取响应数据
    • 与后端服务器通信,接收后端服务器的处理结果
    • 缓存数据,访问缓存索引,查询和调用缓存数据
    • 发送请求结果,响应客户的请求
    • 接收主程序指令,比如重启、升级和退出等

在这里插入图片描述
在这里插入图片描述
Nginx是多进程组织模型,而且是一个由Master主进程和Worker工作进程组成。

Nginx进程间通信

?作进程是有主进程?成的,主进程由root启用,主进程使?fork()函数,在Nginx服务器启动过程中主进程根据配置?件决定启动?作进程的数量,然后建??张全局的?作表?于存放当前未退出的所有的?作进程,主进程?成?作进程后会将新?成的?作进程加?到?作进程表中,并建??个单向的管道并将其传递给?作进程,该管道与普通的管道不同,它是由主进程指向?作进程的单向通道,包含了主进程向?作进程发出的指令、?作进程ID、工作进程在?作进程表中的索引和必要的?件描述符等信息,单向管道,工作进程只能监听内容之后读取指令。 主进程与外界通过信号机制进?通信,当接收到需要处理的信号时,它通过管道向相关的?作进程发送正确的指令,每个?作进程都有能力捕获管道中的可读事件,当管道中有可读事件的时候,?作进程就会从管道中读取并解析指令,然后采取相应的执行动作,这样就完成了主进程与?作进程的交互。

?作进程之间的通信原理基本上和主进程与?作进程之间的通信是?样的,只要?作进程之间能够取得彼此的信息,建?管道即可通信,但是由于?作进程之间是完全隔离的,因此?个进程想要知道另外?个进程的状态信息就只能通过主进程来设置了

为了实现?作进程之间的交互,主进程在?成?作进程之后,在?作进程表中进?遍历,将该新进程的ID以及针对该进程建?的管道句柄传递给?作进程中的其他进程,为?作进程之间的通信做准备,当?作进程1向?作进程2发送指令的时候,?先在主进程给它的其他?作进程?作信息中找到2的进程ID,然后将正确的指令写?指向进程2的管道,?作进程2捕获到管道中的事件后,解析指令并进?相关操作,这样就完成了?作进程之间的通信。
在这里插入图片描述
既然是单向管道,那么主进程怎么知道自己的子进程是不是工作结束,需要的文件是否就绪?

IO多路复用机制

利用IO多路复用机制,一个进程可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作

linux:包含进程相关的所有文件描述符
?在这里插入图片描述

io模型:https://segmentfault.com/a/1190000003063859#item-3-13

select:轮询,将所有正在监听的文件描述符都放到一个数组里面。文件描述符数组最大为1024

poll:也是轮询,但解决了数组最大1024的问题,因为采用了链表的方式存储

epoll:不需要轮询了,而是触发了event后会自动去通知,基于事件的通知方式

select:数组的方式
对所有的fd进行轮询,把准备好的fd进行标记
在这里插入图片描述

poll:链表的方式
也是对所有的fd进行轮询,把准备好的fd标记
在这里插入图片描述
Nginx使用的epoll的异步网络IO模型

连接建立和请求处理过程

  • Nginx启动时,Master 进程,加载配置文件
  • Master进程,初始化监听的socket
  • Master进程,fork 出多个Worker进程
  • Worker进程,竞争新的连接,获胜方通过三次握手,建立Socket连接,并处理请求

在这里插入图片描述

HTTP处理过程

在这里插入图片描述

四、Nginx模块介绍

  • nginx有多种模块
    • 核心模块:是Nginx服务器正常运行必不可少的模块,提供错误日志记录、配置文件解析、事件驱动机制、进程管理等核心功能
    • 标准HTTP模块:提供HTTP协议解析相关功能,比如:端口配置、网页编码设置、HTTP响应头设置等等
    • 可选HTTP模块:主要用于扩展标准的HTTP功能,让Nginx能处理一些特殊服务,比如:Flash多媒体传输、解析GeoIP请求、网络传输压缩、安全协议SSL支持等等
    • 邮件服务模块:实现反向代理功能包括TCP协议代理
    • Stream服务模块:实现反向代理功能包括TCP协议代理
    • 第三方模块:是为了扩展Nginx服务器应用,完成开发者自定义功能,比如json支持、Lua支持等
  • nginx高度模块化;1.9.11版本支持动态装载和卸载
  • 模块分类
    • 标准模块
      • HTTP模块:ngx_http_*
        • HTTP Core modules默认功能
        • HTTP Optional modules需要编译时指定
      • Mail模块:ngx_mail_*
      • Stream模块:ngx_stream_*
    • 第三方模块
      • https://nginx.org/en/docs/

五、Nginx安装

Nginx版本分为Mainline version(主要开发版本)、Stable version(当前最新稳定版)和Legacy version(旧的稳定版本)https://nginx.org/en/

Nginx安装可以使用yum或源码安装,但是推荐使用源码编译安装

  • yum的版本比较旧(没有epel-release库根本都没有nginx)
  • 编译安装可以更方便自定义相关路径
  • 使用源码编译可以自定义相关功能,自定义编译的模块,更方便业务上的使用

源码安装需要提前准备标准的编译器GCC的全称是(GNU Complier collection),其有GNU开发,并以GPL即LGPL许可,是自由的类UNIX即苹果电脑Mac OS X操作系统的标准编译器,因为GCC原本只能处理C语言,所以原名为GNU C语言编译器,后来得到快速发展,可以处理C++,Fortran,pascal,objective-C,java以及Ada等其他语言,此外还需要Automake工具,以完成自动创建Makefile的工作,Nginx的一些模块需要依赖第三方库,比如:pcre(支持rewrite),zlib(支持gzip模块)和openssl(支持ssl模块)等。

基于yum安装nginx

[root@localhost ~]# yum install epel-release.noarch -y
[root@localhost ~]# yum install nginx -y

查看当前系统中的nginx版本

范例:查看系统和EPEL的nginx版本

[root@localhost ~]# yum info nginx
[root@localhost ~]# yum -ql nginx
[root@localhost ~]# systemctl start nginx
[root@localhost ~]# systemctl enable nginx

官方包源码安装nginx

可以自己选择安装官方源的版本

官方包链接:

https://nginx.org/en/download.html

查看官方编译指令

[root@localhost ~]# nginx -v

编译安装

  • 从官网获取源码包,以1.18.0举例
[root@localhost ~]# wget https://nginx.org/download/nginx-1.18.0.tar.gz -P /usr/local/src
[root@localhost ~]# cd /usr/local/src
[root@localhost src]# tar xzvf nginx-1.18.0.tar.gz
[root@localhost src]# cd nginx-1.18.0
[root@localhost nginx-1.18.0]# ./configure --help
# 可以查看到编译的一些参数配置的帮助
tar
格式:tar [选项] [文件目录列表]
功能:对文件目录进行打包备份
选项:
-c 建立新的归档文件
-r 向归档文件末尾追加文件
-x 从归档文件中解出文件
-O 将文件解开到标准输出
-v 处理过程中输出相关信息
-f 对普通文件操作
-z 调用gzip来压缩归档文件,与-x联用时调用gzip完成解压缩
-Z 调用compress来压缩归档文件,与-x联用时调用compress完成解压缩
  • 编译安装
[root@localhost ~]# yum install -y gcc pcre-devel openssl-devel zlib-devel
[root@localhost ~]# useradd -r -s /sbin/nologin nginx	#-r创建系统用户
[root@localhost nginx-1.18.0]# ./configure --prefix=/apps/nginx \
--user=nginx \
--group=nginx \
--with-http_ssl_module \
--with-http_v2_module \
--with-http_realip_module \
--with-http_stub_status_module \
--with-http_gzip_static_module \
--with-pce \
--with-stream \
--with-stream_ssl_module \
--with-stream_realip_module \
[root@localhost nginx-1.18.0]# make -j 2 && make install
[root@localhost nginx-1.18.0]# chown -R nginx.nginx /apps/nginx	#-R表示递归修改
[root@localhost nginx-1.18.0]# ls /apps/nginx
conf html logs sbin

[root@localhost nginx-1.18.0]#ln -s /apps/nginx/sbin/nginx /usr/bin
[root@localhost nginx-1.18.0]#which nginx
/usr/bin/nginx
[root@localhost nginx-1.18.0]# nginx -v 
  • nginx完成安装以后,有四个主要的目录
    • conf:保存nginx所有的配置文件,其中nginx.conf是nginx服务器的最核心最主要的配置文件,其他的.conf则是用来配置nginx相关的功能性,例如fastcgi功能使用的是fastcgi.conf和fastvgi.params两个文件,配置文件一般都有个样板配置文件,是文件名.default结尾,使用的时候将其赋值为并将default去掉即可。
    • html:目录中保存了nginx服务器的web文件,但是可以更改为其他目录保存web文件,另外还有一个50x的web文件是默认的错误页面提示页面。
    • logs:用来保存nginx服务器的访问日志错误日志等日志,logs目录可以放在其他路径,比如/var/logs/nginx里面。
    • sbin:保存nginx二进制启动脚本,可以接受不同的参数以实现不同的功能。

启动和停止nginx测试访问web界面

  • 启动和关闭nginx
[root@localhost nginx-1.18.0]# nginx 
[root@localhost nginx-1.18.0]# nginx -s stop

创建nginx自启动文件

用yum安装的时候,会自动在/usr/lib/systemd/system/下创建对应的.service文件,使得我们可以用systemctl这个命令来启动关闭服务

# 复制同一版本的nginx的yum安装生成的service文件
[root@localhost ~]# vim /usr/lib/systemd/system/nginx.service
[Unit]
Description=The nginx HTTP and reverse proxy server
Documentation=http://nginx.org/en/docs/
After=network.target remote-fs.target nss-lookup.target
Wants=network-online.target

[Service]
Type=forking
PIDFile=/apps/nginx/run/nginx.pid
ExecStart=/apps/nginx/sbin/nginx -c /apps/nginx/conf/nginx.conf
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s TERM $MAINPID

[Install]
WantedBy=multi-user.target

[root@localhost ~]# mkdir /apps/nginx/run/
[root@localhost ~]# vim /apps/nginx/conf/nginx.conf
pid		/apps/nginx/run/nginx.pid;

验证Nginx自启动文件

[root@localhost ~]# systemctl daemon-reload
[root@localhost ~]# systemctl enable --now nginx
[root@localhost ~]# ll /apps/nginx/run
总用量 4
-rw-r--r--. 1 root root 5 524 10:07 nginx.pid

六、Nginx核心配置详解

配置文件说明

  • nginx官方帮助文档
    • https://nginx.org/en/docs
  • tengine帮助文档
    • https://tengine.taobao.org/documentation.html
  • Nginx的配置文件的组成部分
    • 主配置文件:nginx.conf

    • 子配置文件:include conf.d/*.conf

    • fastcgi,uwsgi,scgi等协议的相关配置文件

    • mime.types:支持的mime类型,MIME(Multipurpose Internet Mail Extensions)多用途互联网邮件扩展类型,MIME消息能包含文本、图像、音频、视频以及其他应用程序专用的数据,是设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会自动使用指定的应用程序来打开。多用于指定一些客户端自定义的文件名,以及一些媒体文件打开方式。

      MIME参考文档:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Basic_of_HTTP/MIME_types

  • Nginx主配置文件的配置指令方式
directive value [value2 ...];
注意
(1)指令必须以分号结尾
(2)支持使用配置变量
   内建变量:由Nginx模块引入,可直接应用
   自定义变量:由用户使用set命令,格式:set variable_name value;
   引用变量:$variable_name
  • 主配置文件结构:四部分
main block:主配置段,既全局配置段,对http,mail都有效
# 事件驱动相关的配置
event{
	...
}
# http/https协议相关配置段
http {
	...
}
# 默认配置文件不包括下面两个块
# mail协议相关配置段
mail {
	...
}
# stream服务器相关配置段
stream {
	...
}
# 导入其他路径的配置文件
include /apps/nginx/conf.d/*.conf

默认的nginx.conf配置文件格式说明

在这里插入图片描述
在这里插入图片描述

全局配置

(event{}结构上方的配置)

Main全局配置段常见的配置指令分类

  • 正常运行必备的配置
  • 优化性能相关的配置
  • 用于调试及定位问题相关的配置
  • 时间驱动相关的配置

全局配置说明

CPU性能优化

# 在nginx.conf配置文件里面修改
user	nginx nginx;	#启动Nginx工作进程的用户和组
worker_process [number | auto];		# 启动Nginx工作进程数量,一般设为和CPU核心数相同
worker_process 4
worker_cpu_affinity 0001 0010  0100 1000;	# 将Nginx工作进程绑定到指定的CPU核心,默认Nginx是不进行进程绑定的,绑定并不是意味着当前nginx进程独占一核CPU,但是可以保障此进程不会运行在其他核心上,这就极大减少了nginx的工作进程在不同的cpu核心上的来回跳转,减少了cpu对进程资源分配与回收以及内存管理等等,因此可以有效的提示nginx服务器性能。
CPU MASK:0001	0号CPU
		  0010	 1号CPU
		  0100	 2号CPU
		  1000	 3号CPU

[root@localhost ~]# watch -n.5 'pas axo pid,cmd,psr |grep nginx'
#查看nginx进程对应的CPU

yum install httpd-tools -y	# 安装ab这个工具
[root@localhost ~]# while true;do ab -c 1000 -n 2000 http://127.0.0.1/;done
#压力测试

错误日志记录配置

# 错误日志记录配置,语法:error_log file [debug | info | notice | warn | error | crit | alert | emerg]
# error_log logs/error.log;
# error_log logs/error.log notice;
[root@localhost conf]# vim /apps/nginx/conf/nginx.conf
error_log /apps/nginx/logs/error.log error;

工作优先级与文件并发数

[root@localhost conf]# vim /apps/nginx/conf/nginx.conf
worker_priority	0;	# 工作进程优先级(-20~19)
worker_rlimit_nofile 65536;	 #所有worker进程能打开的文件数量上限,包括:nginx的所有连接(例如与代理服务器的连接等),而不仅仅是客户端的连接,另一个考虑因素是实际的并发连接数不能超过系统级别的最大打开文件数的限制,最好与ulimit -n的值保持一致
[root@localhost ~]# ulimit -n 102400
[root@localhost ~]# vim /etc/security/limits.conf
*	soft	nofile	102400
*	hard	nofile	102400

# 查看优先级
[root@localhost ~]# watch -n.5 'pas axo pid,cmd,psr |grep nginx'

其他优化配置

daemon off;		#前台运行nginx服务,用于测试、docker等环境
master_process off|on;	# 是否开启Nginx的master-worker工作模式,仅用于开发调试场景,默认为on
events{
	worker_connection 65536;	# 设置单个工作进程的最大并发连接数
	use epoll;	 # 使用epoll事件驱动,Nginx支持众多的事件驱动,比如:select、poll、epoll,只能设置在events模块中
	accept_mutex on; 	#on为同一时刻一个请求轮流由work进程处理,而防止被同时唤醒所有worker,避免多个睡眠进程被唤醒的设置,默认为off,新请求会唤醒所有worker进程,此过程也被称为“惊群”,因此nginx刚安装完以后要进行适当的优化,建议设置为on
	multi_accept on;	# on时Nginx服务器的每个工作进程可以同时接受多个新的网络连接,此指令默认为off,即默认为一个工作进程只能一次接受一个新的网络连接,打开后几个同时接受多个,建议设置为on
}

http配置块

http协议相关的配置结构

http {
	...
	...#各server的公共配置
	server{		# 每个server用于定义一个虚拟主机,第一个server为默认虚拟服务器
		...
	}
	server{
		...
		server_name
		root
		alias
		location [OPERATOR] URL {	# 指定URL特性
			...
			if CONDITION {
				...
			}
		}
	}
}

http协议配置说明

http {
	#	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 /var/log/nginx/access.log main; 	# 指定日志文件路径
	sendfile on; # 允许sendfile方式传输文件 ,sendfile系统调用在两个文件描述符之间直接传递数据(完全在内核中操作),从而避免了数据在内核缓冲区和用户缓冲区之间的拷贝,操作效率很高,被称之为零拷贝。
	tcp_nopush on; # 在sendfile启动下,使用TCP_CORK套接字,当有数据时,先别着急发送, 确保数据包已经装满数据, 避免了网络拥塞
	tcp_nodelay on; # 接连接保持活动状态
	keepalive_timeout 65; # 超时时间
	types_hash_max_size 2048;# 连接超时时间
	include /etc/nginx/mime.types; # 文件扩展名与文件类型映射表
	default_type application/octet-stream; # 默认文件类型,默认为text/plain
	include /etc/nginx/conf.d/*.conf;
	server {
		listen 80 default_server; # 指定监听的端口
		listen [::]:80 default_server;
		server_name _; # 指定网站主机名
		root /usr/share/nginx/html; # 定义站点目录的位置
		include /etc/nginx/default.d/*.conf; # 定义首页文件
		location / {
		}
		error_page 404 /404.html; # 定义优雅显示页面信息
		location = /40x.html {
		}
		error_page 500 502 503 504 /50x.html;
		location = /50x.html {
		}
	}
}

指定响应报文server首部

[root@localhost ~]# curl -I 127.0.0.1

# 是否在响应报文的Server首部显示nginx版本
server_tokens on | off | bulid | string

[root@localhost ~]# vim /apps/nginx/conf/nginx.conf
server{
	listen 	80;
	server_name localhost;
	charset utf-8;
	server_tokens off;
	#charset koi9-r;
}
[root@localhost ~]# curl -I 127.0.0.1

范例:修改server字段

# 如果想自定义响应报文的nginx版本信息,需要修改源码文件,重新编译
# 如果server_tokens on,修改 src/core/nginx.h 修改第13-14行,如下示例
# define NGINX_VERSION "1.68.9"
# define NGINX_VER "mynginx" NGINX_VERSION
如果server_tokens off,修改src/http/ngx_http_header_filter_module.c
第49行,如下示例:
static char ngx_http_server_string[] = 'Server: nginx' CRLF;
把其中的nginx改为自己想要的文字即可,如mynginx

范例:修改Server头部信息

[root@localhost ~]# vim /usr/local/src/nginx-1.18.0/src/core/nginx.h
# define NGINX_VERSION "1.68.9"
# define NGINX_VER "mynginx" NGINX_VERSION
[root@localhost ~]# vim /usr/local/src/nginx-1.18.0/src/http/ngx_http_header_filter_module.c
static char ngx_http_server_string[] = 'Server: mynginx' CRLF;

修改完成后重新编译
[root@localhost ~]# cd /usr/local/srcnginx-1.18.0
root@localhost nginx-1.18.0]# ./configure --prefix=/apps/nginx \
--user=nginx \
--group=nginx \
--with-http_ssl_module \
--with-http_v2_module \
--with-http_realip_module \
--with-http_stub_status_module \
--with-http_gzip_static_module \
--with-pcre \
--with-stream \
--with-stream_ssl_module \
--with-stream_realip_module \
[root@localhost nginx-1.18.0]# make -j 2 && make install
[root@localhost nginx-1.18.0]# systemctl restart nginx
[root@localhost nginx-1.18.0]# curl -I 127.0.0.1

核心配置示例

基于不同的IP、不同的端口以及不同的域名实现不同的虚拟主机,依赖于核心模块ngx_http_core_module实现

PC站与手机站

  • 定义子配置文件路径,在主配置文件最后添加导入
[root@localhost ~]# mkdir /apps/nginx/conf.d
[root@localhost ~]# vim /apps/nginx/conf/nginx.conf
http {
	...
	include /apps/nginx/conf.d/*.conf;
}
  • 创建pc网站配置
[root@localhost ~]# vim /apps/nginx/conf.d/pc.conf
server{
	listen 80;
	server_name www.pc.com;
	location / {
		root /apps/nginx/html/pc;
	}
}
[root@localhost ~]# mkdir -p /apps/nginx/html/pc
[root@localhost ~]# echo "hello pc" > /apps/nginx/html/pc/index.html
[root@localhost ~]# systemctl reload nginx
[root@localhost ~]# vim /etc/hosts
192.168.64.129 www.pc.com
  • 创建移动端的网站的配置
[root@localhost ~]# vim /apps/nginx/conf.d/moblie.conf
server{
	listen 80;
	server_name www.mobile.com;
	location / {
		root /apps/nginx/html/mobile;
	}
}
[root@localhost ~]# mkdir -p /apps/nginx/html/mobile
[root@localhost ~]# echo "hello mobile" > /apps/nginx/html/mobile/index.html
[root@localhost ~]# systemctl reload nginx
[root@localhost ~]# vim /etc/hosts
192.168.64.129 www.mobile.com

root与alias

  • root:指定web的家目录,在定义location的时候,文件的绝对路径等于root+location

范例:

[root@localhost ~]# vim /apps/nginx/conf.d/test.conf
server{
	listen 80;
	server_name a.test.com;
	location / {
		root /apps/nginx/html/www;
	}
	location /about {
		root /apps/nginx/html/about;	# 这样写其实访问的是/app/nginx/html/下的about的about
	}
}
[root@localhost ~]# vim /etc/hosts
192.168.64.129 a.test.com
[root@localhost ~]# mkdir -p /apps/nginx/html/about
[root@localhost ~]# echo "about" > /apps/nginx/html/about/index.html
[root@localhost ~]# systemctl reload nginx
  • alias:定义路径别名,会把访问的路径重新定义到其指定的路径,文档映射的另一种机制;仅能用于location上下文,此指令使用较少

范例:

[root@localhost ~]# vim /apps/nginx/conf.d/test.conf
server{
	listen 80;
	server_name a.test.com;
	location / {
		root /apps/nginx/html/www;
	}
	location /about {
		alias /apps/nginx/html/about;	# 当访问about的时候,会显示alias定义的/apps/nginx/html/about里面的内容
	}
}
[root@localhost ~]# systemctl reload nginx
[root@localhost ~]# curl a.test.com/about/

location的详细使用

在一个server中location配置段可存在多个,用于实现从uri到文件虚脱的路径映射;nginx会根据用户请求的URI来检查定义的所有location,按一定的优化级找出一个最佳匹配,而后应用其配置。

在没有使用正则表达式的时候,nginx会先在server中的多个location选取匹配度最高的一个uri,uri是用户请求的字符串,即域名后面的web文件路径,然后使用该location模块中的正则uri和字符串,如果匹配成功就结束搜索,并使用此location处理此请求。

location官方帮助:https://nginx.org/en/docs/http/ngx_http_core_module.html#location

  • 语法规则
location [ = | ~ | ~* | ^~ ] uri { ... }
匹配正则解释
=用于标准uri前,需要请求字符串与uri精确匹配,大小敏感,如果匹配成功就停止向下匹配并立即处理请求
^~用于标准uri前,表示包含正则表达式,并且适配以指定的正则表达式开头,对URI的最左边部分做匹配检查,不区分字符大小写
~用于标准uri前,表示包含正则表达式,并且区分大小写
~*用于标准uri前,表示包含正则表达式,并且不区分大小写
不带符号匹配其实与此uri的所有的uri
|用于标准uri前,表示包含正则表达式,并且转义字符。可以将.*等转为普通符号
  • 匹配优先级从高到低
    • = ^~ ~/~* 不带符号
  • 官方范例
    • The "/"request will match configuration A
    • the "/index.html"request will match configuration B
    • the "/documents/document.html"request will match configuration C
    • the "/images/1.gif"request will match configuration D
    • the "/documents/1.jpg"request will match configuration E
location = / {
	[ configuration A ]
} 
location / {
	[ configuration B ]
} 
location /documents/ {
	[ configuration C ]
} 
location ^~ /images/ {
	[ configuration D ]
} 
location ~* \.(gif|jpg|jpeg)$ {
	[ configuration E ]
} 
精确匹配
  • 精确匹配logo
[root@localhost ~]# vim /apps/nginx/conf.d/test.conf
server{
	listen 80;
	server_name a.test.com;
	location / {
		root /apps/nginx/html/www;
	}
	location = /logo.jpg {
		root /apps/nginx/html/images;
	}
}
[root@localhost ~]# mkdir -p /apps/nginx/html/images
[root@localhost ~]# cd /apps/nginx/html/images
[root@localhost images]# wget https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png
[root@localhost images]# mv PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png logo.png
[root@localhost ~]# systemctl restart nginx
[root@localhost ~]# curl a.test.com/logo.jpg
区分大小写
  • ~实现区分大小写的模糊匹配,以下范例中,如果访问uri中包含大写字母的JPG,则以下location匹配Ax.jpg条件不成功,因为~区分大小写,那么当用户的请求被指向匹配时发现location中定义的是小写的jpg,则匹配失败,即要么继续往下匹配其他的location(如果有),要么报错给客户端
[root@localhost ~]# vim /apps/nginx/conf.d/test.conf
location ~ /A.?\.jpg {	#正则表达式中的.表示任意字符,?表示可以出现0次或一次,\转义字符
	index index.html;
	root /apps/nginx/html/images;
}
[root@localhost images]# mv logo.jpg Aa.jpg
[root@localhost ~]# systemctl restart nginx
[root@localhost ~]# curl a.test.com/Aa.jpg	#这里可以匹配到正常访问
[root@localhost ~]# mv Aa.jpg aa.jpg
修改文件为小写之后再访问因为大小写敏感就访问不了了
不区分大小写
  • ~*用来对用户请求的uri做模糊匹配,uri中无论都是大写、都是小写或者大小写混合,此模式也都会匹配,通常使用此模式匹配用户request中的静态资源,并继续做下一步操作,此方式使用较多
  • 注意:此方式中,对linux文件系统上的文件仍然是区分大小写的,如果磁盘文件不存在,仍会提示404
location ~* /A.?\.jpg {	
	index index.html;
	root /apps/nginx/html/images;
}
这里虽然规则写的大写A但是去访问http://a.test.com/aa.jpg正常可以访问到
URI开始
location ^~ /images {	
	index index.html;
	root /apps/nginx/html;
}
访问http://a.test.com/images/aa.jpg
文件点后缀名
location ~* \.(jpg|gif|jpeg|bmp|png|tiff|ico|wmf|js|css)$ {	
	index index.html;
	root /apps/nginx/html/images;
}
http://a.test.com/images/aa.jpg可以访问到
优先级
[root@localhost ~]# mkdir -p /apps/nginx/html/static{1,2,3}
[root@localhost ~]# vim /apps/nginx/conf.d/test.conf
location = /1.jpg {
	index index.html; 
	root /apps/nginx/html/static1;
}
location /1.jpg {
	index index.html; 
	root /apps/nginx/html/static2;
}
location ~* \.(jpg|gif|jpeg|bmp|png|tiff|ico|wmf|js|css)$ {
	index index.html; 
	root /apps/nginx/html/static3;
}
[root@localhost ~]# wget -O /apps/nginx/html/static1/1.jpg https://dummyiamge.com/600x100/000/fff&text=static1
[root@localhost ~]# wget -O /apps/nginx/html/static2/1.jpg https://dummyiamge.com/600x200/000/fff&text=static2
[root@localhost ~]# wget -O /apps/nginx/html/static3/1.jpg https://dummyiamge.com/600x300/000/fff&text=static3
重启访问nginx测试访问http:a.test.com/1.jpg
  • 匹配优先级
    • location =>location ^~ 路径>location ~,~* 正则>location 完整路径>location 部分起始路径>/
生产使用案例
  • 直接匹配网站根会加速Nginx访问处理
location = /index.html {
	...
}
location / {
	...
}
  • 静态资源配置方法1
location ^~ /static/ {
	...
}
  • 静态资源配置方法2,应用较多
location ~* \.(jpg|gif|jpeg|bmp|png|tiff|ico|wmf|js|css)$ {
	...
}
  • 多应用配置
location ~* /app1 {
	...
}
location ~* /app2 {
	...
}

Nginx四层访问控制

访问控制基于模块ngx_http_access_module实现,可以通过匹配客户端源IP地址进行限制

注意:如果能再防火墙设备控制最好就不要在nginx上配置,可以更好的节约资源

官方帮助:https://nginx.org/en/docs/http/ngx_http_access_module.html

范例:

[root@localhost ~]# vim /apps/nginx/conf.d/test.conf
server{
	listen 80;
	server_name a.test.com;
	location / {
	root /apps/nginx/html/www;
	}
	location = /1.jpg {
	index index.html;
	root /apps/nginx/html/static1;
	allow 192.168.64.129;
	deny all;
	}
}
}禁止了主机访问,虚拟机本机可以访问刚才的1.jpg

Nginx账户认证功能

由ngx_http_auth_basic_module模块提供此功能

官方帮助:https://nginx.org/en/docs/http/ngx_http_auth_basic_module.html

范例

[root@localhost ~]# htpasswd -cb /apps/nginx/conf/.htpasswd user1 123456
[root@localhost ~]# htpasswd -b /apps/nginx/conf/.htpasswd user2 123456
# -c 创建文件
# -b 非交互式提交密码
[root@localhost ~]# tail /apps/nginx/conf/.htpasswd

[root@localhost ~]# vim /apps/nginx/conf.d/test.conf
server{
	listen 80;
	server_name a.test.com;
	auth_basic "login password";
	auth_basic_user_file /apps/nginx/conf/.htpasswd;
	location = /1.jpg {
	index index.html;
	root /apps/nginx/html/static1;
	}
}
[root@localhost ~]# systemctl restart nginx

自定义错误页面

自定义错误页,以指定的响应状态码进行响应,可用位置:http,server,location, if in location

error_page code ... [=[response]] uri;

范例:

[root@localhost ~]# vim /apps/nginx/conf.d/nginx.conf
server{
	listen 80;
	server_name a.test.com;
	error_page 500 502 503 504 /error.html;
	location = /error.html {
	root html;
	}
}

范例:

[root@localhost ~]# vim /apps/nginx/conf.d/test.conf
server{
	listen 80;
	server_name a.test.com;
	auth_basic "login password";
	auth_basic_user_file /apps/nginx/conf/.htpasswd;
	error_page 404 /40x.html
	location = /1.jpg {
	index index.html;
	root /apps/nginx/html/static1;
	}
}
[root@localhost ~]# echo "<h1>404 not found</h1>" > /apps/nginx/html/40x.html

范例:

error_page 404 /index.html;
# 如果404,就跳转到主页

自定义错误日志

可以自定义错误日志

Syntax: error_log file [level];
Default:
error_log logs/error.log error;
Context:main, http, mail, stream, server, location
level:debug, info, notice, warn, error, crit, alert, emerg

范例:

[root@localhost ~]# vim /apps/nginx/conf.d/nginx.conf
server{
	...
	error_page 500 502 503 504 /error.html;
	access_log /apps/nginx/logs/a_test_access.log;
	error_log /apps/nginx/logs/a_test_error.log;
	location = /error.html {
	root html;
	}
}

长连接设置

[root@localhost ~]# vim /apps/nginx/conf/nginx.conf
keepalive_timeout timeout [header_timeout];
# 设定保持连接超时时长,0表示禁止长连接,默认为75s,通常配置在http字段作为站点全局配置
keepalive_requests number;
# 在一次长连接上所允许请求的资源的最大数量,默认为100次,建议适当调大,比如500

范例:

[root@localhost ~]# vim /apps/nginx/conf/nginx.conf
http {
	...
	keepalive_requests 3;
	keepalive_timeout 65 60;
}
	# 开启长连接后,返回客户端的会话保持时间为60s,单次长连接累计请求达到指定次数请求或65秒就会断开,后面的60为发送给客户端应答报文头部中显示的超时时间设置为60s,如不设置客户端将不显示超时时间。
	keep-Alive:timeout=60;
	# 浏览器收到的服务器返回的报文
	# 如果设置为keepalive_timeout 0 表示关闭会话保持功能,将如下显示:
	Connection:close	# 浏览器收到的服务器返回的报文
# 使用命令测试

[root@localhost ~]# telnet a.test.com 80

作为下载服务器

ngx_http_autoindex_module模块处理以斜杠字符“/”结尾的请求,并生成目录列表可以作为下载服务配置使用

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

相关指令:

autoindex on|off;
# 自动文件索引功能,默认off
autoindex_exact_size on|off;
# 计算文件确切大小(bytes),off显示大概大小(单位K、M),默认on
autoindex_localtime on|off;
# 显示本机时间而非GMT(格林威治时间),默认off
autoindex_format html|xml|json|jsonp;
# 显示索引的页面分割,默认html
limit_rate rate;
# 限制响应客户端传输速率(除GET和HEAD以外的所有方法),单位B/s,即bytes/second,默认值0,表示无限制,此指令由ngx_http_core_module提供

范例:实现下载站点

[root@localhost ~]# mkdir -p /apps/nginx/html/www/download
[root@localhost ~]# cd /apps/nginx/html/www/download
[root@localhost download]# touch f1
[root@localhost download]# touch f2
[root@localhost ~]# vim /apps/nginx/conf.d/www.conf
server{
	listen 80;
	server_name file.test.com;
	location /download {
		autoindex on;	# 自动索引功能,开启才会展示出文件列表
		autoindex_exact_size off;	# 关闭详细文件大小统计,让文件大小消失MB,GB单位,默认b
		autoindex_localtime on;	# on表示显示本机时间
		limit_rate 1024k;	# 限速,默认不限速
		root /apps/nginx/html/www;
	}
}
修改hosts
192.168.64.129 file.test.com
测试http://file.test.com/download/

作为上传服务器

client_max_body_size 1m;
# 设置允许客户端上传单个文件的最大值,默认值为1m,上传文件超过此值会出现413错误
client_body_buffer_size size;
# 用户接受每个客户端请求报文的body部分的缓冲区大小;默认16k;超过此大小时,其将被暂存到磁盘上client_body_temp_path所指定的位置
client_body_temp_path path [level1 [level2 [level3 ]]]
# 设定存储客户端请求报文的body部分的临时存储路径及子目录结构和数量,目录名为16禁止的数字,使用hash之后的值从后往前截取1位、2位、2位作为目录名
# 1级目录占1位16进制,即2^4=16个目录 0-f
# 2级目录占2位16进制,即2^8=256个目录 00-ff
# 3级目录占2位16进制,即2^8=256个目录 
# 因为如果所有上传的文件都放在一个文件夹下,不仅很容易文件名冲突,并且容易导致一个文件夹特别大。所以有必要创建子目录这里的level1,2,3如果有值就代表存在一级,二级,三级子目录。目录名是由数字进行命名的,所以这里的具体的值就是代表目录名的数字位数,比如如下设置
# client_body_temp_path /spool/nginx/client_temp 3 2;
# 可能创建的文件路径为
# /spool/nginx/client_temp/702/45/000001234567
[root@localhost ~]# md5sum f1

其他配置

  • 对哪种浏览器禁用长连接
keepalive_disable none | browser ...;
  • 限制客户端使用除了指定的请求方法之外的其他方法
limit_except method ... { ... };	# 仅用于location
method: GET, HEAD, POST, PUT, DELETE, MKCOL, COPY, MOVE, OPTIONS, PROPFIND, PROPPATCH, LOCK, UNLOCK, PATCH
[root@localhost ~]# vim /apps/nginx/conf.d/www.conf
location /download {
	root /apps/nginx/html/www;
	autoindex on;
	autoindex_exact_size off;	
	autoindex_localtime on;
	limit_except POST {	#相当于只允许底下允许列表里的使用除了post外的其他方法
		allow 192.168.64.1;	#只有浏览器可以使用除了post外的其他方法,其他人只能用post
		deny all;
	}
}
[root@localhost ~]# systemctl restart nginx
浏览器测试http://file.test.com/download/
  • 是否启用asynchronous file I/O功能,需要编译开启--with-file-aio
  • 在读取文件的时候使用异步可以提高效率
aio on | off
[root@localhost ~]# cd /usr/local/src/nginx-1.18.0
[root@localhost nginx-1.18.0]# ./configure --prefix=/apps/nginx \
--user=nginx \
--group=nginx \
--with-http_ssl_module \
--with-http_v2_module \
--with-http_realip_module \
--with-http_stub_status_module \
--with-http_gzip_static_module \
--with-prce \
--with-stream \
--with-stream_ssl_module \
--with-stream_realip_module \
--with-file-aio
[root@localhost nginx-1.18.0]# make -j 2 && make install
[root@localhost nginx-1.18.0]# nginx -V

#支持file-aio了
[root@localhost ~]# vim /apps/nginx/conf.d/www.conf
server{
	listen 80;
	server_name file.test.com;
	file aio;
	...
}
  • directio是在写文件到磁盘的时候大小大于size的时候,直接写磁盘,而非写缓存
directio size | off;
  • Nginx支持对磁盘中的文件进行缓存
open_file_cache on;	# 是否缓存打开过的文件信息
open_file_cache max=N [inactive=time];
#nginx可以缓存以下三种信息:
#1.文件元数据,文件的描述符,文件大小和最近一次的修改时间
#2.打开的目录结构
#3.没有找到的或者没有权限访问的文件相关信息
max=N; # 可缓存的缓存项上限数量;达到上限后会使用LRU(Least recently used,最近最少使用)算法实现管理
inactive=time;	# 缓存项的非活动时长,在此处指定的时长未被命中的或命中的次数少于open_file_cache_min_uses指令所指定的次数的缓存项即为非活动项,将被删除
open_file_cache_valid time; # 缓存项有效性的检查验证频率,默认值为60s
open_file_cache_errors on | off; 	#是否缓存查找时发送错误的文件一类的信息,默认值为off
open_file_cache_min_uses number; 	#open_file_cache指令的inactive参数指定的时长内,至少被命中此处指定的次数放可被归类为活动项,默认值为1

范例:

open_file_cache max=10000 inactive=60s;
open_file_cache_valid 60s;
open_file_cache_min_uses 5;
open_file_cache_errors off;
文章来源:https://blog.csdn.net/dreamnn/article/details/135777169
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。