nginx:配置文件(nginx.conf)各项说明
学习自:
Nginx nginx.conf配置文件详解_nginxconf配置详解_一片星空~的博客-CSDN博客
Nginx基础和原理介绍_nginx原理_khuangliang的博客-CSDN博客
Nginx配置文件详解_nginx default_type-CSDN博客
Nginx中的location和root配置_笔记大全_设计学院
【精选】Nginx教程(系统详细)_nginx详细教程-CSDN博客
Nginx官方文档:Nginx
0、常用
1)完整匹配的URI为server_name:listen/location
2)server_name默认值:localhost、127.0.0.1
3)listen默认值:80
4)root:location匹配到的请求会去root目录下找响应文件
5)一个server代表一个host,相当于URI的前缀,可以有多个后缀,用location表示。
6)root的相对路径是以conf目录所在的目录为起始(即NG的安装路径);
关于匹配:
1)最先看listen,listen不对的直接跳过
一个server可以有多个listen,最先进行匹配的是listen,如果匹配不上直接跳过该server;如果listen的是端口,则只匹配端口即可;如果listen后是ip+端口,那必须保证本机的IP和端口都匹配上,其中有一个匹配不上都会跳过;
2)listen相同的,看server_name和url前缀的匹配程度,最适配的会匹配
如果有多个相同listen端口的server,那么会根据URL前缀去匹配server_name;当有url匹配上server_name,就用这条server的规则;
3)如果所有的server_name和url前缀都不匹配,会使用默认server(由default_server标识)
4)如果没有default_server就用第一个server。
一、配置文件结构
worker_processes 1; #全局块 events { #events块 worker_connections 1024; } http { #http块 include mime.types; #http全局块 default_type application/octet-stream; sendfile on; keepalive_timeout 65; server { #server块 ... #server全局块
location{
...
}
}
}
nginx配置文件由三部分组成:1、全局块(events之前的部分);2、events块(events{...});3、http块(http{...})。
1、全局块(events之前的部分)
从配置文件开始到events块之间的内容,主要设置一些影响nginx服务器整体运行的配置指令,主要包括:1)运行Nginx服务器的用户(组);2)允许生成的Worker进程数;3)进程PID存放路径;4)日志存放路径和类型;5)配置文件的引入……。
上文第一行配置的:
worker_processes 1;
这是Nginx并发处理服务的关键配置,worker_processes值越大,可以支持的并发处理量越多,但是会受到硬件、软件等设备的制约。
2、events块(events{...})
NGINX采用的异步非阻塞的事件驱动机制。
events块涉及的是Nginx服务器与用户的网络连接,常用的设置包括1)是否开启对多worker进程下的网络连接进行序列化;2)是否允许同时接收多个网络连接;3)选取哪种事件驱动模型来处理连接请求;4)每个worker进程可以同时支持的最大连接数(即上文的worker_connections);
上文中events块为
events { worker_connections 1024; }
代表每个worker进程支持的最大连接数为1024。
该部分对Nginx性能影响较大,在实际中应该灵活配置。
3、http块(http{...})
定义HTTP协议的处理行为。
这部分是nginx服务器配置中最频繁的部分,代理、缓存、日志定义等绝大多数功能和第三方模块配置都放在这里。
http块包括http全局块、server块。一个http块可以嵌套多个server块,一个server就代表一个虚拟主机或host(Web服务器),例如www.cnblogs.com(一个host是指一个完整IP或三级、四级域名组)
http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; server { ...
location{
...
}
}
1)http全局块(server块以外部分)
全局块配置的指令包括文件引入(include)、MIME-TYPE定义、日志自定义、连接超时时间、单链接请求数上限。
2)server块(server{...})
该块与虚拟主机有密切联系,从逻辑上看,虚拟主机与一台独立的硬件主机没什么区别(访问一个主机的两种方式:IP、域名)。
每个http块可以包括多个server块,而每个server块就相当于一个WEB服务器。每个server块分为全局server块、location块。
①全局server块
最常见的配置是1)本虚拟机的监听配置(listen项);2)本虚拟机的名称或IP配置(server_name项)。
②location块
一个server块可以配置多个location块。
这块的主要作用是基于Nginx服务器收到的请求字符串(如server_name/url-string),对server_name之外的字符串(如url-string)进行匹配,对匹配到的请求进行处理。地址定向、数据缓存、应答控制等功能。
还有许多第三方模块的配置也在该处进行。
下面举例说明什么是server和location:
https://editor.csdn.net/md/
- server:editor.csdn.net
- location:/md/
https://www.cnblogs.com/index.html
- server:www.cnblogs.com
- location:/index.html
可见:
- server就是//之后那一截(不带结尾的/);
- location就是server之后的全部(开头带/);
注意
- 如果只有server,没有location,那么会采用默认location /,即在server后加/
- 如果有了location,那么最后不会自动加斜杠,location的末尾有无斜杠代表了两个不同的location:location后的url末尾有/,则该url会被识别为一个目录;否则会识别为一个文件(更详细说明见location后缀)。
二、配置文件中的指令和变量
NGINX配置文件由指令和变量组成。
1)指令
指令分为简单指令和块指令。
简单指令:名称+参数,以分号;结尾。
块指令:以一组由{ }包围的附加指令结尾。块指令也称为上下文,如events、http、server、location。
块指令用于划分区域块,具有一定的层次关系,例如http块中可以有多个server块,server块中可以包含多个location块。
2)变量
NGINX的不同模块中有不同的变量,使用这些变量可以简化配置并提高配置的灵活性。
变量的访问方式:$变量名,如$server_port。
NGINX变量分为内置变量、自定义变量。
内置变量放在ngx_http_core_module中,代表请求与应答的字段信息,例如,C端请求Header中的$http_user_agent、$http_cookie等;请求参数名$arg_name,传给C端的字节数$bytes_sent。
具体内置变量的列表及细节可以参考Nginx内置变量详解-CSDN博客。
自定义变量,在块中用set命令声明。写法:set $变量名 变量值。
三、例子
说明
- 配置文件的每项(一行)都以分号结尾;
- 每次对于配置文件的修改,都要重启nginx才能生效。
1)例1
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
include include/*/vhost.conf;
include include/*.conf;
server {
listen 80;
server_name localhost;
location / {
root html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
配置项
配置项 |
说明 |
| 全局块 | |
| worker_processes 1 | worker进程的数量 |
| events块 | |
| worker_connections 1024 | 每个worker进程支持的最大连接数 |
| http块 | |
|
include mime.types |
引入conf目录下的配置文件 mime.types:文件扩展名-文件类型映射表 |
|
include include/*/vhost.conf include include/*.conf |
在conf目录下新建了一个include文件夹,相当于为不同host准备的配置文件 |
| default_type application/octet-stream | 默认的文件类型,默认为text/plain |
| sendfile on | 开启高效传输模式 |
|
http.server块 一个Server就代表一个虚拟host(下文server_name和listen分别代表host的IP和Port) |
|
| listen 80 |
监听的端口 默认80 |
|
server_name localhost server_name 127.0.0.1 |
监听的域名或IP 默认localhost、127.0.0.1 |
|
location / location /test |
匹配的后缀为/,完整匹配的URL为server_name:listen/ 匹配的后缀为/test,完整匹配的URL为ser_name:listen/test |
|
root html index index.html |
root:所有location匹配到的请求都会被转发到root指定的目录(如果以/开头就是绝对路径,如果不以/开头就是以nginx安装目录为起始目录的相对路径)下,后边的index指定的文件也是在该目录下的 index:默认的首页文件,如果有多个,则用空格分开 如果没有,默认就是index.html |
| error_page 500 502 /50x.html | 如果出现对应的http状态码(500,502)时,用/50x.html返回给用户 |
| location = /50x.html | 如果访问的是50x.html时 |
本例总结
由于本例是第一个例子,所以只用到了大部分NG配置通用的配置项,一些更具体和细节的配置之后的例子之后会进行补充说明
- 通过include项,引入某个配置文件,include后跟的路径是以conf目录为起点的;可以通过在conf下新建目录,再用include引入,以达到将不同的配置项加以分散,防止某个conf文件过大。
- 一个server块就代表一个host,一个host由IP、Port,host的IP由server_name指定,Port由listen指定;
- 一个location块代表URL中除host以外的后缀项,一个server只有一个host,但却可以有多个后缀,映射到多个html文件上,因此一个server可以有多个location块;
- location块的root项,代表这个后缀会被传到哪个目录下处理;index块代表传入这个目录时返回的默认首页文件。(Nginx中的location和root配置_笔记大全_设计学院)
- error_page指定了出现某种特定状态码该去哪个页面。
2)例2
#user admin admin;
#worker_processes 2;
#pid /nginx/pid/nginx.pid;
error_log log/error.log debug;
debug|info|notice|warn|error|crit|alert|emerg
events {
accept_mutex on;
multi_accept on;
#use epoll;
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
#access_log off;
log_format myFormat '$remote_addr–$remote_user [$time_local] $request $status $body_bytes_sent $http_referer $http_user_agent $http_x_forwarded_for';
access_log log/access.log myFormat;
sendfile on;
sendfile_max_chunk 100k;
keepalive_timeout 65;
upstream mysvr {
server 127.0.0.1:7878;
server 192.168.10.121:3333 backup;
}
error_page 404 https://www.baidu.com;
server {
keepalive_requests 120;
listen 4545;
server_name 127.0.0.1;
location ~*^.+$ {
#root path;
#index vv.txt;
proxy_pass http://mysvr;
deny 127.0.0.1;
allow 172.18.5.54;
}
}
}
配置项
配置项 |
说明 |
| 全局块 | |
| user admin admin | 配置用户和组,默认nobody nobody |
| worker_processes 2 | worker进程数,默认1 |
| pid /nginx/pid/nginx.pid | nginx的pid存放文件 |
| error_log log/error.log debug |
指定某种级别的日志存入某个路径。 级别:debug|info|notice|warn|error|crit|alert|emerg 该项可以放在全局、http、server下 |
| events块 | |
| accept_mutex on | 设置网络连接序列化,防止惊群现象 |
| multi_accept on | 设置一个进程是否同时接受多个网络连接,默认off |
| use epoll | 事件驱动模型:select|poll|kqueue|epoll|resig|/dev/poll|eventport |
| worker_connections 1024 | 最大连接数,默认512 |
| http块 | |
| include mime.types | 引入文件,文件扩展名-文件类型映射表 |
| default_type application/octet-stream |
Nginx响应前端请求默认的MIME类型,默认text/plain |
| log_format myFormat 'xxxxxxx' | 自定义日志格式,myFormat为这个格式的自定义命名 |
| access_log log/access.log myFormat | 将日志以myFormat这个格式输出到文件中 |
| sendfile on |
允许以sendfile的方式传输文件,默认off 可以在http、server、location块 |
| sendfile_max_chunk 100k | 每个进程每次调用传输数量不能大于设定的值,默认0,即无上限 |
| keepalive_timeout 65 | 连接超时时间,默认75s |
|
http.upstream块:负载均衡 upstream mysvr{ ... } #xxx为upstream的名 |
|
|
server 127.0.0.1:7878 server 192.168.10.121:3333 backup |
提供负载均衡的host backup:热备 |
| error_page 404 www.baidu.com | 错误页面 |
| server块 | |
| keepalive_requests 120 | 单连接请求上限次数 |
| listen 4545 | 监听的Port |
| server_name 127.0.0.1 | 监听的IP |
| location ~*^.+$ |
匹配的URL后缀 这里使用了正则 |
| location块 | |
| proxy_pass http://mysvr | 匹配到的URL会被转向上边mysvr定义的负载均衡服务器列表 |
| deny 127.0.0.1 | 拒绝的IP(来自该IP的请求会被拒绝访问) |
| allow 172.18.5.54 | 允许的IP(只允许该IP访问) |
本例总结
- 本例中引入了upstream块,即负载均衡块,同时取消了location块中的root和index项,代表匹配这一后缀的请求将被转向upstream定义的server列表;
- 在location块中,引入了deny和allow项,代表IP检查,除了需要后缀匹配之外,还要检查某些IP是否被加入黑名单或者准入策略中,注意这里的IP与之前的server_name的区别:server_name是URL中的一部分字段,这里的两个IP是请求头中源IP。
- default_type:浏览器中可以显示的内容有HTML、XML、GIF等文件、媒体资源,浏览器使用MIMEType来区分它们(Nginx配置文件详解_nginx default_type-CSDN博客)。所以MIME Type就是指网络资源的媒体类型。Nginx作为Web服务器,需要识别前端请求的资源类型。在NG的conf文件中,与MIME-Type类型相关的配置项有include和default_type。conf目录下的mime.types文件记录了有哪些MIME Type,这里列举几个常用的:
超文本标记语言文本 text/html; 普通文本 : text/plain; Json文件:application/json; 压缩文件.rar application/octet-stream;
upstream与proxy_pass
配置了upstream,那么这个upstream通常会被用到proxy_pass中。
用法:proxy_pass http://upstream服务器名,不用加$前缀。
即upstream单独不会起作用,只是为了统一管理proxy_pass转发的目的地址。
3)关于listen与server_name
本节学习自:【精选】Nginx教程(小白必看,看了必会,不看血亏),-CSDN博客
listen:配置网络监听
有几种写法,可以监听IP和Port:
1 listen *:80 | *:8080 #监听所有80端口和8080端口 2 listen IP_address:port #监听指定的地址和端口号 3 listen IP_address #监听指定ip地址所有端口 4 listen port #监听该端口的所有IP连接
server_name:虚拟主机配置
三种情况:
1)端口(listen)相同,域名(server_name)不同的虚拟主机
#当客户端访问www.lijie.com,监听端口号为80,直接跳转到data/www目录下文件
server {
listen 80;
server_name www.lijie.com;
location / {
root data/www;
index index.html index.htm;
}
}
#当客户端访问bbs.lijie.com,监听端口号为80,直接跳转到data/bbs目录下文件
server {
listen 80;
server_name bbs.lijie.com;
location / {
root data/bbs;
index index.html index.htm;
}
}
一些规则:
- 如果是域名模式,每个域名由两段或三段组成,每段用"."隔开;
- 可以有多个name,它们之间用空格隔开;
- 可以用通配符"*",但是只能用于三段式开头或结尾或两段式的结尾:
server_name *.123.com www.123.*
- 可以用正则表达式,用~作为name开头标记:
server_name ~^www\d+\.123\.com$; 该表达式“~”表示匹配正则表达式,以www开头(“^”表示开头), 紧跟着一个0~9之间的数字,在紧跟“.123.co”,最后跟着“m”($表示结尾)
2)server_name相同,端口(listen)不同
#当客户端访问www.lijie.com,监听端口号为8080,直接跳转到data/www目录下文件
server {
listen 8080;
server_name www.lijie.com;
location / {
root data/www;
index index.html index.htm;
}
}
#当客户端访问www.lijie.com,监听端口号为80直接跳转到真实ip服务器地址 127.0.0.1:8080
server {
listen 80;
server_name www.lijie.com;
location / {
proxy_pass http://127.0.0.1:8080;
index index.html index.htm;
}
}
3)server_name为IP
server_name 192.168.1.1
4)location路由块配置
1)uri匹配
学习自:nginx location 配置 正则表达式实例详解_nginx_脚本之家
语法
location [ = | ~ | ~* | ^~] uri {
}
功能
匹配不同的后缀,根据匹配结果执行相应的功能
符号
共4种,且不能同时出现。
| 符号 | uri要求 | 说明 |
| = | 不含正则 | 请求的URL与uri严格匹配 |
| ~ | 包含正则 | 区分大小写 |
| ~* | 不区分大小写 | |
| ^~ | 不含正则 | 当nginx服务器找到请求URL与uri匹配度最高的location之后,立刻用该location处理请求,而不再用location块中的正则uri和请求URL做匹配 |
| 空 | 区分大小写的前缀匹配 | |
| / | 匹配所有进来的url |
例子
1)=
精确匹配
#优先级1,精确匹配,根路径
location =/ {
return 400;
}
只会匹配http://www.abc.com
不会匹配http://www.abc.com/index.html
2)~
区分大小写的正则匹配
location ~ /Example/{
……
}
url中有Example会匹配成功
3)~*
不区分大小写的正则匹配
location ~* /Example/ {
……
}
url只要有Example、example就会匹配成功,因此下文两个URL都会匹配成功
http://abc.com/test/Example/(由于是正则匹配,所以example即使不是url的第一节也一样可以匹配成功,但是在进行root拼接时,仍然是从test开始拼接,即 root + /test/Example)
http://abc.com/example/
4)^~
无正则,只要前缀匹配上就行
location ^~ /index/{
……
}
只要server后跟的是index就会匹配成功
http://abc.com/index/index.html
http://abc.com/index/error.page
2)location内部指令
index:默认首页
语法
index filename ...; #后面的文件名称可以有多个,中间用空格隔开。 index index.html index.jsp;
功能
- 在用户请求访问网站时,可以不写首页名称;
- 对一个请求,根据请求内容不同设置不同的首页。
当index缺省时,首先看访问的url中,最后一节是否为文件,如security.html、error.html,如果是,则去root目录下找这些文件。如果不是,则默认去找index.html。
root:index文件所在的目录
proxy_pass:代理服务器的地址
语法
proxy_pass URL;#URL 为被代理服务器的地址,可以包含传输协议、主机名称或IP地址加端口号,URI等。 proxy_pass http://www.123.com/uri;
5)反向代理设置
nginx中有2个反向代理相关的配置项:proxy_pass、fastcgi_pass,前者使用标准HTTP协议转发,后者使用FastCGI协议转发,用于PHP等架构的环境。
proxy_pass(在location块中)
proxy_pass后的URL有两种写法:
#1、直接接要代理的地址
location ~ /edu/ {
proxy_pass http://127.0.0.1:8080
}
location ~ /vod/ {
proxy_pass http://127.0.0.1:8081
}
#2、接负载均衡upstream的name
upstream mysvr {
server 127.0.0.1:7878;
server 192.168.10.121:3333 backup; #热备
}
...
proxy_pass http://mysvr; #请求转向上面mysvr 定义的服务器列表
配置了proxy_pass之后,请求会被代理到哪个URL?
假设在地址栏输入http://192.168.1.1/proxy/test.html,那么location要匹配的后缀为/proxy/,根据proxy_pass最后是否加/,会被代理到两个不同的地址:
#传入的请求为http://192.168.1.1/proxy/test.html
#1、不加/,此时会在代理地址后引入后缀
location /proxy/ {
proxy_pass http://127.0.0.1:81; #代理到http://127.0.0.1:81/proxy/test.html
}
#2、加/,此时不会在代理地址后引入匹配到的后缀,而是将后缀之后的部分拼到proxy_pass之后
location /proxy/ {
proxy_pass http://127.0.0.1:81/; #代理到http://127.0.0.1:81/test.html
}
当加上了/,相当于是绝对根路径,则nginx不会把location中匹配的路径部分代理走;
如果没有/,则会把匹配的路径部分也给代理走。
location与proxy-pass末尾的斜杠
见:Nginx:location、proxy_pass中的斜杠/ - ShineLe - 博客园
6)nginx中的变量
说明
nginx中可以使用预定义和自定义的变量,为其赋值和使用其值。
nginx中的变量值只有字符串格式,需要用双引号括起。
语法
定义:set $变量名 变量值
使用: $变量名
set $var "hello world";
return $var
内置变量(已被官方定义好,可以直接通过$name使用)

常用变量
$uri:请求的uri中不带参数的部分
$request_uri:球球的uri中带参数的部分
localhost:8088/crow/index.html?name=id065&group=su # uri为/crow/index.html # request_uri为/crow/index.html?name=id065&group=su
7)return(常用于location块下)
①返回状态码
return 404;
②返回字符串
location /test {
return 200 'hello';
}
③地址跳转
location /test {
return http://www.baidu.com;
}
④返回自定义变量
set $name 'user123'; return 200 $name;
⑤返回内置变量
return $uri;
⑥返回日志信息
return 200 '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" "$http_x_forwarded_for"';
8)转发页:proxy相关
本节介绍与转发相关的配置项
基础:proxy_pass
下边所有和转发相关的配置都是建立在会用proxy_pass指定反向代理的目标后端服务这一基础上的:
proxy_pass url proxy_pass http://upstream
①错误页:error_page、proxy_intercept_errors
error_page 404 https://www.runnob.com; #错误页 proxy_intercept_errors on; #如果被代理服务器返回的状态码为400或者大于400,设置的error_page配置起作用。默认为off。
②只支持一种请求方法get或post:proxy_method get
proxy_method get; #支持客户端的请求方法。post或get;
如果想要只支持一种C端请求(默认多种都能接收)
③支持的http协议版本:proxy_http_version
proxy_http_version 1.0 ; #Nginx服务器提供代理服务的http协议版本1.0,1.1,默认设置为1.0版本
④定制转发的请求header:proxy_set_header
a、作用域:location块
b、语法:
proxy_set_header 参数 值
c、例子:
#配置示例
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_set_header Connection "";
proxy_http_version 1.1;
add_header Access-Control-Allow-Origin *;
proxy_pass http://127.0.0.1:8889;
}
假设:
客户端地址(请求服务的地址):192.168.1.1 nignx服务器地址:192.168.1.2 后端服务器地址:192.168.1.3
测试时,在C端输入nginx服务器的地址,即192.168.1.2进行访问。
d、参数
-
X-Real-IP
C端的真实IP,如果其后跟参数$remote_addr,那么后端服务器就能获取到真实的C端IP,也就是本例中的192.168.1.1。
未设置该项,默认为nginx的地址。
-
Host
如果Host后跟参数$proxyhost,那么指的是配置项proxy_pass后跟的host值,在本例中就是192.168.1.3,即服务器的IP地址;
若C端发来的请求header中有HOST字段,那么参数$http_host、$host表示的就是原始请求host,例如初始请求HOST的值为http://test.com,那么反向代理后还是http://test.com;
若C端发来的请求header中没有HOST字段,$host代表nginx服务器地址,本例中就是192.168.1.2。
$http_host并非一个固定值,它是$http_HEADER通配后的结果,这里的HEADER是指一系列的header属性,例如$http_content_type代表Header中content-type属性值,同理,$http_host就是Header中的host属性。
服务器名和后端服务器端口可以一起传送:
proxy_set_header Host $host:$proxy_port;
-
X-Forwarded-For
该变量可以取值:$proxy_add_x_forwarded_for和$remote_addr,在只有一个代理服务器转发的情况下,二者效果差不多,都可以真实显示出C端原始IP。
而在第二个nginx代理服务器上,X-Forwarded-For变为"用户真实IP,第一台nginx的IP"。
也就是说$proxy_add_x_forwarded_for会包含完整的路由转发过程中的所有IP,每经过一次转发,就会在后边贴上一个所经过的服务器IP。
-
request_uri
请求的原始URI
e、其他
- 获取真实的IP
proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
第一行:只要用户在浏览器中访问的域名绑定了 VIP(Virtual IP,负载均衡对外暴露的IP),VIP 下面有RS(Real Server,后端真实服务器);则就用$host ;host是访问URL中的域名和端口 www.taobao.com:80
第二行:把源IP 【$remote_addr,建立HTTP连接header里面的信息】赋值给X-Real-IP;这样在代码中 $X-Real-IP来获取 源IP
第三行:在nginx 作为代理服务器时,设置的IP列表,会把经过的机器ip,代理机器ip都记录下来,用 【,】隔开;代码中用 echo $x-forwarded-for |awk -F, '{print $1}' 来作为源IP
- 转发后会被重新定义的配置
默认情况下,nginx在代理后会重新定义两个header参数:Host、Connection,将Host设置为$proxy_host,Connection设置为close。
此外,清除值为空的参数。
-
如何防止header信息被转发
将参数值设置为空字符串,例如:
location /some/path/ {
proxy_set_header Accept-Encoding “”;
proxy_pass http://localhost:8000;
}
-
缓冲区配置proxy_buffering
默认请求下,nginx会缓存被代理服务器的响应。响应会被存储在内部缓存中。缓存有助于慢客户端的性能优化。
通过proxy_buffering来开启、关闭缓存,默认开启。当缓存关闭时,代理服务器收到后端服务器的响应时,会同步发送到C端。从而满足希望快速互动的客户所需。
通过proxy_buffers来控制分配的缓存区大小与数量。响应的第一部分会被存储在一个单独的缓存中,这个单独缓冲区的大小由proxy_buffer_size设置。
如果要设置缓存不可用,可以将location下的proxy_buffering设置为off即可:
location /some/path/ {
proxy_buffering off;
proxy_pass http://localhost:8000;
}
这种情况下,nginx只用proxy_buffer_size配置的缓冲区去存储部分响应。
9)nginx域名解析
nginx在启动时,只做一次域名解析,解析结果会被缓存,后续所有的请求转发,都是直接使用缓存下来的IP,不再做任何域名解析。
如果某个域名有多个IP,那么nginx在转发时会自动轮转IP列表。
配置动态域名解析(在proxy_pass后引入变量)
resolver 8.8.8.8;
server {
location / {
set $servers github.com;
proxy_pass http://$servers;
}
}
这种引入变量的方式可以强制nginx遵守域名解析结果的TTL,过期后自动重新解析。
但是这种写法有个副作用,如此配置后nginx不会自动使用/etc/resolve.conf的配置,需要手动用resolver来给它指定一个DNS服务器。
在upstream中引入resolver进行动态域名解析
upstream amap{ resolver 127.0.0.1 valid=30s ipv6=off; server webapi.amap.com:443 resolve; keepalive 10; zone amap 1m; }
这里的upstream amap块是nginx中定义的一个后端服务集群配置,主要用于动态解析域名并转发请求到高德地图API(webapi.amap.com:443):
第一行
resolver 127.0.0.1 valid=30s ipv6=off;
-
resolver:DNS解析服务器的IP地址,用于解析upstream中定义的域名;
- 127.0.0.1:使用本地DNS服务器(通常是NGINX所在服务器的本地DNS缓存,如systemd-resolved、dnsmasq)进行域名解析;
- valid=30s:设置DNS解析结果的缓存时间为30s,超过后会重新解析域名(避免域名对应的IP变化后Nginx仍使用旧IP);
- ipv6=off:禁用IPv6解析,只返回IPv4地址(防止因IPv6解析失败导致的问题)。
作用:当upstream中的server用域名(而非固定IP)定义时,resolver负责将域名解析为IP,确保NGINX能动态获取后端服务的最新IP。
第二行
server webapi.amap.com:443 resolve;
- server:定义后端服务的地址,当使用该upstream块时,会把请求发往这个这个域名。
- resolve:关键参数,告诉Nginx该server是用域名定义的,需要通过之前的resolver定期解析域名,并自动更新对应的IP地址(配合valid=30s生效);
作用:根据第一行所指定的DNS服务器,动态跟踪web.api.amap.com的IP变化(例如高德服务器扩容、IP迁移时),避免因IP变更导致Nginx转发失败。
第三行
keepalive 10;
启用连接复用机制,设置与后端服务(webapi.amap.com:443)保持的空闲长连接数量上限为10个。
作用:减少频繁创建/关闭连接的开销,提升请求转发效率。当有新请求到来时,Nginx会优先复用空闲的长连接,而非重新建立连接。
第四行
zone amap 1m;
- zone:创建一个名为amap的共享内存区域,大小为1MB;
- 该区域用于存储upstream集群的状态信息(如后端服务器的IP、健康状态、连接数等);
- 在nginx多worker进程模式下,共享内存可以让所有worker进程共享这些状态,确保负载均衡、健康检查的一致性;
作用:实现多进程间的状态共享,保证upstream配置在集群中生效的一致性(特别是动态解析和长连接管理)。
补充:zone放在upstream而非全局块中的意义
虽然zone的共享内存确实是全局可见的(所有worker进程都能访问),但它的数据内容、管理范围是严格绑定到所属upstream的,每个upstream可以根据不同的集群规模,申请实际所需的共享内存,避免全局统一分配导致的资源浪费。
此外,如果zone定义在全局,就需要手动维护其与upstream的关联。当zone放在upstream块中,当upstream块被删除、修改时,对应的zone共享内存也会随upstream的生命周期自动管理。
这个upstream适用于后端服务IP不固定(域名动态解析)的场景,如第三方API、云服务等。
使用时,通常会在http块的location中通过proxy_pass https://amap来引用该upstream,将请求转发到高德API。
10)stream块与http块
Nginx中,stream块和http块是两个同级别的顶层配置块,分别用于处理不同层级的网络流量。二者本质是传输层代理和应用层代理的差异。
stream块:
- OSI层级为传输层(四层);
- 处理对象为基于TCP/UDP协议的原始流量(仅解析IP和端口);
- 不关心应用层协议(如HTTP、MySQL、Redis等)
以一个stream块转发Redis流量的配置为例:
stream{ server { listen 6379; #监听本地6379端口 proxy_pass 192.168.1.100:6379; #进入该端口的流量都被转发到指定地址 } }
再写一个之前提到的http块:
http { server { listen 80; server_name example.com; #基于URL路径转发 location /api/ { proxy_pass http:/backend_api; #转发到后端API服务 proxy_set_header Host $host; #修改HTTP请求头 } #处理静态文件 location /static/ { root /var/www; } } }
可以看出,stream块在进行流量转发时,只需要做端口匹配即可;而http块处理应用层流量时,需要用server_name来区分不同域名的请求,这依赖于应用层协议对域名的解析。
不过,虽然stream块不能用server_name,但仍可以通过listen来监听从不同IP的网卡进来的请求,并将其转发到不同的服务上。
stream { #绑定 IP 192.168.1.10:3306,转发到MySQL A集群 server { listen 192.168.1.10:3306; proxy_pass mysql_cluster_a; } #绑定IP 192.168.1.11:3306,转发到MySQL B集群 server { listen 192.168.1.11:3306; proxy_pass mysql_cluster_b; } }
实践中更常用的场景是,stream和upstream的结合使用:
stream { upstream abc9026 { server 21.54.162.138:8000 max_fails=3 fail_timeout=30s; } server { listen 9026; proxy_connect_timeout 300s; proxy_timeout 300s; proxy_pass abc9026; } …… }
由于server块和http块是同一级的流量处理块,所以可能面临这样的问题,如果二者listen了同一个端口,那么流量进来之后会被谁处理呢?
答案是stream和http块禁止用相同端口,同一个端口不能被两个不同的模块同时监听。如果强行这样配置,那么nginx在启动时会报错address already in use。
upstream与proxy_pass
配置了upstream,那么这个upstream通常会被用到proxy_pass中。
用法:proxy_pass http://upstream服务器名,不用加$前缀。
即upstream单独不会起作用,只是为了统一管理proxy_pass转发的目的地址。
三、详细配置
1、全局块(events之前的部分)
#user nobody; worker_processes 1; #error_log logs/error.log; #error_log logs/error.log notice; #error_log logs/error.log info; #pid logs/nginx.pid;
#worker_rlimit_nofile 204800
1)user
含义:配置用户与组
说明:
运行worker进程的用户和组
默认:user nobody nobody
2)worker_processes
含义:启动了worker进程的数目。说明:
为了避免上下文切换,通常设置为CPU总核心数-1或总核心数。
3)pid logs/nginx.pid
含义:pid(进程标识符) 存放路径4)worker_rlimit_nofile 204800
含义:worker进程可以打开的最大文件数(默认1024)说明:
1)该指令是指当一个nginx进程打开的最多文件描述符数目,理论值应该是 最多打开文件数(ulimit -n)÷ nginx进程数 ,但是nginx分配请求并不是那么均匀,因此最好和ulimit -n的值保持一值;
2)Linux 2.6内核下文件打开数为65535,worker_rlimit_nofile的值就该填写65535。这是因为nginx调度时分配请求到进程时并非那么均匀,所以如果填写10240,那么当总并发量达到3-4W时就有进程会超过10240,此时返回502错误。
worker_rlimit_core size
含义:所有worker进程所能使用的总体最大核心文件大小
5)error_log
写法:error_log 路径 级别
含义:日志存放哪种信息,日志路径
说明:这项设置可以放到全局块、http块、server块中;
级别分别为:debug|info|notice|warn|error|crit|alert|emerg
2、events块
use epoll; worker_connections 1024; keepalive_timeout 60 client_header_buffer_size 4k; open_file_cache max=65535 inactive=60s; open_file_cache_valid 80s; open_file_cache_min_uses 1;
multi_accept on;
1)use epoll
含义:事件驱动模型——select|poll|kqueue|epoll|resig|/dev/poll|eventport说明:
Linux下建议epoll,FreeBSD建议kqueue,windows下不指定。
2)worker_connections 1024
含义:每个工作进程能够接受的最大连接数量,默认512。
说明:
根据硬件调整,和前面工作进程(全局块中的worker_processes变量)配合起来用,尽量大,但是不要让CPU跑到100。
理论上每台nginx服务器的最大连接数为 worker_processes × worker_connections。
3)keepalive_timeout 60
含义:长连接的超时时间(单位:s),默认65。
说明:该项可设置于http、server、location块
keepalive_requests n
含义:在一个长连接上所能允许请求的最大资源数
4)client_header_buffer_size 4K
含义:客户端请求头部的缓冲区大小。
说明:
可以根据你地系统分页大小来设置,一般一个请求头大小不超过1K,不过由于一般系统分页都要>1K,因此这里设置为分页大小。
分页大小可以用getconf PAGESIZE获取:

也有client_header_buffer_size>4K的情况,但是其值必须为PAGESIZE的整数倍。
5)open_file_cache max=65535 inactive=60s
为打开文件指定缓存,默认不启用
max:缓存数量,建议和打开文件数一致;
inactive:经过多长时间文件未被请求后删除缓存。
6)open_file_cache_valid 80s
多久检查一次缓存的有效信息
7)open_file_cache_min_uses 1
与参数5)open_file_cache的inactive选项相关,该选项指定了在inactive时间内文件的最少使用次数,上文所说,如果1次未被使用,那它将被移除;否则文件描述符会一直在缓存中打开。
3、http块
include mime.types; #文件扩展名与文件类型映射表
default_type application/octet-stream; #默认文件类型,默认为text/plain
#access_log off; #取消服务日志
log_format myFormat '$remote_addr–$remote_user [$time_local] $request $status $body_bytes_sent $http_referer $http_user_agent $http_x_forwarded_for'; #自定义格式
access_log log/access.log myFormat; #combined为日志格式的默认值
sendfile on; #允许sendfile方式传输文件,默认为off,可以在http块,server块,location块。
sendfile_max_chunk 100k; #每个进程每次调用传输数量不能大于设定的值,默认为0,即不设上限。
keepalive_timeout 65; #连接超时时间,默认为75s,可以在http,server,location块。
1)include mime.types;
含义:设定mime类型(文件扩展名与文件类型的映射表),类型由mime.type文件定义2)default_type application/octet-stream;
含义:设置默认文件类型,默认text/plain
3)log_format
含义:自定义日志格式
log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; log_format log404 '$status [$time_local] $remote_addr $host$request_uri $sent_http_location';
日志格式设置:
$remote_addr与$http_x_forwarded_for用以记录客户端的ip地址;
$remote_user:用来记录客户端用户名称;
$time_local: 用来记录访问时间与时区;
$request: 用来记录请求的url与http协议;
$status: 用来记录请求状态;成功是200,
$body_bytes_sent :记录发送给客户端文件主体内容大小;
$http_referer:用来记录从那个页面链接访问过来的;
$http_user_agent:记录客户浏览器的相关信息;
通常web服务器放在反向代理的后面,这样就不能获取到客户的IP地址了,通过$remote_add拿到的IP地址是反向代理服务器的iP地址。
反向代理服务器在转发请求的http头信息中,可以增加x_forwarded_for信息,用以记录原有客户端的IP地址和原来客户端的请求的服务器地址。
4)access_log:日志文件的存放路径
access_log logs/host.access.log main; access_log logs/host.access.404.log log404; 用了log_format指令设置了日志格式之后,需要用access_log指令指定日志文件的存放路径;
5)server_names_hash_bucket_size 128;
保存服务器名字的hash表是由指令server_names_hash_max_size和server_names_hash_bucket_size所控制的。hash bucket size = hash表的大小,并且是一路处理器缓存大小的倍数。
在减少了在内存中的存取次数后,使在处理器中加速查找hash表键值成为可能。如果hash bucket size等于一路处理器缓存的大小,那么在查找键的时候,最坏的情况下在内存中查找的次数为2。第一次是确定存储单元的地址,第二次是在存储单元中查找键-值。因此,如果Nginx给出需要增大hash max size 或 hash bucket size的提示,那么首要的是增大前一个参数的大小.
6)client_header_buffer_size 4k;
默认客户端请求头部的缓冲区大小。
这个可以根据你的系统分页大小来设置,一般一个请求的头部大小不会超过1k,不过由于一般系统分页都要大于1k,所以这里设置为分页大小。
分页大小可以用命令getconf PAGESIZE取得。
7)large_client_header_buffers 8 128k;
超过默认值时客户请求头缓冲大小。
nginx默认会用client_header_buffer_size这个buffer来读取header值,如果header过大,它会使用large_client_header_buffers来读取。
8)open_file_cache max=102400 inactive=20s;
缓存是否启用。
9)10)11)用于http、location、server
open_file_cache_valid 30; open_file_cache_min_uses 2; open_file_cache_errors on;
9)open_file_cache_valid
写法:open_file_cache_valid time
默认值:60
含义:何时需要检查open_file_cache中缓存项目的有效信息.
10)open_file_cache_min_uses
写法:open_file_cache_min_uses number
默认值:1
含义:在open_file_cache指令无效的参数中一定的时间范围内可以使用的最小文件数,如果使用更大的值,文件描述符在cache中总是打开状态.
11)open_file_cache_errors
写法:open_file_cache_errors on | off
默认值:off
含义:是否在搜索一个文件是记录cache错误.
12)client_max_body_size 300m
含义:通过nginx上传文件的大小
13)sendfile on;
sendfile指令指定 nginx 是否调用sendfile 函数(zero copy 方式)来输出文件,对于普通应用,必须设为on。
如果用来进行下载等应用磁盘IO重负载应用,可设置为off,以平衡磁盘与网络IO处理速度,降低系统uptime。
14)tcp_nopush on;
允许或禁止使用socke的TCP_CORK的选项,此选项仅在使用sendfile的时候使用
15)-17)为连接、超时控制
15)proxy_connect_timeout 90;
后端服务器连接的超时时间_发起握手等候响应超时时间。
16)proxy_read_timeout 180;
连接成功后_等候后端服务器响应时间_其实已经进入后端的排队之中等候处理(也可以说是后端服务器处理请求的时间)
17)proxy_send_timeout 180;
后端服务器数据回传时间_就是在规定时间之内后端服务器必须传完所有的数据
18)proxy_buffer_size 256k;
设置从被代理服务器读取的第一部分应答的缓冲区大小,通常情况下这部分应答中包含一个小的应答头,默认情况下这个值的大小为指令proxy_buffers中指定的一个缓冲区的大小,不过可以将其设置为更小
19)proxy_buffers 4 256k;
设置用于读取应答(来自被代理服务器)的缓冲区数目和大小,默认情况也为分页大小,根据操作系统的不同可能是4k或者8k
20)proxy_busy_buffers_size 256k;
21)proxy_temp_file_write_size 256k;
设置在写入proxy_temp_path时数据的大小,预防一个工作进程在传递文件时阻塞太长
22)proxy_temp_path proxy_cache_path
proxy_temp_path /data0/proxy_temp_dir; proxy_cache_path /data0/proxy_cache_dir levels=1:2 proxy_temp_path和proxy_cache_path指定的路径必须在同一分区
23)keys_zone=cache_one:200m inactive=1d max_size=30g;
设置内存缓存空间大小为200MB,1天没有被访问的内容自动清除,硬盘缓存空间大小为30GB。
24)keepalive_timeout 120;
keepalive超时时间。
25)tcp_nodelay on;
26)client_body_buffer_size 512k;
如果把它设置为比较大的数值,例如256k,那么,无论使用firefox还是IE浏览器,来提交任意小于256k的图片,都很正常。
如果注释该指令,使用默认的client_body_buffer_size设置,也就是操作系统页面大小的两倍,8k或者16k,问题就出现了。 无论使用firefox4.0还是IE8.0,提交一个比较大,200k左右的图片,都返回500 Internal Server Error错误
27)proxy_intercept_errors on;
表示使nginx阻止HTTP应答代码为400或者更高的应答。28)upstream:负载方式
upstream backend { server 127.0.0.1:8027; server 127.0.0.1:8028; server 127.0.0.1:8029; hash $request_uri;
目前支持4种负载方式:
①轮询(默认)
每个请求按照时间顺序,逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。
②weight
指定权重,权重weight和访问比率成正比,用于后端服务器性能不均的情况。
upstream backend { server 192.168.0.14 weight=10; server 192.168.0.15 weight=10; }
③ip_hash
每个请求按ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。
upstream backend { ip_hash; server 192.168.0.14:88; server 192.168.0.15:80; }
④fair(第三方)
按后端服务器的响应时间来分配请求,响应时间短的优先分配。
upstream backend {
server server1;
server server2;
fair;
}
⑤url_hash(第三方)
按照url的hash结果分配请求,使每个url定向到同一个后端服务器,后端服务器为缓存时比较有效。
在upstream中加入hash语句,在server语句中不能写入weight等其他的参数,hash_method是某个hash算法。
upstream backend { server squid1:3128; server squid2:3128; hash $request_uri; hash_method crc32; }
在需要使用服务负载均衡的server块中增加 proxy_pass http://backend/;
每个设备的状态设置为:
1.down表示单前的server暂时不参与负载 2.weight为weight越大,负载的权重就越大。 3.max_fails:允许请求失败的次数默认为1.当超过最大次数时,返回proxy_next_upstream模块定义的错误 4.fail_timeout:max_fails次失败后,暂停的时间。 5.backup: 其它所有的非backup机器down或者忙的时候,请求backup机器。所以这台机器压力会最轻。 nginx支持同时设置多组的负载均衡,用来给不用的server来使用。 client_body_in_file_only设置为On 可以讲client post过来的数据记录到文件中用来做debug client_body_temp_path设置记录文件的目录 可以设置最多3层目录 location对URL进行匹配.可以进行重定向或者进行新的代理 负载均衡
4、server块
1)listen 80
监听端口
2)server_name www.xxx.com
访问域名
3)location ~* \.(mp3|exe)$
对以mp3或exe结尾的地址进行负载均衡
4)proxy_pass http://img_relay$request_uri;
设置被代理服务器的端口或套接字,以及URL
5)
proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
将代理服务器收到的用户的信息传到真实服务器上

浙公网安备 33010602011771号