一、基本概念
-
Nginx提供了哪些功能?
- 轻量级开源Web服务器软件(相比于apache,iis等)
- 高性能(可承受3万以上并发连接数,是apache的10倍)
- 代理服务,包括正向代理,反向代理(四层代理,七层代理)
- 动静分离(用于提供文件服务等)
- 扩展性(lua,java)
二、反向代理和正向代理
1.反向代理 (Reverse Proxy)作用:
- 负载均衡:在多个后端服务器之间分发客户端请求,以确保没有任何服务器过载。
- Web 加速:使用缓存来减少后端服务器的负载并加快响应速度。
- SSL 终止:处理 SSL/TLS 握手和解密,释放后端服务器的负担。
- 安全和匿名性:隐藏后端服务器的真实 IP 地址和身份,为后端服务器提供一个保护层,从而提高安全性。
工作流程:
- 客户端发起请求到代理服务器。
- 代理服务器根据某种策略决定将请求转发到哪个后端服务器。
- 后端服务器处理请求并返回响应给代理服务器。
- 代理服务器再将响应返回给客户端。
2.正向代理 (Forward Proxy)作用:
- 访问限制:企业或学校可能使用正向代理来限制员工或学生访问特定的外部网站。
- 内容过滤:正向代理可以用来过滤某些不安全或不恰当的内容。
- 缓存:减少外部请求并加速访问速度。
- 匿名浏览:隐藏用户的真实 IP 地址,使用户可以匿名访问互联网。
3.主要区别
| 属性/代理类型 | 反向代理 | 正向代理 |
|---|---|---|
| 目的 | 通常在服务器端,用于负载均衡、安全、加速等。 | 通常在客户端,用于匿名浏览、访问控制、内容过滤等。 |
| 位置 | 位于后端服务器和客户端之间 | 位于客户端和所有互联网服务器之间 |
| 知晓性 | 客户端可能不知道自己正在与反向代理通信 | 客户端通常知道并显式配置其浏览器或应用程序以使用正向代理。 |

