Nginx负载均衡和反向代理

Nginx反向代理和负载均衡

一、Nginx的应用场景与区别

Nginx能够实现哪些事情?(应用场景)

1.反向代理:客户端使用Nginx转发到真实服务器访问,从而保证真实服务安全性;

2.负载均衡:能够对集群的节点实现负载均衡;

3.微服务网关入口:实现对服务转发 根据域名路由到真实的服务;

4.静态资源服务器:比Tomcat性能高很多,可以存放静态资源;

5.保护网站:安全策略、熔断、防止ddos攻击、限流;

正向代理 反向代理
隐藏用户行为 隐藏真实服务器、隐藏真实服务ip地址 安全
比如访问一些国外的网站,需要通过VPN翻墙才可以访问,这时候就可以使用正向代理隐藏用户行为 客户端请求打到代理服务器,再通过代理服务器转发到真实服务器

二、Nginx反向代理配置

基于Nginx实现反向代理

Windows: C:\Windows\System32\drivers\etc host文件中新增

Linux: /etc/nginx/nginx.conf文件中新增

反向代理配置

1
2
3
4
5
6
7
8
9
10
11
12
13
server {
# 使用nginx创建了监听端口号码为80
listen 80;
## localhost
server_name www.baidu.com;
## 根据url规则匹配
location / {
## 反向代理配置
proxy_pass http://127.0.0.1:8080; #实现反向代理 访问80端口代理至8080端口
## 默认查找index
index index.html index.htm;
}
}

三、Nginx负载均衡和策略

什么是负载均衡?

当一台服务器的单位时间内的访问量越大时,服务器压力就越大,大到超过自身承受能力时,服务器就会崩溃。为了避免服务器崩溃,让用户有更好的体验,通过负载均衡的方式来分担服务器压力。

我们可以建立很多很多服务器(服务器集群)——解决高并发,组成一个服务器集群,当用户访问网站时,先访问一个中间服务器,再让这个中间服务器在服务器集群中选择一个压力较小的服务器,然后将该访问请求引入该服务器。如此以来,用户的每次访问,都会保证服务器集群中的每个服务器压力趋于平衡,分担了服务器压力,避免了服务器崩溃的情况。

服务器集群中会存在哪些问题?

服务器集群中的jar包都是完全相同的

1.分布式Session一致性问题:可以使用spring-session框架或者Token替代解决

2.分布式任务调度重复执行:分布式任务调度平台 xxl-job

3.分布式日志收集问题:elk+kafka日志收集

​ 分布式事务和集群没有关系

目前Nginx服务器的upstream模块支持6种方式的分配:

名称 说明
轮询 默认方式
weight 权重方式
ip_hash 依据ip分配方式
least_conn 最少连接方式
fair(第三方) 响应时间方式
url_hash(第三方) 依据URL分配方式

基于Nginx实现负载均衡——六种负载均衡策略

轮询(默认) 指定权重(weight) IP绑定ip_hash least_conn(最少连接) fair(第三方) url hash(第三方)
每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除 指定轮询几率,weight(权重)访问比率成正比,用于后端服务器性能不均的情况 每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。 把请求转发给连接数较少的后端服务器。 按后端服务器的响应时间来分配请求,响应时间短的优先分配 访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,后端服务器为缓存时比较有效

哈希(Hashing)是一种常用的技术,将数据(如字符串、文件等)转换为固定长度的值或键(Key)。这个过程通常用于提高数据检索的效率,比如在数据库索引、缓存、数据加密等领域。

在网络会话管理中,指服务器与浏览器间的会话机制,通过Session ID识别用户身份,采用Cookie或URL重写传输ID,并需考虑安全策略如HTTPS加密。‌

访问率是互联网领域用于衡量用户访问行为的基础指标,这个术语在其他广告媒体上也和在网络上一样使用。该术语通过统计用户访问次数与目标群体总量的比值,反映特定时期内用户接触媒介内容的频率。计算方式:*同类网站访问率= 同类网站访问量÷网站总访问量×100%*

**1、轮询法(默认)**:最基本的配置方法,上面的例子就是轮询的方式,它是upstream模块默认的负载均衡默认策略。每个请求会按时间顺序逐一分配到不同的后端服务器。

参数

