一、Nginx目录结构
[root@localhost ~]# tree /usr/local/nginx
/usr/local/nginx
├── client_body_temp # POST 大文件暂存目录
├── conf # Nginx所有配置文件的目录
│ ├── fastcgi.conf # fastcgi相关参数的配置文件
│ ├── fastcgi.conf.default # fastcgi.conf的原始备份文件
│ ├── fastcgi_params # fastcgi的参数文件
│ ├── fastcgi_params.default
│ ├── koi-utf
│ ├── koi-win
│ ├── mime.types # 媒体类型
│ ├── mime.types.default
│ ├── nginx.conf #这是Nginx默认的主配置文件,日常使用和修改的文件
│ ├── nginx.conf.default
│ ├── scgi_params # scgi相关参数文件
│ ├── scgi_params.default
│ ├── uwsgi_params # uwsgi相关参数文件
│ ├── uwsgi_params.default
│ └── win-utf
├── fastcgi_temp # fastcgi临时数据目录
├── html # Nginx默认站点目录
│ ├── 50x.html # 错误页面优雅替代显示文件,例如出现502错误时会调用此页面
│ └── index.html # 默认的首页文件
├── logs # Nginx日志目录
│ ├── access.log # 访问日志文件
│ ├── error.log # 错误日志文件
│ └── nginx.pid # pid文件,Nginx进程启动后,会把所有进程的ID号写到此文件
├── proxy_temp # 临时目录
├── sbin # Nginx 可执行文件目录
│ └── nginx # Nginx 二进制可执行程序
├── scgi_temp # 临时目录
└── uwsgi_temp # 临时目录
主要的目录包含conf,html,logs和sbin:
① conf目录用来存放配置文件相关
② html目录用来存放静态文件的默认目录 ,如前端包、html、css等
③ logs目录用来存放日志信息
④ sbin目录用于存放可执行文件,可以用 ./nginx启动nginx:
二、基本运行原理
Nginx 是一种高性能的 HTTP 和反向代理服务器,它采用了经典的「Master-Worker」模型来运行。以下是 Nginx 基本运行原理的介绍:
-
启动过程:
-
当 Nginx 启动时,首先会创建一个
Master
进程。 -
Master
进程负责读取和验证配置文件(如/conf/nginx.conf
),确保配置的正确性。
-
-
配置文件:
-
配置文件中定义了 Nginx 的各种设置,包括监听的端口、处理请求的方式等。
-
-
Worker 进程:
-
Master
进程会根据配置文件中的设置,启动多个Worker
进程。 -
这些
Worker
进程是实际处理客户端请求的进程。 -
每个
Worker
进程独立运行,平等地竞争来自客户端的请求。
-
-
请求处理:
-
客户端通过浏览器或其他方式向 Nginx 发送请求(如访问
http://192.168.44.101/index.html
)。 -
请求首先到达
Master
进程,然后由Master
进程分发给一个Worker
进程。 -
Worker
进程解析请求,并根据请求内容读取相应的文件(如/html/index.html
)。 -
Worker
进程处理完请求后,将响应返回给客户端。
-
-
进程管理:
-
Master
进程负责管理Worker
进程,包括接收外界信号、向Worker
进程发送信号、监控Worker
进程的运行状态等。 -
如果某个
Worker
进程异常退出,Master
进程会自动重新启动一个新的Worker
进程,以确保服务的连续性。
-
-
性能优化:
-
通常,
Worker
进程的数量会设置为与机器的 CPU 核心数一致,以充分利用多核 CPU 的性能。 -
Nginx 的事件处理模型(如 epoll)使得
Worker
进程能够高效地处理大量并发连接。
-
通过这种「Master-Worker」模型,Nginx 能够实现高性能、高并发的 Web 服务处理。
三、Nginx配置与应用场景
3.1 nginx.conf
刚安装好的nginx.conf如下:
#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;events {worker_connections 1024;
}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;#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;}# proxy the PHP scripts to Apache listening on 127.0.0.1:80##location ~ \.php$ {# proxy_pass http://127.0.0.1;#}# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000##location ~ \.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 {# deny all;#}}# another virtual host using mix of IP-, name-, and port-based configuration##server {# listen 8000;# listen somename:8080;# server_name somename alias another.alias;# location / {# root html;# index index.html index.htm;# }#}# HTTPS server##server {# 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;# }#}}
去掉注释的简单版如下:
worker_processes 1; #允许进程数量,建议设置为cpu核心数或者auto自动检测,
#注意Windows服务器上虽然可以启动多个processes,但是实际只会用其中一个events {#单个进程最大连接数(最大连接数=连接数*进程数)#根据硬件调整,和前面工作进程配合起来用,尽量大,但是别把cpu跑到100%就行。worker_connections 1024;
}http {#文件扩展名与文件类型映射表(是conf目录下的一个文件)include mime.types;#默认文件类型,如果mime.types预先定义的类型没匹配上,默认使用二进制流的方式传输default_type application/octet-stream;#sendfile指令指定nginx是否调用sendfile 函数(zero copy 方式)来输出文件,
#对于普通应用,必须设为on。如果用来进行下载等应用磁盘IO重负载应用,
#可设置为off,以平衡磁盘与网络IO处理速度。sendfile on;#长连接超时时间,单位是秒keepalive_timeout 65;#虚拟主机的配置server {#监听端口listen 80;#域名,可以有多个,用空格隔开server_name localhost;#配置根目录以及默认页面location / {root html;index index.html index.htm;}#出错页面配置error_page 500 502 503 504 /50x.html;#/50x.html文件所在位置location = /50x.html {root html;}}}
配置介绍:
Worker
进程 )。 -
sendfile
可以实现数据的零拷贝(zero-copy),即数据直接从文件系统传输到网络缓冲区,而不需要经过用户空间的拷贝,从而提高传输效率。

