一、Nginx 基础介绍
1. 核心四大功能
- 静态 Web 服务: 直接处理并响应 HTML、CSS、JavaScript、图片等静态文件请求。
- 反向代理: 接收客户端请求,然后转发给后端的应用服务器(如 Tomcat, PHP-FPM),并将结果返回给客户端。
- 负载均衡 : 基于反向代理,将客户端请求分发到多个后端服务器,实现流量分摊和高可用。负载均衡功能是反向代理的延伸和应用。
- 前端缓存: 将后端返回的动态内容或静态资源缓存到 Nginx 本地,缩短响应时间,减轻后端服务器压力。
2. 技术特性
- 开发语言: 纯 C 语言编写,性能优异,资源消耗低。
- IO 模型 : 采用
epoll事件驱动模型(Linux),支持高并发连接,异步非阻塞处理方式。 - 架构: 高度模块化设计,核心功能与扩展模块分离,配置语法简洁,管理方便。
3. 三种虚拟主机配置方式
用于在一台 Nginx 服务器上部署多个不同的网站。
表格
| 匹配类型 | 配置指令 | 作用描述 | 实操案例 |
|---|---|---|---|
| 基于域名 | server_name |
同一 IP 和端口,通过不同域名区分不同网站。 | server_name www.yun333.com; |
| 基于端口 | listen |
同一 IP,通过监听不同的端口来区分不同网站。 | listen 81; |
| 基于 IP | listen |
服务器绑定多个 IP 地址,通过不同的 IP 来区分不同网站。 | listen 192.168.1.100:80; |
二、Nginx 核心功能详解
1. 地址重写 (Rewrite)
用于改变用户请求的 URI,实现 URL 跳转、规范化等功能。
语法:
nginx
rewrite 匹配规则(正则表达式) 目标地址 [标记];
四种常用标记 (flag):
表格
| 标记 | 含义与作用 | 场景 |
|---|---|---|
last |
停止当前 location 的 rewrite 规则,然后 根据重写后的 URL 重新发起一次内部请求 ,从头开始匹配 server 和 location。 |
用于将请求重写到其他 location 块进行处理。 |
break |
停止当前 location 的 rewrite 规则 ,不再继续处理,直接使用当前重写后的 URI 在当前 location 中处理请求。 |
用于在当前 location 内完成重写。 |
redirect |
返回 302 临时重定向。浏览器地址栏会显示新的 URL。主要用于临时的页面跳转。 | 临时维护、页面临时移动。 |
permanent |
返回 301 永久重定向。搜索引擎会更新索引,浏览器会缓存该重定向规则。 | 域名更换、页面永久迁移。 |
案例:将不带 www 的域名永久重定向到带 www 的域名
nginx
server {
listen 80;
server_name yun333.com;
# ^/(.*)$ 匹配所有路径,$1 代表匹配到的路径部分
rewrite ^/(.*)$ http://www.yun333.com/$1 permanent;
}
2. 反向代理 (Proxy_pass)
概念: Nginx 作为客户端和后端服务器之间的代理,隐藏后端服务器的真实 IP 和端口,统一对外提供服务。
核心指令 : proxy_pass http://后端服务器地址;
案例:代理后端的 Java Web 应用
nginx
server {
listen 80;
server_name app.yun333.com;
location / {
# 将请求转发到后端运行在 8080 端口的 Tomcat 服务器
proxy_pass http://192.168.91.165:8080;
# 重要:将客户端的真实 IP 传递给后端服务器
proxy_set_header X-Real-IP $remote_addr;
# 重要:将客户端请求的 Host 头传递给后端,后端可能需要此信息
proxy_set_header Host $host;
# 重要:传递客户端的原始协议和端口,特别是在 HTTPS 环境下
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
3. 负载均衡 (Load Balancing)
3.1 四层负载与七层负载
- 四层负载均衡 (传输层) : 工作在 OSI 模型的第四层(TCP/UDP)。基于 IP 地址 和端口号进行流量分发。它不关心应用层的内容(如 HTTP 请求)。代表软件:LVS。
- 七层负载均衡 (应用层) : 工作在 OSI 模型的第七层(HTTP/HTTPS)。可以识别 HTTP 协议的完整内容,如域名 (
Host)、URL (URI)、请求头、Cookie等,进行更精细的流量调度。代表软件:Nginx, HAProxy。
3.2 主流负载均衡方案
- 开源软件 :
- Nginx : 主流的 七层 负载均衡器,性能高,配置灵活。从 1.9.0 版本开始,通过
stream模块支持 四层 TCP 负载均衡。 - LVS (Linux Virtual Server) : 强大的 四层 负载均衡器,性能极高,工作在内核态。
- HAProxy : 同时支持 四层 和 七层,功能强大,常用于数据库等多种服务的负载均衡。
- Nginx : 主流的 七层 负载均衡器,性能高,配置灵活。从 1.9.0 版本开始,通过
- 商业硬件 :
- F5 BIG-IP, A10, Radware, Citrix Netscaler 等。性能强大,功能丰富,但价格昂贵。
3.3 Nginx 负载均衡实现
Nginx 实现负载均衡依赖两个核心部分:
upstream块: 定义一个后端服务器地址池。proxy_pass指令 : 将请求转发到upstream定义的地址池。
upstream 块关键字段:
server: 定义后端服务器,格式为IP:端口。weight=number: 设置权重。数字越大,被分配到的请求越多。down: 标记该服务器为永久不可用。backup: 标记该服务器为备用服务器。只有当所有非备用服务器都不可用时,才会将请求转发给它。
调度算法:
rr(Round Robin, 轮询): 默认算法。请求按顺序逐一分配到不同的后端服务器。wrr(Weighted Round Robin, 权重轮询): 根据权重分配请求。权重越高的服务器处理的请求越多。ip_hash: 根据客户端的 IP 地址进行哈希计算,来自同一个 IP 的请求将始终被定向到同一台后端服务器。可用于解决会话保持问题。fair: 根据后端服务器的响应时间来分配请求,响应时间短的优先分配。(需要第三方模块支持)least_conn: 将请求分配给当前活动连接数最少的后端服务器。适用于请求处理时间长短不一的场景。
健康检查 : Nginx 默认会对后端节点进行简单的健康检查。如果某个节点连续失败,Nginx 会在一段时间内停止将请求转发给它。但它不会主动发送告警,需要结合监控系统来实现。
完整负载均衡案例:
nginx
http {
# 1. 定义一个名为 "backend_pool" 的后端服务器地址池
upstream backend_pool {
# 调度算法,这里使用 ip_hash 实现会话保持
ip_hash;
# 后端服务器1,权重为 2
server 192.168.91.165:8080 weight=2;
# 后端服务器2,权重为 1
server 192.168.91.166:8080 weight=1;
# 后端服务器3,标记为备用服务器
server 192.168.91.167:8080 backup;
}
server {
listen 80;
server_name www.yun333.com;
location / {
# 2. 将所有请求转发到名为 "backend_pool" 的地址池
proxy_pass http://backend_pool;
# 传递必要的请求头信息
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
}
三、配置文件标准化与优化
1. 标准化管理
- 将不同网站的配置文件分离,存放在
conf.d目录下,通过include conf.d/*.conf;在主配置文件中引入。 - 使用注释清晰地标明每个配置块的用途。
- 统一日志格式和存放路径。
2. 基础优化建议
worker_processes: 通常设置为 CPU 核心数或核心数的 2 倍。auto会自动检测。worker_connections: 每个 worker 进程的最大连接数。sendfile on;: 启用高效文件传输模式。keepalive_timeout: 长连接超时时间。
3. 完整带注释的 Nginx 配置示例
nginx
# 工作进程数,建议设置为CPU核心数
worker_processes auto;
events {
# 每个工作进程的最大连接数
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
# 开启高效文件传输
sendfile on;
# 开启TCP_NOPUSH,在sendfile开启时有效
tcp_nopush on;
# 长连接超时时间
keepalive_timeout 65;
# 定义后端服务器地址池
upstream my_backend_servers {
# 使用权重轮询算法
# wrr;
# 使用IP哈希算法,保证会话粘性
ip_hash;
# 后端节点1,权重为3
server 192.168.91.165:80 weight=3;
# 后端节点2,权重为1
server 192.168.91.166:80 weight=1;
# 后端节点3,作为备份
server 192.168.91.167:80 backup;
}
server {
listen 80;
server_name localhost;
location / {
# 将请求反向代理到地址池
proxy_pass http://my_backend_servers;
# 将客户端请求的 Host 头传递给后端服务器
proxy_set_header Host $host;
# 将客户端的真实IP地址传递给后端服务器
proxy_set_header X-Real-IP $remote_addr;
# 在已有X-Forwarded-For头信息后追加客户端IP
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
# 引入其他网站的配置文件
# include conf.d/*.conf;
}