名称 说明
fail_timeout 与max_fails结合使用。
max_fails 设置在fail_timeout参数设置的时间内最大失败次数,如果在这个时间内,所有针对该服务器的请求都失败了,那么认为该服务器会被认为是停机了。
fail_time 服务器会被认为停机的时间长度,默认为10s。
backup 标记该服务器为备用服务器。当主服务器停止时,请求会被发送到它这里。
down 标记服务器永久停机了。

注意: 在轮询中,如果服务器down掉了,会自动剔除该服务器。 缺省配置就是轮询策略。此策略适合服务器配置相当,无状态且短平快的服务使用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
nginx.conf
###定义上游服务器(需要被nginx真实代理访问的服务器) 默认是轮询机制
##上游服务器集群节点
upstream backServer{
##新增集群节点 默认策略负载均衡(轮询机制)
server 127.0.0.1:8080;
server 127.0.0.1:8081;
}

server {
# 使用nginx创建了监听端口号码为80
listen 80;
## localhost
server_name www.baidu.com;
## 根据url规则匹配
location / {
## 反向代理配置
proxy_pass http://backServer;
## 默认查找index
index index.html index.htm;
}
}

2、指定权重(加权轮询法)

权重方式,在轮询策略的基础上指定轮询的几率 —— 权重越大,访问越多

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
nginx.conf
###定义上游服务器(需要被nginx真实代理访问的服务器) 默认是轮询机制
##上游服务器集群节点
upstream backServer{
##新增集群节点 默认策略负载均衡(轮询机制)
server 127.0.0.1:8080 weight=1; #权重1
server 127.0.0.1:8081 weight=2; #权重2
}

server {
# 使用nginx创建了监听端口号码为80
listen 80;
## localhost
server_name www.baidu.com;
## 根据url规则匹配
location / {
## 反向代理配置
proxy_pass http://backServer;
## 默认查找index
index index.html index.htm;
}
}

注意:

  • 权重越高分配到需要处理的请求越多。
  • 此策略可以与least_conn和ip_hash结合使用。
  • 此策略比较适合服务器的硬件配置差别比较大的情况。

3、IP绑定ip_hash(源地址哈希法)

指定负载均衡器按照基于客户端IP的分配方式,这个方法确保了相同的客户端的请求一直发送到相同的服务器,以保证session会话。这样每个访客都固定访问一个后端服务器,可以解决session不能跨服务器的问题。

1
2
3
4
5
6
7
8
#动态服务器组
upstream backServer {
ip_hash; #保证每个访客固定访问一个后端服务器
server localhost:8080 weight=2; #tomcat 7.0
server localhost:8081; #tomcat 8.0
server localhost:8082; #tomcat 8.5
server localhost:8083 max_fails=3 fail_timeout=20s; #tomcat 9.0
}

注意:

  • 在nginx版本1.3.1之前,不能在ip_hash中使用权重(weight)。
  • ip_hash不能与backup同时使用。
  • 此策略适合有状态服务,比如session。当有服务器需要剔除,必须手动down掉。
  • 缺点:分配到哪台节点,后面会一直访问同一台节点,但集群就没有效果了,无意义

4、least_conn(最少连接)

把请求转发给连接数较少的后端服务器。轮询算法是把请求平均的转发给各个后端,使它们的负载大致相同;但是,有些请求占用的时间很长,会导致其所在的后端负载较高。这种情况下,least_conn这种方式就可以达到更好的负载均衡效果。

1
2
3
4
5
6
7
8
#动态服务器组
upstream backServer {
least_conn; #把请求转发给连接数较少的后端服务器
server localhost:8080 weight=2; #tomcat 7.0
server localhost:8081; #tomcat 8.0
server localhost:8082 backup; #tomcat 8.5
server localhost:8083 max_fails=3 fail_timeout=20s; #tomcat 9.0
}

注意: 此负载均衡策略适合请求处理时间长短不一造成服务器过载的情况


5、fair法(第三方)

按照服务器端的响应时间来分配请求,响应时间短的优先分配。

在Nginx中使用Fair负载均衡算法,必须安装ngx_http_upstream_fair_module模块。这个模块是第三方插件,默认未包含在Nginx的标准发行版中,因此需要手动编译和安装。

安装Fair模块

1、下载Nginx源码:

1
2
wget http://nginx.org/download/nginx-<version>.tar.gz
tar -zxvf nginx-<version>.tar.gz

2、下载Fair模块源码:

1
git clone https://github.com/itoffshore/nginx-upstream-fair.git

