主要介绍Nginx核心配置文件

配置文件说明

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

nginx 配置文件组成:

  • 主配置文件: nginx.conf
  • 子配置文件: conf.d/*.conf
  • fastcgi,, uwsgi,scgi 等协议的相关配置文件
  • mime.types:支持的mime类型,MIME(Multipurpose Internet Mail Extensions)多用途互联网邮件扩展类型,MIME消息能包含文本、图像、音频、视频以及其他应用程序专用的数据,是设定某种扩展名的文件用指定应用程序来打开的方式类型,当带有某种扩展名的文件被访问的时候,浏览器会自动使用指定应用程序打开(比如:应用程序会被下载,文本文件会直接显示内容)。简单来说,MIME就是利用扩展名标识文件类型,然后根据文件的类型做响应的处理。MIME 参考文档:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Basics_of_HTTP/MIME_Types

nginx 配置文件格式说明:

  • 配置文件由指令和指令块构成
  • 每条指令以分号;结束,指令和值之间以空格分隔
  • 多条指令可以放在同一行,以分号分隔。但可读性差,不推荐这样配置
  • 指令块以{ } 括号作为开始和结束的标识,将多条指令组织在一起,且支持嵌套
  • 可通过include引入其他配置文件内容,提升配置文件的可维护性(如子配置文件conf.d/*.conf)
  • 配置文件使用# 作为注释符,使用$引用变量
  • 部分指令的参数支持正则表达式

nginx 主配置文件指令格式:

directive value [value1 ...];
说明:
1、指令必须以分号;结束
2、支持变量:
   1)内建变量:由Nginx模块引入,可直接引用
   2)自定义变量:由用户使用set指定定义,格式: set  variable_name value;
   3) 引用变量的方式:$variable_name

主配置文件结构:四部分

main block:主配置段,即全局配置段,对http,mail都有效

#事件驱动相关的配置
event {
 ...
}   

#http/https 协议相关配置段
http {
 ...
}      

#默认配置文件不包括下面两个块
#mail 协议相关配置段
mail {
 ...
}    

#stream 服务器相关配置段
stream {
 ...
}

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

##全局配置块,对全局生效。主要设置nginx的启动用户/组,启动的工作进程数量,工作模式,nginx的pid文件路径等。
user nginx nginx;
worker_processes 1; #启动工作进程的数量,一般与CPU核心数一致

##events块,主要影响nginx服务器与用户的网络连接,比如是否允许同时接受多个网络连接,使用哪种事件驱动模型,每个工作进程最大支持并发连接数,是否开启对多工作进程下的网络连接进行序列化等。
events {
	worker_connections 1024; #单个worker进程的最大并发连接数。作为web服务器时,nginx的最大并发数为:worker_connections * worker_processes。作为反向代理的时候为(worker_connections * worker_processes)/2
}

##http块是nginx服务器配置中的重要组成部分,缓存、代理和日志格式定义等绝大多数功能和第三方模块都在这里配置。http块可以包含多个server块,而一个server块又可以包含多个location块,server块可以配置文件引入、MIME-Type定义、日志自定义、是否启用sendfile、连接超时时间和单个链接的请求上限等。
http {
	include			mime.types;
	default_type 	application/ostet-stream;
	sendfile		on; 	#作为web服务器时打开sendfile加快静态文件传输,指定是否使用sendfile系统调用传输文件。sendfile系统调用在两个文件描述符之间直接传递数据(完全在内核空间进程),从而避免了数据在内核缓冲区和用户缓冲区之间的拷贝,效率很高,是零拷贝技术的一种。
	keepalive_timeout 65; 	#长连接超时时间,单位:秒
	##server块可用于配置虚拟主机,有自己的全局配置,可以包含多个location块。可配置本虚拟机监听的端口,设置虚拟机名称,多个server监听同一个端口。
	server {
		listen 			80; #监听端口
		server_name;	localhost; #server的域名,配置多个虚拟主机时用到
		location / {
			root	html;
			index	index.html index.htm; #网站默认主页
		}
		error_page 500 502 503 504 /50x.html; #错误页面
		##location处理对应的不同错误码的页面定义到50x.html,指示了50.html文件所在目录
		location = /50x.html { 	
        	root	html;   #错误页面文件所在目录
		}
	}
	
	##和邮件相关的配置
    #mail {
    #               ...
    #}         mail 协议相关配置段
    #tcp代理配置,1.9版本以上支持

    #stream {
    #               ...
    #}       stream 服务器相关配置段
    #导入其他路径的配置文件
    #include /apps/nginx/conf.d/*.conf
}

全局配置

main 全局配置块常见的配置指令分类

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

全局配置说明

user	nginx nginx; #启动nginx工作进程的用户和组
worker_processes [number | auto]; #启动nginx工作进程的数量,一般和CPU核心数相同
worker_cpu_affinity 00000001 00000010 00000100 00001000; #将Nginx工作进程绑定到指定的CPU核心,默认Nginx是不进行进程绑定的,绑定并不是意味着当前nginx进程独占以一核心CPU,但是可以保证此进程不会运行在其他核心上,这就极大减少了nginx的工作进程在不同的cpu核心上的来回跳转,减少了CPU对进程的资源分配与回收以及内存管理等,因此可以有效的提升nginx服务器的性能。
CPU MASK: 00000001:0号CPU
          00000010:1号CPU
  		  10000000:7号CPU
  		  
##示例:
[root@test conf]# egrep "processes|affinity" nginx.conf
worker_processes 4;	 #启动四个worker进程
worker_cpu_affinity 0001 0010;   #将workr进程绑定到 0号CPU和1号CPU

[root@test conf]# lscpu | grep CPU\(s\)   # CPU核数为2
CPU(s):                2
On-line CPU(s) list:   0,1
NUMA node0 CPU(s):     0,1

[root@test conf]# nginx -t  #语法检查出现警告,因为worker进程数比CPU核心数多。多出的worker进程将绑定在‘上一个CPU核心‘也即0010上。对于‘上一个CPU核心’(last mask for remaining worker)的解释: processes:nginx分别将worker进程绑定到worker_cpu_affinity 指定的CPU核心上(从左至右的顺序),而从第三个work进程起并未指定对应的CPU核心,因此全部绑定到‘上一个CPU核心’ 0010这个CPU核心。
nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
nginx: [warn] the number of "worker_processes" is not equal to the number of "worker_cpu_affinity" masks, using last mask for remaining worker processes
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful
[root@test conf]# ps axo pid,cmd,psr | grep nginx
   827 nginx: master process /apps   0
  1226 nginx: worker process         0
  1227 nginx: worker process         1
  1228 nginx: worker process         1
  1229 nginx: worker process         1
  1249 grep --color=auto nginx       0

#将worker进程数量改为2
[root@test conf]# vim nginx.conf
[root@test conf]# egrep "processes|affinity" nginx.conf
worker_processes 2;
worker_cpu_affinity 0001 0010;
#语法检查不再警告
[root@test conf]# nginx -s reload  
[root@test conf]# nginx -t
nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful
[root@test conf]# ps axo pid,cmd,psr | grep nginx
   827 nginx: master process /apps   1
  1261 nginx: worker process         0
  1262 nginx: worker process         1
  1265 grep --color=auto nginx       1
 
 
#错误日志记录配置,语法:error_log file [debug | info | notice | warn | error | crit | alert | emerg]  #括号内为日志记录详细级别(从左至右逐渐提高)

##示例配置
#error_log logs/error.log;
#error_log logs/error.log notice;
error_log /apps/nginx/logs/error.log error;

#pid文件保存路径
pid       /apps/nginx/logs/nginx.pid;
worker_priority 0; #工作进程优先级,-20~20(19)
worker_rlimit_nofile 65536; #所有worker进程能打开的文件数量上限,包括:Nginx的所有连接(例如与代理服务器的连接等),而不仅仅是与客户端的连接。该值最好与ulimit -n 或者limits.conf的值保持一致,

#通过pam限制文件打开数量上限
[root@centos8 ~]#cat /etc/security/limits.conf
*               soft   nofile          1000000
*               hard   nofile          1000000

#worker进程优先级
[root@test conf]# grep priority nginx.conf
worker_priority 0;
[root@test conf]# ps -axo pid,cmd,nice | grep nginx
   827 nginx: master process /apps   0
  1391 nginx: worker process         0
  1392 nginx: worker process         0
  1449 grep --color=auto nginx       0
  
daemon off;  #前台运行Nginx服务,通常在测试环境或者docker环境中使用
master_process off|on; #是否开启Nginx的master-worker工作模式,仅用于开发调试场景,默认为on
events {
   worker_connections  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
}

范例:实现nginx的高并发配置

[root@localhost conf]# ulimit -n 
10
[root@localhost conf]# cat /apps/nginx/conf/nginx.conf | grep rlimit
worker_rlimit_nofile 100;
#默认配置不支持高并发,当worker_rlimit_nofile设置的值大于ulimit -n的值,会出现以下错误日志
[root@localhost conf]# ab -c 5000 -n 10000 http://127.0.0.1/
This is ApacheBench, Version 2.3 <$Revision: 1430300 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 127.0.0.1 (be patient)
socket: Too many open files (24)     #打开的文件描述符过多

http 配置块

http 协议相关的配置结构

http {
	...
 	...  
 	server {    #每个server用于定义一个虚拟主机,第一个server为默认虚拟服务器
 		...
	}
 	server {     
 		...
 		server_name   #虚拟主机名
        root     #主目录
        alias     #路径别名
        location [OPERATOR] URL {     #指定URL的特性
         	...
            if CONDITION {
            ...
            }
 		}
 	}
}

http 协议配置说明

http {
   include       mime.types; #导入支持的文件类型,是相对于/apps/nginx/conf目录
   default_type  application/octet-stream; #除mime.types中文件类型外,设置其它文件默认类型,访问其它类型时会提示下载不匹配的类型文件
#日志配置部分
    #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; #在开启了sendfile的情况下,合并请求后统一发送给客户端,必须开启sendfile
    #tcp_nodelay   off; #在开启了keepalived模式下的连接是否启用TCP_NODELAY选项,当为off时,延迟0.2s发送,默认On时,不延迟发送,立即发送用户响应报文。
    #keepalive_timeout 0;
  	keepalive_timeout  65 66; #设置会话保持时间,第二个值为响应首部:keep-Alived:timeout=65,可以和第一个值不同
    #gzip on; #开启文件压缩
    server {
    	listen       80; #设置监听地址和端口
       	server_name localhost; #设置server name,可以以空格隔开写多个并支持正则表达式,如:*.magedu.com www.magedu.* ~^www\d+\.magedu\.com$ default_server 
       	#charset koi8-r; #设置编码格式,默认是俄语格式,建议改为utf-8
       	#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;
        }
        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ \.php$ { #以http的方式转发php请求到指定web服务器
        #   proxy_pass   http://127.0.0.1;
        #}
        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        #location ~ \.php$ { #以fastcgi的方式转发php请求到php处理
        #   root           html;
        #   fastcgi_pass   127.0.0.1:9000;
        #   fastcgi_index index.php;
        #   fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
        #   include       fastcgi_params;
        #}
        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /\.ht { #拒绝web形式访问指定文件,如很多的网站都是通过.htaccess文件来改变自己的重定向等功能。
        #   deny all;
        #}
       location ~ /passwd.html {
           deny all;
       }
   }
    # another virtual host using mix of IP-, name-, and port-based configuration
    #
    #server { #自定义虚拟server
    #   listen       8000;
    #   listen       somename:8080;
    #   server_name somename alias another.alias;
    #   location / { 
    #       root   html;
    #       index index.html index.htm; #指定默认网页文件,此指令由ngx_http_index_module模块提供
    #   }
    #}
    # HTTPS server
    #
    #server { #https服务器配置
    #   listen       443 ssl;
    #   server_name localhost;
    #   ssl_certificate     cert.pem;
    #   ssl_certificate_key cert.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;
    #   }
    #}

MIME

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

#在响应报文中将指定的文件扩展名映射至MIME对应的类型
include          mime.types;
default_type     application/octet-stream;#除mime.types中的类型外,指定其它文件的默认MIME类型,浏览器一般会提示下载
types {
	text/html html;
    image/gif gif;
    image/jpeg jpg;
}

范例:

#未定义mime.types类型
[root@localhost nginx]# ll html/mime.types
ls: cannot access html/mime.types: No such file or directory

[root@localhost nginx]# curl localhost/test.php -I
HTTP/1.1 200 OK
Server: nginx/1.18.0
Date: Thu, 28 Jul 2022 11:23:54 GMT
Content-Type: application/octet-stream  #mime未定义的类型默认视为二进制文件处理(如果是浏览器访问,则会下载test.php文件)
Content-Length: 20
Last-Modified: Thu, 28 Jul 2022 11:19:48 GMT
Connection: keep-alive
Keep-Alive: timeout=66  #长连接显示的时长,由keepalive_timeout  65 66; 配置
ETag: "62e270d4-14"
Accept-Ranges: bytes

#修改默认文件类型
[root@localhost nginx]# cat conf/nginx.conf | grep default_type
    default_type  text/html;
[root@localhost nginx]# nginx -s reload
[root@localhost nginx]# curl localhost/test.php -I
HTTP/1.1 200 OK
Server: nginx/1.18.0
Date: Thu, 28 Jul 2022 11:32:15 GMT
Content-Type: text/html     #将test.php识别为文本文件(如果是浏览器访问,直接显示文件内容)
Content-Length: 20
Last-Modified: Thu, 28 Jul 2022 11:19:48 GMT
Connection: keep-alive
Keep-Alive: timeout=66
ETag: "62e270d4-14"
Accept-Ranges: bytes

指定响应报文

#是否在响应报文中的Content-Type显示指定的字符集,默认off不显示
charset charset | off;
#示例
charset utf-8;
#是否在响应报文的Server首部显示nginx版本
server_tokens on | off | build | string;

范例:源码修改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

核心配置示例

虚拟主机的实现

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

新建两个虚拟主机

# 添加域名解析
[root@localhost conf.d]# cat /etc/hosts |grep test
172.16.16.88   pc.test.org  mobile.test.org

## 开始新建虚拟主机
root@localhost nginx]# mkdir /apps/nginx/conf/conf.d
[root@localhost nginx]# cd /apps/nginx/conf/conf.d/
[root@localhost conf.d]# vim /apps/nginx/conf/nginx.conf
   ......
   include /apps/nginx/conf.d/*.conf; #在配置文件的最后面添加此行,注意不要放在最前面,会导致前面的配置无法生效(文件配置从上到下依次生效)
[root@localhost conf.d]# cat pc.conf 
server {
  listen 80;
  server_name pc.test.org;
  location / {
    root html/pc;
  }
}
[root@localhost conf.d]# mkdir /apps/nginx/html/pc
[root@localhost conf.d]# echo pc_page > /apps/nginx/html/pc/index.html
[root@localhost conf.d]# nginx -s reload
[root@localhost conf.d]# curl pc.test.org   #虚拟主机pc
pc_page

[root@localhost conf.d]# cat mobile.conf 
server {
  listen 80;
  server_name mobile.test.org;
  location / {
    root html/mobile;
  }
}
[root@localhost conf.d]# mkdir /apps/nginx/html/mobile  #虚拟主机mobile
[root@localhost conf.d]# echo mobile_page > /apps/nginx/html/mobile/index.html
mobile_page

root 与 alias 的区别

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

范例:

[root@localhost conf.d]# cat pc.conf 
server {
  listen 80;
  server_name pc.test.org;
  location / {
    root html/pc;
  }

  location /about {
    root /opt/html;   #实际路径为/opt/html/about/index.html
  }
}
[root@localhost conf.d]# ll /opt/html/about/
total 4
-rw-r--r-- 1 root root 11 Jul 28 23:24 index.html
[root@localhost conf.d]# cat /opt/html/about/index.html 
about_page
[root@localhost conf.d]# nginx -s reload
[root@localhost conf.d]# curl pc.test.org/about/
about_page

alias:定义路径别名,会把访问的路径重新定义到其指定的路径,文档映射的另一种机制;仅能用于location上下文,此指令使用较少

范例:

[root@localhost conf.d]# cat pc.conf 
server {
  listen 80;
  server_name pc.test.org;
  location / {
    root html/pc;
  }

  location /about {
     alias /opt/html;  #实际路径为/opt/html/index.html
  }
}
[root@localhost conf.d]# cat /opt/html/index.html 
about_page
[root@localhost conf.d]# nginx -s reload
[root@localhost conf.d]# curl pc.test.org/about/
about_page

localtion 的匹配规则

在一个server中location配置段可存在多个,用于实现从uri到文件系统的路径映射;ngnix会根据用户请

求的URI来检查定义的所有location,按一定的优先级找出一个最佳匹配,而后进行处理。

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

#语法规则:
location [ = | ~ | ~* | ^~ ] uri { ... }
=   #用于标准uri前,需要请求字串与uri精确匹配,大小敏感,如果匹配成功就停止向下匹配并立即处理请求
^~  #用于标准uri前,表示包含正则表达式,并且匹配以指定的正则表达式开头,对URI的最左边部分做匹配检查,不区分字符大小写
~   #用于标准uri前,表示包含正则表达式,并且区分大小写
~*  #用于标准uri前,表示包含正则表达式,并且不区分大小写
不带符号 #匹配起始于此uri的所有的uri
\   #用于标准uri前,表示包含正则表达式并且转义字符。可以将 . * ?等转义为普通符号

#匹配优先级从高到低:
=, ^~, ~/~*, 不带符号

官方范例

location = / {
   [ configuration A ]
}
location / {
   [ configuration B ]
}
location /documents/ {
   [ configuration C ]
}
location ^~ /images/ {
   [ configuration D ]
}
location ~* \.(gif|jpg|jpeg)$ {
   [ configuration E ]
}
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, and the “/documents/1.jpg” 
request will match configuration E.

匹配案例-精确匹配

在server部分使用location配置一个web界面,例如:当访问nginx服务器的/logo.jpg的时候要显示指定html文件的内容

精确匹配一般用于匹配网站logo等相对固定的URL

范例:精确匹配

[root@localhost images]# cat /apps/nginx/conf.d/pc.conf 
server {
  listen 80;
  server_name pc.test.org;
  location / {
    root html/pc;
  }

  location /logo.jpg {
     root html/images;
  }
}
[root@localhost images]# ll /apps/nginx/html/images/logo.jpg 
-rw-r--r-- 1 root root 13110 Jul 29 15:11 /apps/nginx/html/images/logo.jpg

#访问成功
[root@localhost images]# curl pc.test.org/logo.jpg -I
HTTP/1.1 200 OK
Server: nginx/1.18.0
Date: Fri, 29 Jul 2022 15:17:35 GMT
Content-Type: image/jpeg
Content-Length: 13110
Last-Modified: Fri, 29 Jul 2022 07:11:49 GMT
Connection: keep-alive
Keep-Alive: timeout=66
ETag: "62e38835-3336"
Accept-Ranges: bytes

匹配案例-区分大小写

~ 实现区分大小写的模糊匹配

[root@localhost images]# cat /apps/nginx/conf.d/pc.conf 
server {
  listen 80;
  server_name pc.test.org;
  location / {
    root html/pc;
  }

  location ~ /A.?\.jpg {   #匹配字母A开头的jpg图片,后面?表示A后面零次或一个字符
     root html/images;
  }
}

#确保资源存在
[root@localhost images]# ll /apps/nginx/html/images/A.jpg 
-rw-r--r-- 1 root root 13110 Jul 29 15:11 /apps/nginx/html/images/A.jpg
[root@localhost images]# nginx -s reload

#以大写URI访问成功
[root@localhost images]# curl -I pc.test.org/A.jpg
HTTP/1.1 200 OK
Server: nginx/1.18.0
Date: Fri, 29 Jul 2022 15:27:52 GMT
Content-Type: image/jpeg
Content-Length: 13110
Last-Modified: Fri, 29 Jul 2022 07:11:49 GMT
Connection: keep-alive
Keep-Alive: timeout=66
ETag: "62e38835-3336"
Accept-Ranges: bytes

#以小写URI访问失败
[root@localhost images]# curl -I pc.test.org/a.jpg
HTTP/1.1 404 Not Found
Server: nginx/1.18.0
Date: Fri, 29 Jul 2022 15:27:55 GMT
Content-Type: text/html
Content-Length: 153
Connection: keep-alive
Keep-Alive: timeout=66

匹配案例-不区分大小写

~* 用来对用户请求的uri做模糊匹配。

注意:尽管匹配时不区分大小写,但实际请求是仍会以用户请求的uri去寻找相应的磁盘文件,如用户访问uri为/A.jpg,在location条件通过后就在对应路径下寻找磁盘中的A.jpg文件,如果磁盘上是a.jpg,则请求是失败的(在window系统中,文件名不区分大小写,该请求会成功——受文件系统影响)。

[root@localhost images]# cat /apps/nginx/conf.d/pc.conf 
server {
  listen 80;
  server_name pc.test.org;
  location / {
    root html/pc;
  }

  location ~* /A.?\.jpg {  #匹配规则不区分大小写
     root html/images;
  }
}
[root@localhost images]# ll /apps/nginx/html/images/a.jpg  #磁盘中仅存在a.jpg文件
-rw-r--r-- 1 root root 13110 Jul 29 15:11 /apps/nginx/html/images/a.jpg
[root@localhost images]# nginx -s reload

#访问/a.jpg成功
[root@localhost images]# curl -I pc.test.org/a.jpg
HTTP/1.1 200 OK
Server: nginx/1.18.0
Date: Fri, 29 Jul 2022 15:41:25 GMT
Content-Type: image/jpeg
Content-Length: 13110
Last-Modified: Fri, 29 Jul 2022 07:11:49 GMT
Connection: keep-alive
Keep-Alive: timeout=66
ETag: "62e38835-3336"
Accept-Ranges: bytes

#访问/A.jpg失败。location匹配成功,但磁盘上并无A.jpg文件
[root@localhost images]# curl -I pc.test.org/A.jpg
HTTP/1.1 404 Not Found
Server: nginx/1.18.0
Date: Fri, 29 Jul 2022 15:41:48 GMT
Content-Type: text/html
Content-Length: 153
Connection: keep-alive
Keep-Alive: timeout=66

nginx 四层访问控制

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

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

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

范例:

## 匹配时按从上至下的规则进行匹配,匹配到相应规则即停止———与防火墙的匹配规则类似
#如:有客户端(IP:10.1.1.0)访问配置了以下规则的web服务器时(访问URI:/about),触发location /about语句块,匹配到allow 10.1.1.0/16,访问控制生效,访问成功。

location = /login/ {
   root /data/nginx/html/pc;
   allow 10.0.0.0/24;
   deny all;
 }
location /about {
   alias /data/nginx/html/pc;
   index index.html;
   deny  192.168.1.1;
   allow 192.168.1.0/24;
   allow 10.1.1.0/16;
   allow 2001:0db8::/32;
   deny all;  #按先小范围到大范围排序
 }

nginx 账户认证功能

由 ngx_http_auth_basic_module 模块提供此功能

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

范例:

#CentOS安装包
[root@centos8 ~]#yum -y install httpd-tools
#Ubuntu安装包
[root@Ubuntu ~]#apt -y install apache2-utils

#创建用户
#-b 非交互式方式提交密码
#-c 重新生成文件,覆盖已有文件。首次创建时使用
[root@localhost html]# htpasswd -bc /apps/nginx/conf/.htpasswd user1 passwd1
Adding password for user user1
[root@localhost html]# htpasswd -b /apps/nginx/conf/.htpasswd user2 passwd2
Adding password for user user2

#生成了带有两个用户的验证文件
[root@localhost html]# tail /apps/nginx/conf/.htpasswd 
user1:$apr1$vzRe30iJ$jF8BZbra6pI8O0JBqlmiP/
user2:$apr1$i2ON7LYs$pxzkeH.xxCdgj670m5cSW/

#网站登录页面配置
[root@localhost html]# cat /apps/nginx/html/index.html 
hello
[root@localhost html]# cat /apps/nginx/conf.d/pc.conf 
server {
  listen 80;
  server_name pc.test.org;
  location /login {
    alias html/;
    index index.html;
    auth_basic "login password";  #指定提示文本信息
    auth_basic_user_file /apps/nginx/conf/.htpasswd;  #指定使用的验证文件
  }
}

#直接访问登录页,失败。未通过验证
[root@localhost html]# curl pc.test.org/login/
<html>
<head><title>401 Authorization Required</title></head>
<body>
<center><h1>401 Authorization Required</h1></center>
<hr><center>nginx/1.18.0</center>
</body>
</html>

##分别使用两种方式输入用户名和密码验证
[root@localhost html]# curl http://user1:passwd1@pc.test.org/login/
hello
[root@localhost html]# curl -u user2:passwd2 pc.test.org/login/
hello

自定义错误页面

自定义错误页,同时也可以用指定的响应状态码进行响应, 可在如下语句块配置:http, server, location, if in

location

格式:

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

范例:

# 准备站点配置
[root@localhost html]# cat /apps/nginx/conf.d/pc.conf 
server {
  listen 80;
  server_name pc.test.org;
  error_page 404 400  /error.html;   #访问不存在的页面,发生404错误,返回error.html错误页面
  location /error.html {
    root html/;
  }
}
#准备错误页面
[root@localhost html]# cat /apps/nginx/html/error.html 
error-page

[root@localhost html]# nginx -s reload

#访问不存在的页面,触发404报错
[root@localhost html]# curl -I pc.test.org/dd
HTTP/1.1 404 Not Found   #查看错误码
Server: nginx/1.18.0
Date: Fri, 29 Jul 2022 17:02:12 GMT
Content-Type: text/html
Content-Length: 11
Connection: keep-alive
Keep-Alive: timeout=66
ETag: "62e411d9-b"

#触发404错误,返回错误页面(如果是浏览器测试,建议用google)
[root@localhost html]# curl pc.test.org/dd
error-page

范例:如果发生404 ,将错误码定义为502,且跳转到主页/index.html

#站点配置
[root@localhost html]# cat /apps/nginx/conf.d/pc.conf 
server {
  listen 80;
  server_name pc.test.org;
  error_page 404 =502  /index.html;
  location /index.html {
    root html/;
  }
}
#主页配置
[root@localhost html]# cat /apps/nginx/html/index.html 
hello
[root@localhost html]# nginx -s reload
[root@localhost html]# curl pc.test.org/dd/
hello

#验证错误码
[root@localhost html]# curl pc.test.org/dd/ -I
HTTP/1.1 502 Bad Gateway  #错误码为自定义的502
Server: nginx/1.18.0
Date: Fri, 29 Jul 2022 17:31:49 GMT
Content-Type: text/html
Content-Length: 6
Connection: keep-alive
Keep-Alive: timeout=66
ETag: "62e40fa4-6"

#重定向成功
[root@localhost html]# cat /apps/nginx/html/index.html 
hello

自定义错误日志

错误日志格式

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 html]# cat /apps/nginx/conf.d/pc.conf 
server {
  listen 80;
  server_name pc.test.org;
  error_page 404 400  /error.html;
  access_log /apps/nginx/logs/test-access.log;  #自定义正常访问日志
  error_log /apps/nginx/logs/test-error.log;   #自定义错误日志
  location /error.html {
    root html/;
  }
}
#当前已有日志文件
[root@localhost html]# ls /apps/nginx/logs/
access.log  error.log  nginx.pid

#重启nginx后生成自定义的错误日志
[root@localhost html]# nginx -s reload
[root@localhost html]# ls /apps/nginx/logs/
access.log  error.log  nginx.pid  test-access.log  test-error.log

#访问站点
[root@localhost html]# curl pc.test.org
hello

#日志成功记录
[root@localhost html]# tail /apps/nginx/logs/{test-access,test-error}.log
==> /apps/nginx/logs/test-access.log <==
172.16.16.88 - - [30/Jul/2022:01:17:55 +0800] "GET / HTTP/1.1" 200 6 "-" "curl/7.29.0"

==> /apps/nginx/logs/test-error.log <==

检测文件是否存在

try_files会按顺序检查文件是否存在,返回第一个找到的文件或文件夹(结尾加斜线表示为文件夹),如

果所有文件或文件夹都找不到,会进行一个内部重定向到最后一个参数。只有最后一个参数可以引起一

个内部重定向,之前的参数只设置内部URI的指向。最后一个参数是回退URI且必须存在,否则会出现内

部500错误。

Syntax: try_files file ... uri;
try_files file ... =code;
Default: —
Context: server, location

范例: 如果不存在页面, 就转到default.html页面

#准备站点配置
[root@localhost html]# cat /apps/nginx/conf.d/pc.conf 
server {
  listen 80;
  server_name pc.test.org;
  location / {
      root html/;
      index index.html;
      try_files $uri $uri.html $uri/index.html /about/default.html;
  }
}
#准备默认页面
[root@localhost html]# cat /apps/nginx/html/default.html 
default
#访问测试
[root@localhost ~]# cat /apps/nginx/html/about/default.html 
about_page
[root@localhost ~]# curl pc.test.org/xx/
about_page
[root@localhost ~]# curl pc.test.org/xx.html
about_page

##自定义响应码
[root@localhost ~]# cat /apps/nginx/conf.d/pc.conf 
server {
  listen 80;
  server_name pc.test.org;
  location / {
      root html/;
      index index.html;
      try_files $uri $uri.html $uri/index.html =555;  #自定义响应码为555
  }
}
#验证结果
[root@localhost ~]# curl pc.test.org/xx.html -I
HTTP/1.1 555   #响应码为555
Server: nginx/1.18.0
Date: Mon, 01 Aug 2022 10:00:03 GMT
Content-Length: 0
Connection: keep-alive
Keep-Alive: timeout=66

长连接配置

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

范例:

#站点主配置项
[root@localhost ~]# cat /apps/nginx/conf/nginx.conf | grep keepalive
    keepalive_requests 3;
    keepalive_timeout 65 60;
[root@localhost ~]# cat /apps/nginx/html/index.html 
hello

#长连接测试
[root@localhost ~]# telnet localhost 80
Trying ::1...
telnet: connect to address ::1: Connection refused
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
GET / HTTP/1.1      #发起get请求,重复三次或者时间到达65秒后,本次链接自动终止
HOST: localhost     #域名为localhost

HTTP/1.1 200 OK
Server: nginx/1.18.0
Date: Mon, 01 Aug 2022 11:03:09 GMT
Content-Type: text/html
Content-Length: 6
Last-Modified: Fri, 29 Jul 2022 16:49:40 GMT
Connection: keep-alive
Keep-Alive: timeout=60  #显示的超时时间
ETag: "62e40fa4-6"
Accept-Ranges: bytes

hello    #返回的页面内容    

作为下载服务器

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

配置使用

官方链接:http://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提供
set $limit_rate 4k; #也可以通变量限速,单位B/s,同时设置,此项优级高于limit_rate

###Rate limit can also be set in the $limit_rate variable, however, since version 1.17.0, this method is not recommended:

范例:将nginx作为下载服务器

#注意:download不需要index.html文件
[root@centos8 ~]# mkdir -p /data/nginx/html/pc/download
[root@localhost ~]# touch /apps/nginx/html/download/{t1,t2,t3}.txt
[root@localhost ~]# mkdir /apps/nginx/html/download/{d1,d2,d3}
[root@localhost ~]# tree /apps/nginx/html/download
/apps/nginx/html/download
├── d1
├── d2
├── d3
├── t1.txt
├── t2.txt
└── t3.txt

3 directories, 3 files

[root@centos8 ~]# cat /apps/nginx/conf.d/pc.conf
 location /download {
   autoindex on;    #自动索引功能
   autoindex_exact_size   off; #计算文件确切大小(单位bytes),此为默认值,off只显示大概大
小(单位kb、mb、gb)  
   autoindex_localtime   off; #on表示显示本机时间而非GMT(格林威治)时间,默为为off显示GMT
时间
   limit_rate 1024k;   #限速,默认不限速
   root html/;
}

结果验证

image-20220801113728007

作为上传服务器

相关指令

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位作为目录名
[root@centos8 ~]# md5sum /data/nginx/html/pc/index.html 
95f6f65f498c74938064851b1bb 96 3d 4 /data/nginx/html/pc/index.html
1级目录占1位16进制,即2^4=16个目录  0-f
2级目录占2位16进制,即2^8=256个目录 00-ff
3级目录占2位16进制,即2^8=256个目录 00-ff
#配置示例:
client_max_body_size 100m; #如果太大,上传时会出现413错误。注意:如果php上传(如WordPress),还需要修改/etc/php.ini的相关配置
client_body_buffer_size 1024k;
client_body_temp_path   /apps/nginx/client_body_temp/ 1 2 2; #上传时,Nginx会自动创建相关目录

##上传文件后,会自动生成相关目录
[root@wang-liyun-pc ~]# tree /apps/nginx/client_body_temp/
/apps/nginx/client_body_temp/
├── 5
│   └── 00
│       └── 00
└── 6
   └── 00
       └── 00

其他配置

keepalive_disable none | browser ...;  #对哪种浏览器禁用长连接
limit_except method ... { ... } #仅用于location语句块,禁止客户端使用除了指定的请求方法之外的其它方法, 如果使用会出现403错误
method:GET, HEAD, POST, PUT, DELETE,MKCOL, COPY, MOVE, OPTIONS, PROPFIND, PROPPATCH, LOCK, UNLOCK, PATCH

##示例:除了GET之外的其它方法仅允许172.16.16.0/24网段主机使用
[root@localhost ~]# hostname -I  #本机IP
172.16.16.88 
[root@localhost ~]# ll /apps/nginx/html/upload/  #新建upload目录用于存储上传的文件
total 0
[root@localhost ~]# cat /apps/nginx/conf.d/pc.conf 
server {
  listen 80;
  server_name pc.test.org;
  
  location /upload {
      root html/;
	  index index.html;
 	  limit_except GET {
      	  allow 172.16.16.88;
	      deny all;
      }
   }
}
[root@localhost ~]# nginx -s reload
[root@localhost ~]# curl -XPUT /etc/issue pc.test.org/upload
curl: (3) <url> malformed
<html>
<head><title>405 Not Allowed</title></head>  #PUT方法具有访问权限,但是程序本身不支持文件上传功能
<body>
<center><h1>405 Not Allowed</h1></center>
<hr><center>nginx/1.18.0</center>
</body>
</html>

[root@localhost ~]# cat /apps/nginx/conf.d/pc.conf 
server {
  listen 80;
  server_name pc.test.org;
  
  location /upload {
        root html/;
	index index.html;
 	limit_except GET {
        #allow 172.16.16.88;  #禁止所有主机使用GET以外的方法
	    deny all;
        }
   }
}
[root@localhost ~]# curl -XPUT /etc/issue pc.test.org/upload
curl: (3) <url> malformed
<html>
<head><title>403 Forbidden</title></head> #再次访问测试,nginx拒绝访问
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx/1.18.0</center>
</body>
</html>
aio on | off  #是否启用asynchronous file I/O(AIO)功能,需要编译时添加参数开启 --with-file-aio
#linux 2.6以上内核提供以下几个系统调用来支持aio: 1、SYS_io_setup:建立aio 的context
2、SYS_io_submit: 提交I/O操作请求
3、SYS_io_getevents:获取已完成的I/O事件
4、SYS_io_cancel:取消I/O操作请求
5、SYS_io_destroy:毁销aio的context
directio size | off; #操作完全和aio相反,aio是读取文件而directio是写文件到磁盘,默认为关闭,当文件大于等于给定大小时,例如:directio 4m,同步(直接)写磁盘,而非写缓存。
open_file_cache off;  #是否缓存打开过的文件信息
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; #最大缓存10000个文件,非活动数据超时时长60s
open_file_cache_valid   60s;  #每间隔60s检查一下缓存数据有效性
open_file_cache_min_uses 5; #60秒内至少被命中访问5次才被标记为活动数据
open_file_cache_errors   on; #缓存错误信息