这一篇我们继续Ngnix系列的第三篇,说一下Nginx的负载均衡,还是先通过简单示例配置体验一下Ngnix的负载均衡,然后我们再从概念上对负载均衡进行说明,各位看到此博客的小伙伴,如有不对的地方请及时通过私信我或者评论此博客的方式指出,以免误人子弟。多谢!
目录
四层/七层负载均衡
Nginx七层负载均衡
七层负载相关指令
upstream
server指令
环境准备
下载Tomcat并配置
启动Tomcat验证
Nginx实现七层负载均衡
测试七层负载均衡
负载均衡策略
轮询(默认)
加权轮询 - weight
根据ip分配方式 - ip_hash
根据url分配方式 - url_hash
最少连接方式 - least_conn
其它方式
其它案例
对特定资源实现负载均衡
Nginx四层负载均衡
四层负载相关指令
stream指令
upstream指令
添加stream模块的支持
配置示例
我们常听说四层/七层负载均衡,他们是什么意思呢?下面是我从网上一篇博客,好像是黑马程序员的教学笔记中截取的一段介绍:
我们先了解一个概念,OSI(open system interconnection),叫开放式系统互联模型,这个是由国际标准化组织ISO指定的一个不基于具体机型、操作系统或公司的网络体系结构。该模型将网络通信的工作分为七层。
所谓四层负载均衡指的是OSI七层模型中的传输层,主要是基于IP+PORT的负载均衡
所谓的七层负载均衡指的是在应用层,主要是基于虚拟的URL或主机IP的负载均衡
区别:
四层负载均衡数据包是在底层就进行了分发,而七层负载均衡数据包则在最顶端进行分发,所以四层负载均衡的效率比七层负载均衡的要高。
四层负载均衡不识别域名,而七层负载均衡识别域名。
本篇记录的是使用Nginx实现的四层/七层负载均衡的实现方式。
该指令是用来定义一组服务器,它们可以是监听不同端口的服务器,服务器可以指定不同的权重,默认为1。
语法 | upstream name {...} |
---|---|
默认值 | — |
位置 | http |
该指令用来指定后端服务器的名称和一些参数,可以使用域名、IP、端口或者unix socket。
语法 | server name [paramerters] |
---|---|
默认值 | — |
位置 | upstream |
我们准备两个Tomcat模拟两个服务,正常情况下访问 http://localhost:8080/ 或者 http://localhost:8081/来获取我们我们需要的数据,通过Ngnix实现负载均衡后,我们访问 http://localhost:8090/ 来从8080和8081来获取数据。
点此下载
下载后解压并复制一份,第一个Tomcat不用该,修改第二个Tomcat下的server.xml配置文件,只修改以下两处即可:
为了演示方便我们修改下Tomcat的首页,\webapps\ROOT目录下的index.jsp文件,增加一个端口号展示:
双击运行bin目录下的startup.bat启动两个Tomcat,启动后我们访问 http://localhost:8080/ 和 http://localhost:8081/ 出现如下页面说明Tomcat正常启动。
Nginx 服务器是介于客户端和服务器之间的中介,通过上一篇博客讲解的反向代理的功能,客户端发送的请求先经过 Nginx ,然后通过 Nginx 将请求根据相应的规则分发到相应的服务器。
我们在Ngnix的配置文件的http块中新增一个server块:
upstream mysvr {
server localhost:8080;
server localhost:8081;
}
server {
listen 8090;
server_name localhost;
location / {
root html;
index index.html index.htm;
proxy_pass http://mysvr;
}
}
重启Ngnix后,我们多次访问 http://localhost:8090/ 发现8090和8091轮流出现,说明请求分发到了两个Tomcat服务。
上面我们多次访问 http://localhost:8090/ 发现8080和8081交替出现,说明我们的请求被交替分发到了两个服务中,这是Ngnix默认的负载均衡策略--轮询,下面看下Nginx的负载均衡策略。
轮询 | 默认方式 |
weight | 权重方式 |
ip_hash | 依据ip分配方式 |
least_conn | 最少连接方式 |
fair(第三方) | 响应时间方式 |
url_hash(第三方) | 依据URL分配方式 |
每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。
有如下参数:
fail_timeout | 设置经过max_fails失败后,服务暂停的时间,默认是10秒。 |
max_fails | 设置在fail_timeout参数设置的时间内最大失败次数,如果在这个时间内,所有针对该服务器的请求都失败了,那么认为该服务器会被认为是停机了, |
fail_time | 服务器会被认为停机的时间长度,默认为10s。 |
backup | 标记该服务器为备用服务器。当主服务器停止时,请求会被发送到它这里。 |
down | 标记服务器永久不可用,那么该代理服务器将不参与负载均衡,该状态一般会对需要停机维护的服务器进行设置。 |
max_conns | max_conns=number:用来设置代理服务器同时活动链接的最大数量,默认为0,表示不限制,使用该配置可以根据后端服务器处理请求的并发量来进行设置,防止后端服务器被压垮。 |
通过weight指定权重,weight和访问比率成正比,用于后端服务器性能不均的情况。如下,我们修改upstream中每个服务的权重,再次测试时会发现明显 8080 端口号出现的次数更多,试验的次数越多越接近我们配置的比例。
upstream mysvr {
server localhost:8080 max_fails=3 fail_timeout=20s weight=5;
server localhost:8081 weight=1;
}
每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。
配置也很简单,只要在upstream 指令块中增加了 ip_hash 指令即可。该指令就是告诉 nginx 服务器,同一个 IP 地址客户端发送的请求都将分发到同一个 Tomcat 服务器进行处理。
upstream backend{
ip_hash;
server 127.0.0.1:9001;
server 127.0.0.1:9002;
server 127.0.0.1:9003;
}
server {
listen 8080;
server_name localhost;
location /{
proxy_pass http://backend;
}
}
按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,要配合缓存命中来使用。同一个资源多次请求,可能会到达不同的服务器上,导致不必要的多次下载,缓存命中率不高,以及一些资源时间的浪费。而使用url_hash,可以使得同一个url(也就是同一个资源请求)会到达同一台服务器,一旦缓存住了资源,再此收到请求,就可以从缓存中读取。
upstream backend{
hash &request_uri;
server 127.0.0.1:9001;
server 127.0.0.1:9002;
server 127.0.0.1:9003;
}
server {
listen 8080;
server_name localhost;
location /{
proxy_pass http://backend;
}
}
把请求转发给连接数较少的后端服务器。轮询算法是把请求平均的转发给各个后端,使它们的负载大致相同;但是,有些请求占用的时间很长,会导致其所在的后端负载较高。这种情况下,least_conn这种方式就可以达到更好的负载均衡效果。
upstream backend{
least_conn;
server 127.0.0.1:9001;
server 127.0.0.1:9002;
server 127.0.0.1:9003;
}
server {
listen 8080;
server_name localhost;
location /{
proxy_pass http://backend;
}
}
另外还有其它第三方的负载均衡策略,第三方的负载均衡策略的实现需要安装第三方插件,比如farl方式,需要安装nginx-upstream-fair模块,感兴趣的自己看下。
如下,我们访问 localhost:8084/video/ 会将请求负载到9001和9002服务器上。
upstream videobackend{
server 192.168.200.146:9001;
server 192.168.200.146:9002;
}
upstream filebackend{
server 192.168.200.146:9003;
server 192.168.200.146:9004;
}
server {
listen 8084;
server_name localhost;
location /video/ {
proxy_pass http://videobackend;
}
location /file/ {
proxy_pass http://filebackend;
}
}
该指令提供在其中指定流服务器指令的配置文件上下文。和http指令同级。
语法 | stream { ... } |
---|---|
默认值 | — |
位置 | main |
该指令和http的upstream指令是类似的。
注意:在nginx1.9.0之后才有的stream模块,如果版本过低,需要先升级版本。
我安装的已经是1.20.2了可以直接添加stream模块即可,如下:
./configure --with-http_ssl_module --with-stream
然后安装即可:
make && make install
最后,使用使用 nginx -V 命令命令查看是否天剑ssl和stream模块成功。
老版本升级步骤如下:
1、将原有/usr/local/nginx/sbin/nginx和conf中的nginx.conf进行备份。
2、进入nginx的安装源码目录,进行配置指定对应模块。
cd /usr/local/nginx-1.20.1
./configure --with-http_ssl_module --with-stream
在进行配置前 先使用 nginx -V 命令查看原有nginx是否有已经配置的信息,有的话先复制出来,我之前安装了 --with-http_ssl_module模块,控制台会展示:
configure arguments: --with-http_ssl_module
此时需要将configure arguments后的参数复制带上,如下:
./configure --with-http_ssl_module --with-stream
3、通过make模板进行编译。
4、make之后将objs目录下的nginx移动到/usr/local/nginx/sbin下。
cp /objs/nginx /usr/local/nginx/sbin
5、在源码目录下执行 make upgrade。
6、检查是否安装成功,还是使用nginx -V命令,如果安装成功会看到 configure arguments: 后会有--with-http_ssl_module,如下:
如下,像上面测试一样,准备三个tomcat启动,配置了一个stream块,访问 http://118.195.59.52:8081 会负载到8090 8091两台服务器。
stream {
upstream backend1 {
server 118.195.59.52:8090;
server 118.195.59.52:8091;
}
upstream backend2 {
server 118.195.59.52:8092;
}
server {
listen 8081;
proxy_pass backend1;
}
server {
listen 8082;
proxy_pass backend2;
}
}