三、反向代理
当你的网站流量增加时,一个服务器可能不足以处理所有请求。在这种情况下,你可以设置多个应用服务器,并使用 Nginx作为负载均衡器,根据特定的算法(如轮询、最少连接等)将请求分发到各个服务器。
| 算法 | 对故障服务器的处理 | 服务器恢复后的行为 |
|---|---|---|
| 轮询(Round Robin) | 继续发送请求到故障服务器,可能导致失败或超时 | 恢复后重新开始分发请求 |
| 权重(Weighted RR) | 停止发送请求到故障服务器,直到恢复正常 | 恢复后重新开始分发请求,根据权重可能有不同的比例 |
| 最小连接(Least Conn) | 继续发送请求到故障服务器,可能导致失败或超时 | 恢复后重新开始分发请求,基于当前连接数选择服务器 |
| IP哈希(IP Hash) | 继续将请求发送到故障服务器 | 恢复后继续将来自相同IP地址的请求发送到相同服务器 |
热备 (Hot Standby)
当您有一个备份服务器可用时,您可以配置 Nginx 以只在主服务器失败时使用它.
http {
upstream myapp0 {
server www.example.com;
server bad.example.com down;
server bak.example.com backup;
}
server {
listen 80; # 侦听 80 端口
server_name www.example.com; # 服务器域名
location / {
proxy_pass http://myapp0; # 转发请求到上面定义的 upstream
}
}
}
1. 初始请求:
当一个请求到达 Nginx 并被定向至 myapp0 后端组,首先会尝试转发请求至 www.example.com。这是因为它是 upstream 配置块中的第一个 server 指令。
2. 跳过标记为 down 的服务器:
Nginx 会跳过 bad.example.com,因为它后面的 down 指令标记这个服务器为不可用。
3. 使用备份服务器:
如果 www.example.com 无法处理请求(例如,它宕机或超时),Nginx 会考虑转发请求至 bak.example.com。这是由于它后面的 backup 指令,它被指定为备份服务器,只在其他非备份服务器不可用时才会被考虑。
总结:
默认地,请求会被转发至 www.example.com。只有当 www.example.com 无法处理请求时,才会考虑备份服务器 bak.example.com。而 bad.example.com 由于标记为 down,所以永远不会接收到请求。
轮询 (Round Robin)
流程:
- 客户端发起请求到 Nginx。
- Nginx 根据轮询策略将请求转发到下一个服务器。
- 后端服务器处理请求并返回响应到 Nginx。
- Nginx 将响应返回给客户端。
http {
upstream myapp1 {
# 使用轮询算法
server srv1.example.com; # 第一个服务器
server srv2.example.com; # 第二个服务器
server srv3.example.com; # 第三个服务器
}
server {
listen 80; # 侦听 80 端口
server_name www.example.com; # 服务器域名
location / {
proxy_pass http://myapp1; # 转发请求到上面定义的 upstream
}
}
}
最少连接 (Least Connections)
流程:
- 客户端发起请求到 Nginx。
- Nginx 检查所有后端服务器,选择当前有最少活动连接的服务器。
- 将请求转发到该服务器。
- 服务器处理请求并返回响应到 Nginx。
- Nginx 将响应返回给客户端。
http {
upstream myapp2 {
least_conn; # 使用最少连接算法
server srv1.example.com; # 第一个服务器
server srv2.example.com weight=3; # 第二个服务器,权重为 3
}
server {
listen 80; # 侦听 80 端口
server_name www.example.com; # 服务器域名
location / {
proxy_pass http://myapp2; # 转发请求到上面定义的 upstream
}
}
}
IP 哈希 (IP Hash)
http {
upstream myapp3 {
ip_hash; # 使用 IP 哈希算法
server srv1.example.com; # 第一个服务器
server srv2.example.com; # 第二个服务器
}
server {
listen 80; # 侦听 80 端口
server_name www.example.com; # 服务器域名
location / {
proxy_pass http://myapp3; # 转发请求到上面定义的 upstream
}
}
}
IP哈希(IP Hash)负载均衡工作原理:
客户端发起请求到Nginx。Nginx获取客户端的IP地址。Nginx使用客户端IP地址计算哈希值。这个哈希值通常是一个非负整数。哈希值与后端服务器的数量进行取模运算(求余数),以确定应该将请求路由到哪个后端服务器。
假设你有两台后端服务器,分别为 srv1.example.com 和 srv2.example.com。
如果哈希值是奇数,那么 (哈希值 % 2) 结果为1,请求将路由到 srv2.example.com。
如果哈希值是偶数,那么 (哈希值 % 2) 结果为0,请求将路由到 srv1.example.com。
请求被转发到选中的后端服务器,然后由该服务器处理。
请求被转发到选中的后端服务器,然后由该服务器处理。
📝 这个过程确保了相同客户端IP地址的请求将始终被路由到相同的后端服务器,从而维护了会话状态。不同的客户端IP地址将产生不同的哈希值,这会分散负载并确保请求被均匀地分配给后端服务器。
⚠️ 需要注意的是,IP哈希算法有一些限制,例如,如果后端服务器的数量变化,哈希值可能导致不均匀的分配。因此,在使用IP哈希算法时,通常需要考虑后端服务器的动态性。如果服务器数量经常变化,可能需要其他负载均衡算法来更好地适应变化。
加权负载均衡 (Weighted Load Balancing)
可以为每个后端服务器分配一个权重,权重高的服务器将处理更多的请求。
http {
upstream myapp4 {
server myapp41.example.com;
server myapp42.example.com weight=3;
server myapp43.example.com weight=2;
}
server {
listen 80; # 侦听 80 端口
server_name www.example.com; # 服务器域名
location / {
proxy_pass http://myapp4; # 转发请求到上面定义的 upstream
}
}
}
proxy_next_upstream 指令
当使用 Nginx 进行反向代理和负载均衡时,proxy_next_upstream 指令非常有用。以下是一个完整的 Nginx 示例配置,包括了 proxy_next_upstream 的使用以及一些其他相关配置项的说明:
error 建立连接 / 发送请求 / 接收响应时出错(缺省值之一);
timeout 建立连接 / 发送请求 / 接收响应时超时(缺省值之一);
invalid_header 上游返回空白或无效响应;
http_500 上游返回 500 Internal Server Error;
http_501 上游返回 501 Not Implemented;
http_502 上游返回 502 Bad Gateway;
http_503 上游返回 503 Service Unavailable;
http_504 上游返回 504 Gateway Timeout;
http_404 上游返回 404 Not Found;
http_429 上游返回 429 Too Many Requests;
non_idempotent 解除对非幂等请求 (POST, LOCK, PATCH) 的封印,小心造成重复提交;
off 不得转给下一台服务器。
Nginx配置示例
http {
upstream myapp5 {
server myapp51.example.com;
server myapp52.example.com;
server myapp53.example.com;
}
server {
listen 80;
server_name mywebsite.com;
location / {
proxy_pass http://myapp5;
# 使用 proxy_next_upstream 指令定义故障转移策略
proxy_next_upstream error timeout http_500 http_502 http_503 http_504;
# 设置最大失败次数和超时时间
proxy_max_temp_file_size 0;
proxy_connect_timeout 5;
proxy_send_timeout 5;
proxy_read_timeout 5;
proxy_buffering off;
}
}
}
解释和说明:
在 upstream 块中定义了一个名为 myapp5 的后端服务器组,其中包含了三个后端服务器。这是要负载均衡的服务器池。
在 server 块中,我们定义了一个虚拟主机,监听端口 80,该虚拟主机用于处理来自 mywebsite.com 的请求。
在 location / 块中,我们配置了反向代理,将请求代理到名为 myapp5 的后端服务器组。这是一个基本的反向代理配置。
🔄 proxy_next_upstream 指令定义了故障转移策略。根据这个配置,当发生以下情况之一时,Nginx 将尝试使用下一个可用的后端服务器:通信错误 (error)、连接或读取超时 (timeout)、后端服务器返回 HTTP 500、502、503 或 504 错误。
我们还设置了一些与代理相关的超时和缓冲参数,以确保在发生问题时有适当的超时和缓冲控制。这些设置可以根据实际需求进行调整。
总之,上述配置演示了如何在 Nginx 中使用 proxy_next_upstream 指令来定义故障转移策略。当一个请求到达时,Nginx 将尝试将其转发到 myapp5 中的服务器,并根据 proxy_next_upstream 指令定义的错误情况来决定是否尝试下一个服务器,从而实现负载均衡和故障转移的目标。
四.正向代理 (Forward Proxy) 客户端
访问限制
示例:阻止访问facebook.com和twitter.com。
server {
listen 8080;
location / {
# 检查请求的Host是否是被禁止的站点
if ($http_host ~* (facebook.com|twitter.com)) {
return 403; # 如果是,返回403 Forbidden响应
}
proxy_pass http://$http_host$request_uri;
proxy_set_header Host $http_host;
}
}
内容过滤
示例:过滤包含关键词confidential的响应内容。
# 注意: 这是一个简化示例,实际实现可能需要第三方模块或更复杂的配置
server {
listen 8080;
location / {
proxy_pass http://$http_host$request_uri;
proxy_set_header Host $http_host;
# 存储响应在变量中
proxy_buffering on;
proxy_buffers 1 1m;
proxy_store /tmp/$binary_remote_addr;
if ($upstream_http_body ~* confidential) {
return 403;
}
}
}
📝 操作流程:
- 客户端请求某个资源。
- 请求首先发送到8080端口上的Nginx正向代理。
- 代理将请求转发到目标服务器。
- 当响应返回时,代理检查响应内容是否包含关键词
confidential。 - 如果找到,代理返回403 Forbidden响应。
缓存
示例:缓存外部网站响应1小时
server {
listen 8080;
location / {
proxy_pass http://$http_host$request_uri;
proxy_set_header Host $http_host;
proxy_cache my_cache;
proxy_cache_valid 200 302 1h;
}
}
# 定义缓存路径和大小
proxy_cache_path /path/to/cache levels=1:2 keys_zone=my_cache:10m max_size=1g
inactive=60m use_temp_path=off;
匿名浏览:
示例:使用代理隐藏客户端的真实IP。
server {
listen 8080;
location / {
proxy_pass http://$http_host$request_uri;
# 清除客户端原始IP信息
proxy_set_header X-Real-IP "";
proxy_set_header X-Forwarded-For "";
proxy_set_header Host $http_host;
}
}
📝 操作流程:
- 客户端请求某个资源。
- 请求首先发送到8080端口上的Nginx正向代理。
- 代理清除关于客户端真实IP的所有头信息。
- 代理将请求转发到目标服务器,但目标服务器无法知道客户端的真实IP。

487

被折叠的 条评论
为什么被折叠?