开启sendfile:
⑥keepalive_timeout 65;
keepalive_timeout
是 Nginx 配置中的一个指令,它用于设置保持连接打开状态的时间,也就是长连接的超时时间。
-
time
:可以是指定的秒数,也可以是小数点表示的秒数(例如,65、65.5)。
3.2 server_name匹配规则
3.2.1完整匹配
可以配置多个域名,例如:
server_name test81.xzj520520.cn test82.xzj520520.cn;
3.2.2通配符匹配
使用通配符的方式如下
①通配符开始匹配:
server_name *.xzj520520.cn;
②通配符结束匹配:
server_name www.xzj520520.*;
需要注意的是精确匹配的优先级大于通配符匹配和正则匹配。
3.2.3正则匹配
采用正则的匹配方式如下:
server_name ~^[0-9]+\.mmban\.com$;
正则匹配格式,必须以~开头,比如:server_name ~^www\d+\.example\.net$;。如果开头没有~,则nginx认为是精确匹配。在逻辑上,需要添加^和$锚定符号。注意,正则匹配格式中.为正则元字符,如果需要匹配.,则需要反斜线转义。如果正则匹配中含有{和}则需要双引号引用起来,避免nginx报错,如果没有加双引号,则nginx会报如下错误:directive "server_name" is not terminated by ";" in ...。
3.2.4 匹配顺序
-
精确匹配:
Nginx 首先查找是否有完全匹配的域名。例如,如果配置了server_name example.com;
,则该服务器块会匹配直接请求example.com
的请求。 -
最长通配符匹配(以 * 开头):
如果没有精确匹配,Nginx 会查找以星号(*)开头的最长通配符匹配。例如,server_name *.example.com;
会匹配任何以.example.com
结尾的域名,如sub.example.com
。 -
最长通配符匹配(以 * 结尾):
如果没有找到以 * 开头的通配符匹配,Nginx 会查找以星号(*)结尾的最长通配符匹配。例如,server_name example.*;
会匹配任何以example.
开头的域名,如example.sub
。 -
正则表达式匹配:
如果上述匹配都未找到,Nginx 会查找正则表达式匹配。正则表达式必须以~
开头(区分大小写)或~*
开头(不区分大小写)。例如,server_name ~^www\.example\.com$;
会匹配www.example.com
。 -
特殊匹配:
server_name "";
用于匹配 Host 请求头不存在的情况。 -
默认服务器块:
如果以上所有匹配都未找到,Nginx 会使用没有server_name
指令的服务器块(如果有的话)作为默认服务器块来处理请求。
3.3反向代理
在 Nginx 中配置反向代理时,proxy_pass
指令用于指定客户端请求将被转发到的目标服务器地址。
-
假设我们要将域名
example.com
的请求代理到后端服务器192.168.1.100
的8080
端口。
server {listen 80; // 监听 80 端口server_name example.com; // 指定域名location / {proxy_pass http://192.168.1.100:8080; // 将请求转发到后端服务器proxy_set_header Host $host; // 传递原始请求的 Host 头部proxy_set_header X-Real-IP $remote_addr; // 传递客户端的真实 IP 地址proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; // 添加 X - Forwarded - For 头部,用于记录请求经过的代理服务器proxy_set_header X-Forwarded-Proto $scheme; // 传递原始请求的协议(如 HTTP 或 HTTPS)}
}
-
在这个配置中,
proxy_pass
指令是核心,它指定了后端服务器的地址和端口。proxy_set_header
指令用于设置转发请求时添加的头部信息,这对于后端服务器正确处理请求很重要。例如,X - Real - IP
头部可以让后端服务器知道客户端的真实 IP 地址,而不是 Nginx 服务器的 IP 地址。
3.4负载均衡
3.4.1 如何配置负载均衡
可以通过upstream
模块定义一组后端服务器,然后在proxy_pass
中引用这个upstream来实现负载均衡。
upstream backend {server 192.168.1.100:8080;server 192.168.1.101:8080;server 192.168.1.102:8080;
}server {listen 80;server_name example.com;location / {proxy_pass http://backend; // 引用 upstream 中定义的服务器组proxy_set_header Host $host;proxy_set_header X - Real - IP $remote_addr;proxy_set_header X - Forwarded - For $proxy_add_x_forwarded_for;proxy_set_header X - Forwarded - Proto $scheme;}
}
默认情况下,Nginx 使用轮询的方式将请求分发到upstream
中的服务器。也可以通过least_conn
(最少连接)或ip_hash
(基于 IP 哈希)等指令来指定其他负载均衡策略
3.4.2 负载均衡策略
1. 轮询(默认策略)
-
工作原理:默认情况下,Nginx 使用轮询策略,按照顺序依次将请求分配给后端服务器。
-
适用场景:适用于后端服务器性能相近且请求量相对均匀的场景。
-
配置示例:
upstream backend {server 127.0.0.1:8050;server 127.0.0.1:8060;server 127.0.0.1:8070; }
2. 权重(Weight)
-
工作原理:通过
weight
指令为每台服务器分配权重。权重越高,分配到的请求越多。权重默认为1。 -
适用场景:适用于后端服务器性能不均的情况,高性能服务器可以分配更高的权重。
-
配置示例:
upstream backend {server 127.0.0.1:8050 weight=10; # 高性能服务器server 127.0.0.1:8060 weight=1; # 低性能服务器server 127.0.0.1:8070 weight=5; # 中等性能服务器
}
3. 禁用服务器(Down)
-
工作原理:使用
down
指令可以将某台服务器标记为暂时不参与负载均衡。 -
适用场景:当某台服务器需要维护或出现故障时,可以将其标记为
down
。 -
配置示例:
upstream backend {server 127.0.0.1:8050;server 127.0.0.1:8060 down; # 暂时禁用这台服务器server 127.0.0.1:8070; }
4. 备用服务器(Backup)
-
工作原理:使用
backup
指令可以将某台服务器标记为备用服务器。只有当其他所有非备用服务器都不可用(如宕机或繁忙)时,才会将请求转发到备用服务器。 -
适用场景:用于提高系统的可用性,确保在部分服务器故障时仍然可以提供服务。
-
配置示例:
upstream backend {server 127.0.0.1:8050;server 127.0.0.1:8060;server 127.0.0.1:8070 backup; # 备用服务器
}
5. IP 哈希(IP Hash)
-
工作原理:根据客户端的IP地址进行哈希计算,将请求分配到特定的服务器。同一个客户端的请求总是被分配到同一台服务器。
-
适用场景:适用于需要会话保持的应用场景,例如在线购物车系统。
-
配置示例:
upstream backend {ip_hash;server 127.0.0.1:8050;server 127.0.0.1:8060;
}
6. 最少连接(Least Conn)
-
工作原理:将新的请求分配给当前连接数最少的服务器。
-
适用场景:适用于请求量波动较大且服务器性能相近的场景。
-
配置示例:
upstream backend {least_conn;server 127.0.0.1:8050;server 127.0.0.1:8060;
}
7. URL 哈希(URL Hash)
-
工作原理:根据请求的URL进行哈希计算,将请求分配到特定的服务器。适用于静态资源的负载均衡。
-
适用场景:适用于静态资源的分配,例如图片、CSS 文件等。
-
配置示例:
upstream backend {hash $request_uri consistent; # 使用请求的 URI 进行哈希server 127.0.0.1:8050;server 127.0.0.1:8060;
}
8. 响应时间(Fair)
-
工作原理:根据后端服务器的响应时间来分配请求。响应时间越短的服务器,分配到的请求越多。
-
适用场景:适用于对响应时间敏感的应用场景。
-
配置示例:
upstream backend {fair;server 127.0.0.1:8050;server 127.0.0.1:8060;
}
3.4.3 综合配置示例
以下是一个综合了多种策略的配置示例:
upstream backend {ip_hash; # 保持会话least_conn; # 最少连接server 127.0.0.1:8050 weight=10;server 127.0.0.1:8060 weight=5;server 127.0.0.1:8070 weight=1 backup; # 备用服务器server 127.0.0.1:8080 down; # 禁用服务器
}server {listen 80;server_name example.com;location / {proxy_pass http://backend;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header X-Forwarded-Proto $scheme;}
}
3.4.3 总结
-
轮询:适用于服务器性能相近的场景。
-
权重:适用于服务器性能不均的场景。
-
最少连接:适用于请求量波动较大的场景。
-
IP 哈希:适用于需要会话保持的场景。
-
URL 哈希:适用于静态资源的负载均衡。
-
响应时间:适用于对响应时间敏感的场景。
-
备用服务器:用于提高系统的可用性。
-
禁用服务器:用于维护或故障处理。
根据实际需求选择合适的策略和配置,可以有效提升系统的性能和可用性。