目录
一、 前言
Nginx(发音为“engine X”)是一款开源、高性能的 HTTP服务器 和 反向代理服务器,同时支持 IMAP/POP3 代理服务。由俄罗斯开发者 Igor Sysoev 于2004年发布,现由 Nginx Inc.(2019年被F5 Networks收购)维护。其核心优势在于 高并发处理能力 和 低资源消耗,尤其适用于高流量场景。
二、 核心功能
-
2.1 反向代理
将客户端请求转发至后端服务器(如Tomcat、Node.js),隐藏真实服务器信息,提升安全性。
-
2.2 负载均衡
支持多种算法分配流量:-
轮询(Round Robin):均分请求。
-
加权轮询(Weighted Round Robin):按权重分配。
-
IP哈希(IP Hash):同一IP固定到同一后端。
-
最少连接(Least Connections):优先分发给连接数少的服务器。
-
-
2.3 HTTP缓存
缓存静态内容(如图片、CSS),减轻后端压力,支持缓存过期、清除策略。 -
2.4 静态资源服务
直接高效处理HTML、JS、图片等静态文件,响应速度远超传统应用服务器。 -
2.5 SSL/TLS终端
处理HTTPS加密/解密,降低后端服务器计算开销,支持SNI多证书。 -
2.6 WebSocket/HTTP2支持
兼容现代协议,提升实时通信效率。 -
2.7 访问控制
IP黑白名单、限速(限流)、Basic认证等安全功能
三、架构与高性能原理
-
3.1 事件驱动模型
基于 异步非阻塞I/O(epoll、kqueue),单线程可处理数千连接,避免多线程上下文切换开销。 -
3.2 多进程架构
-
Master进程:管理配置、监控Worker进程。
-
Worker进程:实际处理请求,相互独立避免竞争,充分利用多核CPU。
-
-
3.3 低内存消耗
每个连接仅占用约256KB内存,支撑数万并发连接。 -
3.4 热部署与平滑升级
不中断服务更新配置或版本,通过信号控制Worker进程替换。
4、对于Nginx的思考
4.1 正向代理和反向代理的区别
正向代理
1. 代理对象不同:正向代理是客户端使用的,比如在公司里,员工上网需要通过公司的代理服务器。这时候,代理服务器代表客户端去访问外部资源。客户端知道正向代理的存在,并且主动配置代理。例如,使用浏览器设置代理服务器地址和端口,这样所有的请求都先发送到代理服务器,再由代理服务器转发到目标网站。这样做的目的可能是为了隐藏客户端的真实IP,或者绕过某些网络限制,比如访问被封锁的网站。正向代理是站在客户端的角度,代替客户端去访问服务器。
2. 实例:
在企业中,如果有一个正向代理服务器,公司内部电脑可以通过这个代理服务器访问受限的网站,同时公司可以监控和过滤员工的网络访问。
反向代理:
1. 代理对象不同:
反向代理应该是服务器端的代理。比如,当用户访问一个网站时,实际上访问的是反向代理服务器,然后反向代理将请求转发到后端的真实服务器。反向代理对客户端是透明的,客户端不知道后面有多台服务器,只知道代理服务器的存在。反向代理的作用可能是负载均衡,比如将请求分发到多个服务器,提高性能;或者提供安全防护,隐藏后端服务器的真实信息,防止直接攻击。比如Nginx常用来做反向代理,处理静态资源,转发动态请求到Tomcat等应用服务器。
2. 实例:
-
网站负载均衡:
Nginx作为反向代理,将用户请求分发到多个Tomcat服务器。 -
CDN加速:
用户访问www.example.com
时,实际连接到最近的CDN节点(反向代理),节点缓存静态资源并返回
总结
概念区别
维度 | 正向代理 | 反向代理 |
---|---|---|
代理方向 | 客户端 → 代理 → 目标服务器 | 客户端 → 代理 → 后端服务器 |
隐藏对象 | 客户端身份 | 服务器身份 |
使用者角色 | 客户端主动控制(如设置代理) | 服务端主动部署(客户端无感知) |
典型问题解决 | 客户端隐私、访问限制绕过 | 服务器安全、高并发处理、服务扩展 |
核心应用场景区别
场景 | 正向代理 | 反向代理 |
---|---|---|
身份隐藏 | 隐藏客户端真实IP(如爬虫、匿名访问) | 隐藏后端服务器IP(防止直接攻击) |
访问控制 | 限制内网用户访问外部资源(如企业防火墙) | 限制外部用户访问后端服务(如API鉴权) |
内容过滤 | 屏蔽特定网站(如公司禁止访问社交媒体) | 过滤恶意请求(如WAF防火墙) |
性能优化 | 缓存常用内容(如减少重复下载) | 负载均衡、缓存静态资源(如Nginx加速) |
突破限制 | 绕过地域封锁(如访问被限制的网站) | 统一接入多区域服务器(如CDN分发) |
反向代理
4.2 使用NGINX的Lua模块来定制请求处理流程
Lua模块是NGINX的一个扩展,允许你使用Lua编程语言在NGINX配置中嵌入自定义的脚本逻辑。通过使用Lua模块、你可以在请求外理过程中执行自定义的操作。从而实现灵活的定制和扩展。
Lua模块在NGINX中提供了以下功能:
请求处理: 你可以使用Lua脚本来修改请求头部、查询参数、请求体等,从而在请求处理过程中进行自定义操作。
响应处理: 你可以使用Lua脚本来处理服务器的响应,修改应内容、响应头部等。
访问控制: 通过Lua脚本,你可以实现基于复杂条件的访问控制,例如IP白名单、黑名单,自定义的访问规则等。
缓存控制: 使用Lua脚本,你可以实现自定义的缓存控制逻辑,以满足特定的缓存需求。
复杂重定向: Lua模块可以处理更复杂的重定向逻辑,根据请求条件进行不同的重定向操作。
4.3 负载均衡是什么?如何具体实现配置负载均衡?
负载均衡(Load Balancing)是一种将网络流量或计算任务分散到多个服务器的技术,目的是提高系统性能、可用性和可靠性。通过避免单点过载,它可以提升吞吐量、降低延迟,并确保服务在部分服务器故障时仍能正常运行。
Nginx 是一个高性能的反向代理服务器,通过以下核心机制实现负载均衡:
1. 反向代理架构
-
Nginx 作为客户端和后端服务器之间的中介,接收请求后按策略将请求分发到多个后端服务器(如 Web 应用服务器、API 服务等)。
2. 配置 upstream
模块
-
在 Nginx 配置中,通过
upstream
块定义后端服务器组(负载均衡池):http { upstream backend_servers { server 192.168.1.10:80; # 后端服务器1 server 192.168.1.11:80; # 后端服务器2 server 192.168.1.12:80; # 后端服务器3 } }
3. 选择负载均衡算法
Nginx 支持多种分发策略:
-
轮询(Round Robin):默认方式,按顺序依次分配请求。
-
加权轮询(Weighted Round Robin):根据服务器性能分配权重,权重高的处理更多请求。
server 192.168.1.10 weight=3; # 处理3倍于其他服务器的请求 server 192.168.1.11 weight=2;
-
IP 哈希(IP Hash):根据客户端 IP 计算哈希值,固定将同一用户的请求分发到同一服务器(适用于会话保持)。
upstream backend_servers { ip_hash; server 192.168.1.10; server 192.168.1.11; }
-
最少连接(Least Connections):将请求分发给当前连接数最少的服务器。
upstream backend_servers { least_conn; server 192.168.1.10; server 192.168.1.11; }
-
响应时间优先(需第三方模块):根据服务器响应时间动态分配请求(如
fair
模块)。
4. 健康检查
-
被动检查:Nginx 默认自动标记故障服务器(如连接超时或返回错误码),暂时停止向其分发请求。
-
主动检查(需 Nginx Plus 或第三方模块):定期向后端服务器发送探测请求,确认存活状态。
5. 示例配置
http {
upstream backend {
server app1.example.com weight=5; # 权重5
server app2.example.com;
server 192.168.1.12:8080 backup; # 备用服务器(仅当主服务器全宕机时启用)
}
server {
listen 80;
location / {
proxy_pass http://backend; # 将请求转发到负载均衡池
proxy_set_header Host $host;
}
}
}
4.4 如何在nginx实现基于ip的访问控制
在 Nginx 中实现基于 IP 的访问控制是一种常见的安全策略,可以通过 allow
和 deny
指令限制特定 IP 地址或网段的访问权限。以下是详细的实现方法及示
1. 基础配置:允许/拒绝特定 IP
场景:
-
允许特定 IP 访问,拒绝其他所有 IP(白名单模式)。
-
或拒绝特定 IP,允许其他所有 IP(黑名单模式)。
配置语法:
location / {
# 白名单模式(仅允许指定 IP)
allow 192.168.1.100; # 允许单个 IP
allow 10.0.0.0/24; # 允许一个网段
deny all; # 拒绝其他所有 IP
# 或黑名单模式(仅拒绝指定 IP)
deny 203.0.113.5;
allow all;
}
规则说明:
-
allow
和deny
按顺序生效,匹配到第一个规则后停止后续检查。 -
白名单模式:先明确允许的 IP,最后用
deny all
拒绝其他所有请求。 -
黑名单模式:先明确拒绝的 IP,最后用
allow all
允许其他请求。
2. 全局访问控制(整个 Server 块)
将规则放在 server
块中,对整个虚拟主机生效:
server {
listen 80;
server_name example.com;
# 全局白名单
allow 192.168.1.0/24;
allow 10.100.20.5;
deny all;
location / {
root /var/www/html;
}
}
3. 针对特定路径(Location 块)
仅限制某个路径的访问(如管理后台):
server {
listen 80;
server_name example.com;
location / {
root /var/www/html;
}
location /admin {
# 仅允许管理员 IP 访问后台
allow 192.168.1.100;
deny all;
# 其他配置
proxy_pass http://backend;
}
}
4. 动态 IP 控制(使用 geo
模块)
通过 geo
模块定义变量,实现更灵活的 IP 分组管理:
# 定义 IP 黑名单变量
geo $block_ip {
default 0;
203.0.113.0/24 1; # 黑名单网段
198.51.100.5 1; # 黑名单单 IP
}
server {
listen 80;
server_name example.com;
location / {
if ($block_ip) {
return 403; # 直接返回 403 禁止访问
}
root /var/www/html;
}
}
5. 从文件加载 IP 列表
将允许或拒绝的 IP 列表保存到文件中,避免配置冗余:
# 创建 IP 白名单文件(如 /etc/nginx/conf.d/allow_ips.conf)
allow 192.168.1.100;
allow 10.0.0.0/24;
deny all;
在 Nginx 配置中引入该文件:
server {
listen 80;
server_name example.com;
location / {
include /etc/nginx/conf.d/allow_ips.conf;
root /var/www/html;
}
}
6. 结合 HTTP 认证(增强安全性)
同时使用 IP 限制和 HTTP 基础认证:
location /secure {
allow 192.168.1.0/24;
deny all;
auth_basic "Restricted Area";
auth_basic_user_file /etc/nginx/.htpasswd;
}
7. 自定义拒绝访问页面
为被拒绝的请求返回自定义错误页:
server {
error_page 403 /custom_403.html;
location = /custom_403.html {
root /usr/share/nginx/html;
internal;
}
location / {
allow 192.168.1.0/24;
deny all;
}
}
8. 常见问题排查
-
403 Forbidden 错误:
-
检查
allow
/deny
规则顺序。 -
确保 Nginx 配置中未在其他位置覆盖规则。
-
-
规则未生效:
-
重新加载配置:
nginx -s reload
。 -
检查客户端 IP 是否被代理服务器(如 CDN)修改,需配置
set_real_ip_from
。
-