Nginx 作为反向代理服务器和负载均衡器在网络架构中扮演了重要角色。它能够分发客户端请求到多台后端服务器,从而提高应用的可用性和性能,还可隐藏后端服务器,提高安全性。

可代理到http服务器,或其他协议的服务,如FastCGI、uwsgi、SCGI、memcaced。

使用proxy_pass指令,指定域名或ip地址,还可能包括端口 URI。代理到非http服务,使用相应**_pass指令:

如fastcgi_pass, uwsgi_pass …

1
2
3
4
5
6
7
location /some/path/ {
proxy_pass http://www.example.com/link/; #包含URI
}

location ~ \.php {
proxy_pass http://127.0.0.1:8000;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
server {
listen 80;
server_name example.com;

location / {
proxy_pass http://backend_server;
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;
}
}

使用https

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
server {
listen 443 ssl; # 监听 HTTPS
server_name example.com;

ssl_certificate /path/to/example.com.crt;
ssl_certificate_key /path/to/example.com.key;

location / {
proxy_pass http://backend_server;
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 反向代理配置中,以下几个关键的指令用于控制请求的转发和响应的处理。

代理常用指令

proxy_pass

  • 功能:将请求转发到指定的后端服务器。

  • 语法proxy_pass URL;

  • 用法proxy_pass 指令指定了请求将被转发到的目标服务器,可以是一个协议(如 httphttps)加地址,也可以是一个 upstream 定义的服务器组。

    1
    2
    3
    location / {
    proxy_pass http://backend_server;
    }

    如果路径后面带有 URI,Nginx 会将该 URI 与请求 URI 的匹配部分一起转发。

代理服务器,通常需要将客户端请求头部信息或自定义头部信息传递给后端服务器,使用proxy_set_header指令。

proxy_set_header

  • 功能:设置在转发到后端服务器时需要附加或修改的请求头。

  • 语法proxy_set_header FIELD VALUE;

  • 常见用法

    • Host:保持客户端请求中的主机头,方便后端根据域名处理请求。

      1
      proxy_set_header Host $host;
    • X-Real-IP:将客户端的真实 IP 地址发送给后端。

      1
      proxy_set_header X-Real-IP $remote_addr;
    • X-Forwarded-For:用于记录代理链中的客户端 IP 地址。

      1
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    • X-Forwarded-Proto:告诉后端使用的协议(HTTP 或 HTTPS)。

      1
      proxy_set_header X-Forwarded-Proto $scheme;

proxy_read_timeoutproxy_connect_timeout

  • 功能:设置与后端服务器的连接和读取超时时间。

  • 语法

    • proxy_connect_timeout time;
    • proxy_read_timeout time;
  • 用法

    • proxy_connect_timeout 设置连接到后端服务器的最大时间。

      1
      proxy_connect_timeout 30s;
    • proxy_read_timeout 设置从后端服务器读取响应的最大时间。

      1
      proxy_read_timeout 60s;

proxy_redirect

  • 功能:修改后端服务器返回的重定向响应中的 Location 头。

  • 语法proxy_redirect default;proxy_redirect off;

  • 用法

    • 修改重定向的 URL。

      1
      proxy_redirect http://backend.example.com/ https://example.com/;
    • default 表示使用默认重写规则,off 表示不进行任何修改。

proxy_cache

  • 功能:启用响应缓存以提高性能。

  • 语法proxy_cache zone;

  • 用法

    • zone 是定义的缓存区域名,使用 proxy_cache_path 指令定义。

      1
      proxy_cache my_cache;
    • 需要结合其他指令如 proxy_cache_valid 来控制缓存策略。

proxy_buffering

  • 功能:控制代理缓冲行为。

  • 语法proxy_buffering on|off;

  • 用法

    • on 表示启用缓冲(默认),off 表示禁用缓冲。

      1
      proxy_buffering off;

proxy_buffers

  • 功能:设置用于存储来自后端服务器的响应的缓冲区大小和数量。

  • 语法proxy_buffers number size;

  • 用法

    • 设置缓冲区数量和每个缓冲区的大小。

      1
      proxy_buffers 8 16k;

反向代理示例

结合上述指令,完整的 Nginx 反向代理配置示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
http {
upstream backend {
server backend1.example.com;
server backend2.example.com;
}

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;
proxy_connect_timeout 30s;
proxy_read_timeout 60s;
proxy_redirect off;
proxy_buffering on;
proxy_cache my_cache;
}
}
}

代理缓存

代理缓存(proxy_cache),它允许 Nginx 缓存从后端服务器获取的响应数据,并在后续的请求中直接从缓存中提供这些数据,而无需再次请求后端服务器。这不仅可以减轻后端服务器的负载,还可以提高响应速度。

当客户端向 Nginx 发送请求时,Nginx 首先检查缓存中是否已经存在该请求的响应。如果存在并且未过期,Nginx 会直接将缓存中的数据返回给客户端。如果缓存中没有响应数据或数据已过期,Nginx 会将请求转发到后端服务器,获取响应后再将其缓存,以供后续请求使用。

配置代理缓存

要配置 Nginx 的代理缓存,通常需要以下几个步骤:

1. 定义缓存区域

首先,定义一个缓存区域,用来存储缓存的内容。使用 proxy_cache_path 指令指定缓存的位置、大小以及其他缓存参数。

1
2
3
http {
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m use_temp_path=off;
}
  • /var/cache/nginx:缓存文件的存储路径。
  • levels=1:2:缓存文件目录层次结构,用于提高文件系统的性能。
  • keys_zone=my_cache:10m:定义一个名为 my_cache 的缓存区域,10m 表示存储元数据(如缓存键)的内存大小。
  • max_size=10g:缓存区域的最大大小,超过后旧的缓存文件会被删除。
  • inactive=60m:缓存文件在 60 分钟内未被访问则过期删除。
  • use_temp_path=off:禁用使用临时路径,提高性能。
2. 在服务器块中启用缓存

在需要缓存的服务器块或位置块中启用缓存,并设置缓存相关参数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
server {
listen 80;
server_name example.com;

location / {
proxy_pass http://backend_server;
proxy_cache my_cache; # 使用定义的缓存区域
proxy_cache_valid 200 302 10m; # 对状态码为 200 和 302 的响应缓存 10 分钟
proxy_cache_valid 404 1m; # 对状态码为 404 的响应缓存 1 分钟
proxy_cache_key "$scheme$request_method$host$request_uri"; # 定义缓存键
proxy_cache_use_stale error timeout updating; # 在后端出现错误或超时时使用旧的缓存
add_header X-Cache-Status $upstream_cache_status; # 返回缓存状态头信息
}
}
  • proxy_cache my_cache;:启用 my_cache 区域的缓存。
  • proxy_cache_valid:设置不同状态码响应的缓存时间。
    • 200:正常的响应(如 200 OK)。
    • 302:重定向响应。
    • 404:未找到的响应。
  • proxy_cache_key:定义缓存键,决定哪些请求会被缓存。通常包括协议、请求方法、主机名和请求 URI。
  • proxy_cache_use_stale:当后端服务器不可用或请求超时时,使用旧的缓存数据。常用选项包括 errortimeoutinvalid_headerupdating 等。
  • add_header X-Cache-Status $upstream_cache_status;:在响应头中添加缓存状态信息,如 HITMISSEXPIRED,帮助调试。
3. 设置缓存控制头

Nginx 默认会遵循后端服务器的 Cache-ControlExpires 头来决定是否缓存和缓存多久。可以通过 proxy_ignore_headers 指令忽略这些头信息,自定义缓存策略。

1
2
3
4
5
location / {
proxy_pass http://backend_server;
proxy_cache my_cache;
proxy_ignore_headers Cache-Control Expires;
}

常见的代理缓存配置示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
http {
# 定义缓存路径和参数
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m use_temp_path=off;

server {
listen 80;
server_name example.com;

location / {
proxy_pass http://backend_server;
proxy_cache my_cache;
proxy_cache_valid 200 302 10m;
proxy_cache_valid 404 1m;
proxy_cache_key "$scheme$request_method$host$request_uri";
proxy_cache_use_stale error timeout updating;
add_header X-Cache-Status $upstream_cache_status;
}
}
}

缓存管理和监控

  • 清除缓存:可以通过删除缓存目录中的文件手动清除缓存,也可以使用 Nginx 的 nginx -s reload 命令重新加载配置。

  • 缓存监控:通过查看响应头中的 X-Cache-Status 信息(如 HITMISS),可以了解缓存的命中率。

  • 缓存日志:启用访问日志,结合缓存状态,分析缓存效果。

通过合理配置 Nginx 代理缓存,可以大幅提高网站的响应速度,减轻后端服务器的负载,提高整体性能。

参见:

官方文档 proxy_cache

nginx负载均衡

Nginx 负载均衡是一种用于将客户端请求分发到多个后端服务器的技术,它可以提高应用程序的性能、可用性和容错性。Nginx 充当一个前端代理服务器,将请求根据特定的算法分配给一组后端服务器(也称为 upstream)。这些后端服务器可以是 Web 服务器、应用服务器、数据库服务器等。Nginx 提供了多种负载均衡算法和配置选项,可以根据不同的需求进行优化。

常见的负载均衡算法

Nginx 支持以下几种常用的负载均衡算法:

  1. 轮询(Round Robin):默认的负载均衡方式,每个请求按照顺序依次分发到不同的后端服务器。
  2. 加权轮询(Weighted Round Robin):允许为每个服务器分配权重(weight),权重越高,分配的请求越多,适合后端服务器性能不均的情况。
  3. 最少连接数(Least Connections):将请求分发给当前连接数最少的服务器,适用于后端处理时间较长的场景。
  4. IP 哈希(IP Hash):基于客户端 IP 地址的哈希值分配请求,确保同一个客户端总是被分配到同一台后端服务器。适合需要会话保持的场景。
  5. 一致性哈希(Consistent Hashing):用于在缓存或分布式存储场景下确保同一组数据总是落到同一台服务器上。

负载均衡配置http load balancing

首先使用upstream指令定义该组,放置在http上下文中。

组中的服务器用server指令配置

1
2
3
4
5
6
7
http {
upstream backend {
server backend2.com weight=5;
server backend2.com;
server 192.0.0.1 backup;
}
}

使用proxy_pass指令将请求传递到服务器组

1
2
3
4
5
server {
location / {
proxy_pass http://backend;
}
}

结合起来,http请求代理到后端服务器组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
http {
upstream backend {
# 未指定负载均衡算法
server backend1.com;
server backend2.com;
server 192.0.0.1 backup;
}

server {
location / {
proxy_pass http://backend;
}
}
}

upstream块中未指定负载均衡算法,默认使用round robin算法,即轮询。

选择负载均衡算法
1. round robin

循环法 在服务器间均匀分布,并考虑服务器权重。默认使用此负载均衡策略,不需要额外的配置。

1
2
3
4
5
6
http {
upstream backend {
server backend1.com;
server backen2.com;
}
}

可以为每个后端服务器设置权重,以调整服务器接收请求的比例。

1
2
3
4
5
6
http {
upstream backend {
server backend1.com weight=3;
server backend2.com weight=1;
}
}

weight 参数设置服务器的权重,权重越高,服务器接收请求的频率越高。

适用场景

Round Robin 算法适用于以下场景:

  • 负载均衡:适用于负载较均匀、请求处理时间大致相同的场景。
  • 资源利用:多个服务器性能相似,不需要考虑单个服务器的负载情况。
  • 简单部署:不需要复杂的负载均衡策略,快速实现请求分发。
2. least connections

最少连接 将请求分配给连接数最少的服务器

使用least_conn指令配置

1
2
3
4
5
6
7
8
http {
upstream backend {
least_conn;
server backend1.com;
server backend2.com;
server backend3.com;
}
}

进阶配置

可以为每个后端服务器设置权重、连接数等参数,以更精细地控制负载均衡策略

1
2
3
4
5
6
7
8
http {
upstream backend {
least_conn;
server backend1.com weight=3 max_fails=2 fail_timeout=30s;
server backend2.com weight=2 max_fails=2 fail_timeout=30s;
server backend3.com weight=3 max_fails=2 fail_timeout=30s;
}
}

weight 参数设置服务器的权重,权重越高,服务器被选择的概率越大。

max_fails 参数指定最大失败尝试次数,达到此次数后服务器将被视为不可用。

fail_timeout 参数指定服务器在不可用状态下的超时时间。

适用场景

Least Connections 算法适用于以下场景:

  • 请求处理时间不均匀:例如数据库查询、文件上传等场景,不同请求的处理时间可能差异较大。
  • 高并发应用:例如电商网站、社交网络等,需要在高并发环境下均衡负载,避免某些服务器过载。
3. ip hash

ip哈希 根据客户端ip地址确定请求发送到服务器。使用ipv4地址的前3个8位字节,或整个ipv6地址计算哈希值。保证来自同一地址的请求到达同一服务器,除非该服务器不可用。

这种方法特别适合需要会话保持的应用场景,如购物车、用户登录等。

1
2
3
4
5
6
7
8
http {
upstream backend {
ip_hash;
server backend1.com;
server backend2.com;
}
}
# 同一ip地址的请求将始终分配给同一服务器

如果其中一台服务器需要暂时从负载平衡轮换中删除,则可以使用down参数标记,本服务器要处理的请求会自动发送到组中下一个服务器

1
2
3
4
5
6
7
http {
upstream backend {
ip_hash;
server backend1.com down;
server backend2.com;
}
}

注意事项

  • 服务器故障处理:如果某台服务器宕机,IP Hash 可能导致部分客户端请求失败,需要结合其他健康检查和故障转移机制。
  • 平衡性:IP Hash 的负载均衡效果依赖于客户端 IP 地址的分布,如果 IP 地址分布不均匀,负载可能不平衡。
  • IPv6 支持:确保你的Nginx 版本支持 IPv6 地址的哈希计算。

可以为每个后端服服务器设置额外参数,如权重、失败处理等,weight/max_fails/fail_timeout.

4. generic hash

通用哈希(Generic Hash)算法是一种基于某些请求特征(如 URL、Cookie、Header 等)进行哈希运算来分配请求的算法。这种方法类似于 IP Hash,但可以根据更灵活的规则来决定如何分配请求,从而实现更细粒度的负载均衡和会话保持。

使用hash指令指定基于指定请求特征的哈希负载均衡

1
2
3
4
5
6
7
http {
upstream backend {
hash $request_uri; # 基于请求URI进行哈希计算
server backend1.com;
server backend2.com;
}
}

根据请求的user-Agent头进行哈希计算,使用$http_user_agent参数

根据请求的 Cookie 进行一致性哈希运算,适用于需要基于用户标识(如会话 ID)进行会话保持的场景,使用$http_cookie

可以通过hash指令的consistent参数启用一致性哈希,提高哈希分布的一致性

启用一致性哈希后,添加或删除服务器时,只会影响部分请求的分配,提高系统的稳定性和可扩展性。

1
2
3
4
5
6
7
http {
upstream backend {
hash $request_uri consistent;
server backend1.com;
server backend2.com;
}
}
5. least time

最短时间(仅限 NGINX Plus) - 对于每个请求,NGINX Plus 选择具有最低平均延迟和最少活动连接数的服务器,其中最低平均延迟是根据 least_time不同的参数计算选择。

least_time 指令有三 个参数可选:

  • least_time header:基于服务器的响应头时间进行选择。
  • least_time last_byte:基于服务器的整个响应时间(包括请求到最后一个字节)进行选择。
  • least_time inflight: 基于从服务器接收到完整响应所需的时间,并考虑当前未完成的请求数来选择目标服务器。

适用场景

Least Time 算法适用于以下场景:

  • 高并发应用:如电商网站、社交网络等,需要在高并发环境下确保请求快速响应。
  • 动态负载环境:如微服务架构,服务响应时间可能变化较大,Least Time 算法可以动态调整分配策略。
  • 优化用户体验:希望尽量减少用户等待时间,提高系统响应速度。
6. random

随机负载均衡算法 通过随机选择一台后端服务器来处理请求。与其他负载均衡算法(如轮询、最少连接等)相比,随机负载均衡算法简单直接,适用于需要基本负载分配但不需要精细控制的场景。

可以为每个后端服务器分配权重,权重越高的服务器被选择的概率越大。如果指定了 two 参数,NGINX首先根据服务器权重随机选择两台服务器,然后使用指定的方法选择其中一台服务器:

  • least_conn
  • least_time=header
  • least_time=last_byte
1
2
3
4
5
6
7
upstream backend {
random two least_time=last_byte;
server backend1.example.com;
server backend2.example.com;
server backend3.example.com;
server backend4.example.com;
}

注意:配置除循环之外的任何方法时,请放置相应的指令( haship_hashleast_connleast_timerandom)位于 upstream {} 块中的 server 指令列表上方。

server weights

前面例子已经用到了weight指令

在round robin循环算法中,根据服务器权重分配请求,默认为1.权重越高,接收的请求数量也越多。

通过设置不同的权重,你可以根据后端服务器的处理能力分配请求。例如,处理能力较强的服务器可以设置较高的权重,以便处理更多的请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
http {
upstream backend {
server backend1.example.com weight=3;
server backend2.example.com weight=1;
server backend3.example.com weight=2;
}

server {
listen 80;

location / {
proxy_pass http://backend;
}
}
}
# 这意味着:
# backend1.example.com会处理约50%的请求(3/(3+1+2))。
# backend2.example.com会处理约16.7%的请求(1/(3+1+2))。
# backend3.example.com会处理约33.3%的请求(2/(3+1+2))。
server slow-start

服务器慢启动 用于负载均衡场景下,防止新上线的服务节点因瞬间高负载,再次被标记为故障,设置慢启动可以平滑过渡。在upstream模块中配置slow_start指令

1
2
3
4
5
6
7
8
9
http {
upstream backend {
server backend1.com;
server backend2.com;
server backend3.com;

slow_start 30s; # 表示在30秒内逐步增加流量
}
}

通常与负载均衡算法一起使用,将slow_start写在特写server后面,那么慢启动策略只会用于该特定的服务器。

1
2
3
4
5
6
http {
upstream backend {
server backend1.com;
server backend2.com slow_start=30s;
}
}
enableing session persistence

启用会话保持

可以确保同一个客户端的请求始终被路由到一个后端服务器。对于需要在多次请求间保持状态的应用(如用户登录会话、购物车等)非常有用。

之前的负载算法中用到的hash, ip hash就是其中方法,使用haship_hash指令。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
http {
upstream backend {
hash $request_uri consistent;
server backend1.example.com;
server backend2.example.com;
server backend3.example.com;
}

server {
listen 80;

location / {
proxy_pass http://backend;
}
}
}
# hash $request_uri consistent指令确保基于请求的URI实现会话持久性。consistent关键字确保在增加或移除服务器时,尽量减少影响的会话数。

# 基于cookie哈希
http {
upstream backend {
hash $cookie_session_id consistent;
server backend1.example.com;
server backend2.example.com;
server backend3.example.com;
}

nginx plus支持三种会话持久性方法。使用sticky指令设置,

  • sticky cookie
  • sticky route
  • sticky learn

Sticky Cookie方法在服务器第一次响应客户端时设置一个Cookie,后续请求会使用这个Cookie来确定路由的后端服务器。nginx plus内置功能,nginx需要第三方模块支持,如nginx-sticky-module-ng

1
2
3
4
5
6
7
8
9
upstream backend {
server backend1.example.com;
server backend2.example.com;
sticky cookie srv_id expires=1h domain=.example.com path=/;
}
# sticky cookie srv_id:配置会话持久性使用基于Cookie的方法,并将Cookie命名为srv_id。
# expires=1h:设置Cookie的有效期为1小时。
# domain=.example.com:设置Cookie的作用域为.example.com,包括其所有子域。
# path=/:设置Cookie的作用路径为整个站点

nginx 下载安装nginx-sticky-module-ng模块

1
2
3
4
5
6
7
8
9
wget http://nginx.org/download/nginx-1.18.0.tar.gz
git clone https://bitbucket.org/nginx-goodies/nginx-sticky-module-ng.git
tar -zxvf nginx-1.18.0.tar.gz

cd nginx-1.18.0
./configure --add-module=../nginx-sticky-module-ng
make
sudo make install

如果已安装nginx,想添加模块

1
2
3
4
5
6
git clone https://bitbucket.org/nginx-goodies/nginx-sticky-module-ng.git
cd /path/to/nginx/source
./configure --add-module=/path/to/nginx-sticky-module-ng
make
sudo make install

配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
http {
upstream backend {
server backend1.example.com;
server backend2.example.com;
sticky cookie srv_id expires=1h domain=.example.com path=/;
}

server {
listen 80;

location / {
proxy_pass http://backend;
}
}
}

安全性:如果使用HTTPS,确保Cookie标记为Secure以防止在不安全的连接中发送。这是一种安全最佳实践,用于保护会话Cookie免受中间人攻击。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
http {
upstream backend {
server backend1.example.com;
server backend2.example.com;
sticky cookie srv_id expires=1h domain=.example.com path=/ secure;
}

server {
listen 443 ssl;
server_name example.com;

ssl_certificate /etc/nginx/ssl/nginx.crt;
ssl_certificate_key /etc/nginx/ssl/nginx.key;

location / {
proxy_pass http://backend;
}
}
}

安全最佳实践

除了将Cookie标记为Secure,还可以考虑以下安全措施:

  1. HttpOnly:将Cookie标记为HttpOnly,以防止通过客户端脚本(如JavaScript)访问Cookie。
  2. SameSite:将Cookie的SameSite属性设置为LaxStrict,以防止跨站请求伪造(CSRF)攻击。

虽然在Nginx Plus中直接配置HttpOnlySameSite属性较为复杂,但可以通过后端应用服务器设置这些属性。例如,在Nginx反向代理配置中可以通过HTTP头部设置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
http {
upstream backend {
server backend1.example.com;
server backend2.example.com;
sticky cookie srv_id expires=1h domain=.example.com path=/ secure;
}

server {
listen 443 ssl;
server_name example.com;

ssl_certificate /etc/nginx/ssl/nginx.crt;
ssl_certificate_key /etc/nginx/ssl/nginx.key;

location / {
proxy_pass http://backend;
# 通过添加Set-Cookie头部来设置HttpOnly和SameSite属性
proxy_cookie_path / "/; Secure; HttpOnly; SameSite=Lax";
}
}
}
# 在这个配置中,proxy_cookie_path指令用于修改后端服务器返回的Set-Cookie头部,添加Secure、HttpOnly和SameSite属性。

sticky route

这种方法通过在响应中插入一个“路由”信息,让后续请求能够始终路由到同一台后端服务器。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
http {
upstream backend {
# 定义后端服务器,并设置路由标识
server backend1.example.com route=a;
server backend2.example.com route=b;

# 配置 sticky route
sticky route $route_cookie $route_uri;

# 可选的全局设置
# sticky cookie srv_id expires=1h domain=.example.com path=/;
}

server {
listen 80;

location / {
# 设置 $route_uri 变量,从 URI 中提取路由信息
set $route_uri "";

# 从 URI 中提取路由信息
if ($request_uri ~* "/route/(.*)$") {
set $route_uri $1;
}

proxy_pass http://backend;
}
}
}

基于Cookie的路由信息:可以通过应用程序在响应中设置一个包含路由信息的Cookie,以便Nginx在后续请求中使用。

1
2
# 在应用程序中设置 Cookie,例如:
Set-Cookie: route=a; Path=/; HttpOnly; Secure;

sticky learn

在Nginx Plus中,stickylearn模式是一种高级的会话持久性方法,通过动态学习客户端的会话信息(如Cookie或HTTP头)来决定将请求路由到哪个后端服务器。这种方法非常适用于需要高度灵活性的场景,如用户登录会话的管理。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
http {
upstream backend {
sticky learn
create=$upstream_cookie_sessionid
lookup=$cookie_sessionid
zone=client_sessions:1m;
server backend1.example.com;
server backend2.example.com;
server backend3.example.com;
}

server {
listen 80;

location / {
proxy_pass http://backend;
# 设置 sessionid Cookie 的属性
add_header Set-Cookie "sessionid=$upstream_cookie_sessionid; Path=/; HttpOnly";
}
}
}

limiting the number of connections

在Nginx中,配置upstream块中的queuemax_conns参数可以帮助控制后端服务器的连接和请求排队策略。这个配置非常有用,特别是在负载高峰期,可以防止后端服务器过载,并确保请求能够在一定时间内得到处理。

1
2
3
4
5
6
upstream backend {
server backend1.example.com max_conns=3; # 限制最大连接数为3
server backend2.example.com;
queue 100 timeout=70; # 启用请求队列功能,当所有后端服务器的连接都达到最大值时,最多可以有100个请求在队列中等待。请求在队列中最多等待70秒,如果超过这个时间请求仍未被处理,将返回一个错误给客户端。
}

  • 防止过载:通过限制每个服务器的最大连接数,可以防止后端服务器被过多的请求淹没,从而保证服务的稳定性。
  • 排队机制:即使所有后端服务器的连接都已达到上限,请求也不会立即被拒绝,而是进入队列等待处理,这提高了服务的可用性。

根据具体需求,还可以结合其他Nginx指令进行更详细的配置。例如,设置全局的连接限制和请求速率限制。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
http {
# 定义连接限制区域
limit_conn_zone $binary_remote_addr zone=addr:10m;

upstream backend {
server backend1.example.com max_conns=3;
server backend2.example.com;
queue 100 timeout=70;
}

server {
listen 80;
server_name example.com;

location / {
# 应用连接限制
limit_conn addr 10;
proxy_pass http://backend;
}
}
}