一、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 哈希:适用于静态资源的负载均衡。
响应时间:适用于对响应时间敏感的场景。
备用服务器:用于提高系统的可用性。
禁用服务器:用于维护或故障处理。
根据实际需求选择合适的策略和配置,可以有效提升系统的性能和可用性。