微服务系列文章之 Nginx负载均衡

1、七层负载均衡

1、说明

Nginx要实现七层负载均衡需要用到proxy_pass代理模块配置。Nginx默认安装支持这个模块,我们不需要再做任何处理。Nginx的负载均衡是在Nginx的反向代理基础上把用户的请求根据指定的算法分发到一组【upstream虚拟服务池】。

2、要用到的指令

2.1、upstream指令

该指令用来指定后端服务器的名称和一些参数,可以使用域名、IP、端口或者unix socket。

语法 upstream name
默认值
位置 http

2.2、server指令

该指令是用来定义一组服务器,它们可以是监听不同端口的服务器,并且也可以是同时监听TCP和Unix socket的服务器。服务器可以指定不同的权重,默认为1。

语法 server name [paramerters]
默认值
位置 upstream

1.3、实现流程

图。

1.4、配置示例

配置成功后,访问 http://127.0.0.1 请求会一次访问三个服务。

1.4.1、服务一

复制代码
server {
    listen       8081;
    server_name  127.0.0.1;

    location / {
        default_type text/plain;
        return 200 "127.0.0.1 <=> 8081";
    }
}

1.4.2、服务二

复制代码
server {
    listen       8082;
    server_name  127.0.0.1;

    location / {
        default_type text/plain;
        return 200 "127.0.0.1 <=> 8082";
    }
}

1.4.3、服务三

复制代码
server {
    listen       8083;
    server_name  127.0.0.1;

    location / {
        default_type text/plain;
        return 200 "127.0.0.1 <=> 8083";
    }
}

1.4.4、均衡配置

复制代码
upstream backend {
    server 127.0.0.1:8081;
    server 127.0.0.1:8082;
    server 127.0.0.1:8083;
}