3、编译并安装Nginx:在Nginx源码项目下,使用以下命令编译Nginx,同时添加Fair模块

1
2
3
4
cd nginx-<version>
./configure --add-module=../nginx-upstream-fair
make
sudo make install

4、配置Nginx使用Fair算法:在Nginx配置文件(nginx.conf)中,可以通过以下配置算法来使用Fair算法

1
2
3
4
5
6
7
8
#动态服务器组
upstream backend_Server {
server localhost:8080; #tomcat 7.0 //server ***.***.***.***:8081;
server localhost:8081; #tomcat 8.0 //server ***.***.***.***:8082;
server localhost:8082; #tomcat 8.5
server localhost:8083; #tomcat 9.0
fair; #实现响应时间短的优先分配
}

在这里,定义了一个名为backend_Server的上游服务器组,并启用了Fair负载均衡算法

注意事项

1.兼容性问题:由于ngx_http_upstream_fair_module是一个第三方模块,可能在某些Nginx版本中不兼容,因此在使用前应仔细检查模块的版本与Nginx的兼容性

2.性能问题:Fair算法虽然能动态分配请求,减轻服务器压力,但也需要一定的计算资源来实时监控服务器的响应时间,因此在高并发环境下可能带来额外的性能开销。

3.调试和日志:为了监控Fair算法的工作情况,可以在Nginx配置中增加日志记录,监控每台服务器的响应时间和负载情况。这有助于理解算法的决策过程,并在必要时进行调优。

实际应用中的优势

Fair负载均衡算法非常适合应用在以下场景中:

1.后端服务器性能差异较大:在某些环境中,后端服务器的硬件配置不同,或者运行的服务消耗的资源不同,这导致它们的处理能力存在差异。Fair算法可以根据实际情况动态分配请求,避免性能较差的服务器过载。

2.请求处理时间不均衡:如果不同请求的处理时间差异很大(例如有些请求需要进行复杂的数据库查询或计算),Fair算法能够平衡这些负载,防止某些服务器因为处理耗时请求而被大量占用。

3.高可用性和响应速度优化:在需要提高系统响应速度的场景中,Fair算法能够通过实时监控和调整,减少用户请求的平均响应时间,提高用户体验。


6、url hash(第三方)

按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,要配合缓存命中来使用。同一个资源多次请求,可能会到达不同的服务器上,导致不必要的多次下载,缓存命中率不高,以及一些资源时间的浪费。而使用url_hash,可以使得同一个url(也就是同一个资源请求)会到达同一台服务器,一旦缓存住了资源,再此收到请求,就可以从缓存中读取。

1
2
3
4
5
6
7
8
#动态服务器组
upstream backServer {
hash $request_uri; #实现每个url定向到同一个后端服务器
server localhost:8080; #tomcat 7.0
server localhost:8081; #tomcat 8.0
server localhost:8082; #tomcat 8.5
server localhost:8083; #tomcat 9.0
}

以上便是6种负载均衡策略的实现方式,其中除了轮询和轮询权重外,都是Nginx根据不同的算法实现的。在实际运用中,需要根据不同的场景选择性运用,大都是多种策略结合使用以达到实际需求。


四、软负载与硬负载有哪些区别

  • 硬负载‌:基于专用物理设备(如F5 BIG-IP、A10 Networks),独立于操作系统运行,直接处理网络流量,不消耗服务器资源。‌
  • 软负载‌:通过软件(如Nginx、HAProxy)部署在普通服务器或虚拟机上,依赖宿主机操作系统和硬件性能。‌

性能与稳定性

  1. 硬负载
    • 高性能:专用ASIC芯片加速处理,支持高并发(如百万级请求),延迟低。‌
    • 高稳定性:硬件级故障隔离,适合金融、政务等关键业务。‌‌
  2. 软负载
    • 性能受限:受服务器CPU/内存约束,大规模流量(如并发>1万)易成瓶颈。‌‌
    • 稳定性一般:需额外配置冗余(如Keepalived)防单点故障。‌‌

成本与扩展性

  1. 硬负载
    • 成本高:设备采购价20万–100万元,维护需专业团队。‌‌
    • 扩展性差:新增流量需追加硬件节点,灵活性低。‌‌
  2. 软负载
    • 成本低:开源软件免费,仅需服务器资源。‌‌
    • 扩展性好:支持云环境动态扩缩容(如Kubernetes),快速响应流量变化。‌‌