Nginx 代理的多端口实例负载均衡

Nginx 作为高性能服务器,除了搭建普通的 web 服务,也经常用作反向代理或微服务网关。

为了实现服务高可用,通常会启动多个服务实例,这样某个实例挂掉并不影响整体的可用性,Nginx 可以在多个实例中实现负载均衡,并提供了多种负载均衡策略。

这里在本机开启多个实例,在这些实例中实现负载均衡。

在 http 配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
upstream backser {
server localhost:7100;
server localhost:7200;
server localhost:7300;
}

server {
listen 8000;
server_name backser;

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

启动服务端:

1
2
3
4
5
6
7
# 启动三个Java实例
java -jar app.jar --server.port=7100
java -jar app.jar --server.port=7200
java -jar app.jar --server.port=7300

# 启动nginx
start nginx

默认情况 Nginx 会把请求轮流派发给各个实例,实现最简单的负载均衡。

这种轮询策略可以加入权重,进行负载微调和故障转移:

1
2
3
4
5
upstream backser {
server localhost:7100 weight=1 fail_timeout=3s max_fails=2;
server localhost:7200 weight=2 fail_timeout=3s max_fails=2;
server localhost:7300 weight=3 fail_timeout=3s max_fails=2;
}

另一种使用较多的是 ip_hash 策略,能将来自同一 IP 的客户端请求派发给同一个服务实例,在分布式环境中,可以解决 session 不共享的问题。

1
2
3
4
5
6
upstream backser {
server localhost:7100 fail_timeout=3s max_fails=2;
server localhost:7200 fail_timeout=3s max_fails=2;
server localhost:7300 fail_timeout=3s max_fails=2;
ip_hash;
}

加载修改后的配置:

1
nginx -s reload

然后同一个客户端请求会发现只有一个实例在响应。