server {
    listen       80;
    server_name  127.0.0.1;

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

1.5、负载均衡状态

代理服务器在负责均衡调度中的状态有以下几个

状态 概述
down 当前的server暂时不参与负载均衡
backup 预留的备份服务器
max_fails 允许请求失败的次数
fail_timeout 经过max_fails失败后, 服务暂停时间
max_conns 限制最大的接收连接数
1.5.1、down

将该服务器标记为永久不可用,那么该代理服务器将不参与负载均衡。该状态一般会对需要停机维护的服务器进行设置。

复制代码
upstream backend{
  server 192.168.200.146:9001 down;
  server 192.168.200.146:9002;
  server 192.168.200.146:9003;
}

server {
  listen 8083;
  server_name localhost;

  location /{
    proxy_pass http://backend;
  }
}
1.5.2、backup

将该服务器标记为备份服务器,当主服务器不可用时,将用来传递请求。

复制代码
upstream backend{
  server 192.168.200.146:9001 down;
  server 192.168.200.146:9002 backup;
  server 192.168.200.146:9003;
}

server {
  listen 8083;
  server_name localhost;

  location / {
    proxy_pass  http://backend;
  }
}
1.5.3、max_conns

max_conns=number:用来设置代理服务器同时活动链接的最大数量,默认为0,表示不限制,使用该配置可以根据后端服务器处理请求的并发量来进行设置,防止后端服务器被压垮。

1.5.4、max_failsfail_timeout

max_fails=number:设置允许请求代理服务器失败的次数,默认为1。

fail_timeout=time:设置经过max_fails失败后,服务暂停的时间,默认是10秒。

复制代码
upstream backend{
  server 192.168.200.133:9001 down;
  server 192.168.200.133:9002 backup;
  server 192.168.200.133:9003 max_fails=3 fail_timeout=15;
}

server {
  listen 8083;
  server_name localhost;

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

1.6、 负载均衡策略

Nginx的upstream支持如下六种方式的分配算法,分别是:

算法名称 说明
轮询 默认方式
weight 权重方式
ip_hash 依据IP分配方式
least_conn 依据最少连接方式
url_hash 依据URL分配方式
fair 依据响应时间方式

1.6.1、 轮询

轮询是upstream模块负载均衡默认的策略。每个请求会按时间顺序逐个分配到不同的后端服务器。轮询不需要额外的配置。

复制代码
upstream backend{
  server 192.168.200.146:9001 weight=1;
  server 192.168.200.146:9002;
  server 192.168.200.146:9003;
}

server {
  listen 8083;
  server_name localhost;

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

1.6.2、 weight加权[加权轮询]

weight=number:用来设置服务器的权重,默认为1,权重数据越大,被分配到请求的几率越大;该权重值,主要是针对实际工作环境中不同的后端服务器硬件配置进行调整的,所有此策略比较适合服务器的硬件配置差别比较大的情况。

复制代码
upstream backend{
  server 192.168.200.146:9001 weight=10;
  server 192.168.200.146:9002 weight=5;
  server 192.168.200.146:9003 weight=3;
}

server {
  listen 8083;
  server_name localhost;

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

1.6.3、 ip_hash

当对后端的多台动态应用服务器做负载均衡时,ip_hash指令能够将某个客户端IP的请求通过哈希算法定位到同一台后端服务器上。这样,当来自某一个IP的用户在后端Web服务器A上登录后,在访问该站点的其他URL,能保证其访问的还是后端web服务器A。使用ip_hash指令无法保证后端服务器的负载均衡,可能导致有些后端服务器接收到的请求多,有些后端服务器接收的请求少,而且设置后端服务器权重等方法将不起作用。

语法 ip_hash;
默认值 ---
位置 upstream
复制代码
upstream backend{
  ip_hash;
  server 192.168.200.146:9001;
  server 192.168.200.146:9002;
  server 192.168.200.146:9003;
}

server {
  listen 8083;
  server_name localhost;

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

1.6.4、 least_conn

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

此策略适合请求处理时间长短不一造成服务器过载的情况。

复制代码
upstream backend{
  least_conn;
  server 192.168.200.146:9001;
  server 192.168.200.146:9002;
  server 192.168.200.146:9003;
}

server {
  listen 8083;
  server_name localhost;

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

1.6.5、 url_hash

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

复制代码
upstream backend{
  hash &request_uri;
  server 192.168.200.146:9001;
  server 192.168.200.146:9002;
  server 192.168.200.146:9003;
}
server {
  listen 8083;
  server_name localhost;
  location /{
    proxy_pass http://backend;
  }
}

1.6.5、 fair

fair采用的不是内建负载均衡使用的轮换的均衡算法,而是可以根据页面大小、加载时间长短智能的进行负载均衡。那么如何使用第三方模块的fair负载均衡策略。

复制代码
upstream backend{
  fair;
  server 192.168.200.146:9001;
  server 192.168.200.146:9002;
  server 192.168.200.146:9003;
}

server {
  listen 8083;
  server_name localhost;

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

但是如何直接使用会报错,因为fair属于第三方模块实现的负载均衡。需要添加nginx-upstream-fair,如何添加对应的模块:

1.6.5.1、下载nginx-upstream-fair模块
复制代码
下载地址为:
  https://github.com/gnosek/nginx-upstream-fair
1.6.5.2、将下载的文件上传到服务器并进行解压缩
复制代码
unzip nginx-upstream-fair-master.zip
1.6.5.3、重命名资源
复制代码
mv nginx-upstream-fair-master fair
1.6.5.4、使用./configure命令将资源添加到Nginx模块中
复制代码
./configure --add-module=/root/fair
1.6.5.5、编译
复制代码
make

编译可能会出现如下错误,ngx_http_upstream_srv_conf_t结构中缺少default_port。可以在Nginx的源码中 src/http/ngx_http_upstream.h,找到ngx_http_upstream_srv_conf_s,在模块中添加添加default_port属性

复制代码
int_por_t    port;
in_port_t    default_port;
ngx_unit_t   no_port;

然后再进行make.

1.6.5.6、更新Nginx
1.6.5.6.1、将sbin目录下的nginx进行备份
复制代码
mv /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginxold
1.6.5.6.2、将安装目录下的objs中的nginx拷贝到sbin目录
复制代码
cp objs/nginx /usr/local/nginx/sbin
1.6.5.6.3、更新Nginx
复制代码
make upgrade

2、四层负载均衡

四层负载均衡数据包是在底层就进行了分发,而七层负载均衡数据包则在最顶端进行分发,所以四层负载均衡的效率比七层负载均衡的要高。四层负载均衡不识别域名,而七层负载均衡识别域名。

Nginx在1.9之后,增加了一个stream模块,用来实现四层协议的转发、代理、负载均衡等。stream模块的用法跟http的用法类似,允许我们配置一组TCP或者UDP等协议的监听,然后通过proxy_pass来转发我们的请求,通过upstream添加多个后端服务,实现负载均衡。

四层协议负载均衡的实现,一般都会用到LVS、HAProxy、F5等,要么很贵要么配置很麻烦,而Nginx的配置相对来说更简单,更能快速完成工作。

2.1、添加stream模块的支持

Nginx默认是没有编译这个模块的,需要使用到stream 模块,那么需要在编译的时候加上*--with-stream* 。

完成添加--with-stream的实现步骤如下:

  • 将原有/usr/local/nginx/sbin/nginx进行备份
  • 拷贝nginx之前的配置信息
  • 在nginx的安装源码进行配置指定对应模块 ./configure --with-stream
  • 通过make模板进行编译
  • 将objs下面的nginx移动到/usr/local/nginx/sbin下
  • 在源码目录下执行 make upgrade进行升级,这个可以实现不停机添加新模块的功能

2.2、配置示例

复制代码
stream {
  upstream redisbackend {
    server 192.168.200.146:6379;
    server 192.168.200.146:6378;
  }

  upstream tomcatbackend {
      server 192.168.200.146:8080;
      server 192.168.200.146:8081;
  }

  server {
    listen  81;
    proxy_pass redisbackend;
  }

  server {
    listen  82;
    proxy_pass  tomcatbackend;
  }
}

案例 -Tomcat集群

网络配置

IP PORT DESC
10.108.10.100 80 Nginx Web Server
10.108.10.101 8080 Tomcat App Server①
10.108.10.102 8080 Tomcat App Server②
10.108.10.103 8080 Tomcat App Server③
复制代码
# 负载均衡配置
upstream server-api {
  server 10.108.10.101:8080;
  server 10.108.10.102:8080;
  server 10.108.10.103:8080;
}

server {
  listen  80;
  server_name  localhost;

  # 静态资源配置
  location / {
    root  /www/wwwroot/projects/ui;
    try_files  $uri $uri/ /index.html;
    index  index.html index.htm;
  }

  # 动态资源配置
  location /prod-api/ {
    proxy_set_header  Host $http_host;
    proxy_set_header  X-Real-IP $remote_addr;
    proxy_set_header  REMOTE-HOST $remote_addr;
    proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto  $scheme;
    proxy_pass  http://server-api/;
  }
}

在101、102、103上分别启动Tomcat,此时访问http://10.108.10.100/index.html,刷新会轮训访问三台Tomcat服务。 至此,解决了Tomcat的高可用性,一台服务器宕机,还有其他两台对外提供服务,同时也可以实现后台服务器的不间断更新。

相关推荐
编程一生2 小时前
微服务相比传统服务的优势
微服务·云原生·架构
亿坊电商2 小时前
PHP框架在微服务迁移中能发挥什么作用?
开发语言·微服务·php
prinrf('千寻)5 小时前
nacos设置权重进行负载均衡不生效
运维·负载均衡
Angindem8 小时前
SpringClound 微服务分布式Nacos学习笔记
分布式·学习·微服务
Sonetto19999 小时前
Nginx 反向代理,啥是“反向代理“啊,为啥叫“反向“代理?而不叫“正向”代理?它能干哈?
运维·前端·nginx
细心的莽夫17 小时前
SpringCloud 微服务复习笔记
java·spring boot·笔记·后端·spring·spring cloud·微服务
hoho不爱喝酒21 小时前
微服务Nacos组件的介绍、安装、使用
微服务·云原生·架构
RECRUITGUY1 天前
用交换机连接两台电脑,电脑A读取/写电脑B的数据
服务器·网络·负载均衡