TCP 的 负载均衡
 
这个片段描述了如何通过nginx plus进行负载均衡
 
在版本5中,nginx plus 能够代理和负载均衡通过TCP路径,TCP对于一些流行应用和服务是一个协议:LDAP、MYSQL、RTMP
 
stream 模块
 
TCP 负载均衡被nginx的三个模块所实现,而且这些模块被嵌入在nginx plus中。
它们定义的命令是在stream配置块中:
先决条件
  • nginx plus 版本5(具备基本功能)或者版本6(在这个文章有描述的功能)
  • 一个应用、数据库、服务进行通信都是通过TCP的方式
  • 负载均衡服务中的每个服务都需要运行一个实例
配置TCP负载均衡
 
负载均衡涉及到了高效的分发网络到后台服务,要配置负载均衡,需要执行下面的技术:
  1. 创建最高级别的stream(与http同一级别)上下文在nginx plus配置当中。
  2. 定义一个upstream组,由多个服务组成达到负载均衡
  3. 定义一个服务用来监听TCP连接,并且把他们代理到一个upstream组中
  4. 配置负载均衡的方法和参数为每个server;配置些如:连接数、权重、等等
创建一个upstream组
 
首先创建一个server组,用来作为TCP负载均衡组。定义一个upstream块在stream上下文中
在这个块里面添加由server命令定义的server,指定他的IP地址和主机名(能够被解析成多地址的主机名),和端口号。注意:你不能为每个server定义协议,因为这个stream命令建立TCP作为整个
server的协议了。下面的例子是建立一个被称之为stream_backend组,两个监听12345端口的server
,一个监听12346端口。
 
stream {
     upstream stream_backend {
          server backend1.example.com:12345 weight=5;
          server backend2.example.com:12345;
          server backend3.example.com:12346;
     }
}
 
下面的片段中,你定义每个server为单独的组中。然后你能自定义upstream组的配置,而这些
组是通过负载均衡的算法来进行分组的,或者是能健康的管理。. See Choosing a Load Balancing Method和后续的片段.
 
TCP的代理通信
 
配置反向代理使nginx plus能够把TCP请求从一个客户端转发到负载均衡组中。在每个server配置块中
通过每个虚拟server的server的配置信息和在每个server中定义的监听端口的配置信息和proxy_passs
命令把TCP通信发送到哪个server中去。
 
stream {
     server {
          listen 12345;
          proxy_pass stream_backend;
     }
}
 
一个另类的方式是代理TCP通信到单一的server中而不是server组中。
假如你的server的唯一标识是通过主机,而且你的主机名是可以解析成多个IP地址的话,然而nginx的负载均衡通信通过使用round-robin算法得到的IP方式。在这种情况下,你必须还要附加端口号来标识到底哪个server来处理的。
 
stream {
     server {
          listen 12345;
          proxy_pass backend4.example.com:12345;
     }
}
 
改变负载均衡的方法
 
默认nginx plus是通过轮询算法来进行负载均衡的通信的。引导这个请求循环的到配置在upstream组中server端口上去。
因为他是默认的方法,这里没有轮询命令,只是简单的创建一个upstream配置组在这儿stream山下文中,而且在其中添加server。
 
upstream backend {
     server backnd1.example.com:12345 weight;
     server backedn2.example.com:12345;
     server backend3.example.com:12345;
}
 
配置不同的负载均衡的算法,囊括在upstream配置块中。
  1. least-connected :对于每个请求,nginx plus选择当前连接数最少的server来处理
upstream stream_backend {
     least_conn;
     
     server backend1.example.com:12345 weight=5;
     server backend2.example.com:12345;
     server backend3.example.com:12346;
}
 
2. least time :对于每个链接,nginx pluns 通过几点来选择server的:
  • 最底平均延时:通过包含在least_time命令中指定的参数计算出来的:
  1. connect:连接到一个server所花的时间
  2. first_byte:接收到第一个字节的时间
  3. last_byte:全部接收完了的时间
  • 最少活跃的连接数
 
upstream stream_backend {
     least_time first_byte;
 
     server backend1.exmaple.com:12345 weight=5;
     server backend2.example.com:12345;
     server backend3.example.com:12346;
}
 
3. 普通的hash算法:nginx plus选择这个server是通过user_defined 关键字,就是IP地址:$remote_addr;
 
upstream stream_backend {
     hash $remote_addr consistent;
     
     server backend1.example.com:12345 weight=5;
server backend2.example.com:12345;
server backend3.example.com:12346;
}
这个可选的consistent参数应用这个一致性hash算法,这种方法能减少使由于server添加或者删除导致的关键字映射到其他服务器上的可能性。
 
配置session的持久化
 
配置session的持久化使用hash负载均衡的方式在前面已经描述了。因为hash函数是建立在客户端的IP地址上的,所以TCP请求从一个到同样一个server是非常可能的,除非这个server不可用了
 
限制连接数
 
可以设置nginx plus与server所建立的连接数:server max_conns=?
upstream stream_backend {
     server backend1.example.com:12345 weight=5;
     server backend2.example.com:12345;
     server backend3.example.com:12346 max_conns=4;
}
 
不好的健康监测
     假如连接一个server超市了或者导致一个错误,nginx plus标识这个server是无效的和阻止请求到那个server上去,在一段时间内。下面的参数是用来判断哪些server才算是不可达的:
  • fail_timeout :在这个时间段中进行了多少次连接的尝试失败了,那么就认为是不可达了并标记不可达
  • max_fails:和上面是对应上的。
默认是在10秒钟进行1次尝试。在10秒进行至少一次尝试是失败的,那么nginx则认为这个server是不可达的
下面的例子中要求是:30s进行2次尝试失败认为server不可达
upstream stream_backend {
     server backend1.example.com:12345 weight=5;
     server backend2.example.com:12345 max_fails=2 fail_timout=30; //当个server的不健康的监测
     server backend3.example.com:12346 max_conns=4;
}
 
好的健康监测
 
当你进行健康监测的时,nginx plus平凡的进行TCPupstream的server的测试通过响应为了避免失败。
健康监测可以配置成监测失败类型的范围。
 
how it works?
nginx plus 发送一个健康监测请求到每个TCP upstream server中去,监测响应是否满足这个指定的条件,假如一个连接不能连接到某个server当中去,这个健康监测就会失败,这个server将会被考虑成不监控了。nginx plus就不会代理客户端连接到不健康的server中去,假如几个server被监测为健康的,那么相反的server就是不健康的了
 
先决条件:
  • 你已经定义了一组server在stream上下文中:例如:
stream {
     upstream stream_backend {
          server backend1.example.com:12345; 
          server backend2.example.com:12345; 
          server backend3.example.com:12345;
     }
}
 
  • 你也做好了定义一个TCP连接的代理server
server {
     listen 12345;
     proxy_pass stream_backend;
}
 
基本的配置
  1. 添加一个zone命令在upstream中,这个zone定义的大小是用来给worker processes存放connections和counters用的

    stream {
         upstream stream_backend {
              zone stream_backend 64k;
              server backend1.exmaple.com:12345;
                   ..........
         }
    }

  2. 添加 health_check and health_check_timeout命令到代理的server中去、
    server {
        listen 12345;
        proxy_pass strean_backend;
        health_check;
        health_check_timeout 5s;
    }

    这个health_check命令将会激活这个健康监测功能,当又health_check_timeout 将会覆盖掉这个proxy_timeout的值,
    作为健康监测超时时间应该是显著缩短。

fine-tuning 健康监测
 
默认,nginx plus试着再每5s中连接每个server在upstream server组中。假如连接不能够被建立,nginx plus认为这个健康监测失败,标识他为不健康。停止连接该server。
改变默认的行为,包括的参数如下:
  • interval :多少秒会发送健康请求
  • passses : 多少连续的响应才算被考虑为健康的
  • fails :多少次连续的失败响应才考虑为不健康的
server {
     listen 12345;
     proxy_pass stream_backend;
     health_check insterval=10 passes=2 fails=3; //整体server检测
}
在这个例子中这个时间周期变成了10s;三次连续无响应被考虑为不健康,假如连续两次检测正常可能为server正常
 
fine-tuning health check with the macth configuration block
 
定义一些测试的种类去验证server响应从而达到server是否健康,定义这些种类在一个match的配置块中
这个match在stream上下文中;
使用下面的参数在match块中是需要的目的为了health_check而定制的条件
  • send :发送到server的字符创
  • expect :返回的数据必须匹配这个正则表达式
这些参数可以随意的组合,但是不会超过一个send或者一个expect参数同一时间内,下面是这两个参数的搭配:
  • 既没有send也没有expect参数被指定。连接server的能力是测试的
  • 指定了expect,然后server被期待无条件的发送一条数据过来
    match pop3 {
        expect ~*"\+OK";
    }
  • send被指定,然后期待连接将会成功的建立,指定的字符串会被发送到server端
    match pop_quit {
       send QUIT;
    }
  • 假如两个都有,那么这个发送参数返回的值必须匹配这个expect指定的正则
stream {
     upstream stream_backend {
          zone upstream_backend 64k;
          server backend1.example.com:12345;
     }
     match http {
          send "GET / HTTP/1.0\r\nHost:localhost\r\n\r\n"
          expect ~*"200 OK";
     }
     
     server {
          listen 12345;
          health_check match=http;
          proxy_pass stream_backend;     
     }
 
}
 
运行时的重新配置
 
upstream 服务组能够非常容易的重配在运行的时候通过一个简单的http接口,使用这个接口,你将会能够
看到所有的服务,某个服务的详细信息,或者对server的增删。
为了能够在运行时重配,你需要如下条件:
 
授予访问upstream_conf handler -a 特殊的handler权限;handler能够检查和重配upstream组在nginx plus中。作如上的操作需要在http 快中,使用upstream_conf命令 在一个分开的location中
对于访问这个location需要限定。
http {
     server {
          location /upstream_conf {
               upstream_conf;
               
               allow 127.0.0.1; #permit access from localhost
               deny all;#deny; access from everywhere else
          }
     }
}
 
在这个stream块中,指定zone对于这个server组来说需要;这个命令将会创建一个zone大小的在共享内存当中,在里面保存了server组的配置;这样所有的workprocesses就能够共享同一个配置了。
 
stream {
     ...
     #Configuration of an upstream server group
     upstream appservers {
          zone appservers 64k;
          
          server appserv1.example.com:12345 weight=5;
          server appserv2.example.com:12345 fail_timeout=5s;
          
          server backup1.example.com:12345 backup;
          server backup2.example.com:12345 backup;
     }
     
     server {
          #server that proxies connections to the upstream
          proxy_pass appservers;
          lealth_check;
     }
}
 
http {
...
     server {
          #location for configuration requests
          
          location /upstream_conf {
               upstream_conf;
               allow 127.0.0.1;
               deny all;
          }
     }     
}
 
这里,想访问这个location只有是本地的IP才可以,而其他的IP都被屏蔽了。想发送一个配置命令到nginx中,发送一个http请求可以带很多配置信息。这个请求应该应该有一个适合的uri进入到包含了upstream_conf的location中,这个请求应该包括了设置server组的upstream的参数。
 
例如:查看所有的备份server,对于这server来说就是:http://127.0.0.1/upstream_conf?stream=&upstream=appservers&backp=
 
增加一个新的server到组中,发送一个请求携带了add和server参数:http://127.0.0.1/upstream_conf?stream=&add=&upstream=appservers&server=appserv3.example.com:12345&weight=2&max_fails=3
 
移除一个server,发送一个请求携带remove命令和server唯一标识的参数ID
 
去修改一个特定的server参数,发送一个请求携带ID和参数信息
 
 
 
 
tcp load balancing 配置例子
 
这个配置例子是TCP负载均衡的例子在nginx plus中的
 
stream {
     
     upstream stream_backend {
          least_conn;
          server backend1.example.com:12345 weight=5;
          server backend2.example.com:12345 max_fail=2 fail_timeout=30s;
          server backend3.example.com:12346 max_conns =3;
     }     
     
     server {
          listen 12345;
          proxy_connect_timeout 1s;
          proxy_timeout 3s;
          proxypass stream_backend ;     
     }
     
     server {
          listen 12346;
          proxy_pass backend4.example.com:12346;
     }
}
 
 
在这个例子中,有两个servers 他们被定义在server块中。所有的TCP代理相关的函数都被定义在stream块中像http块一样对待http请求的处理。
 
这第一个server监听12345端口而且代理所有的TCP连接到这个被命令为backend组中server。注意这个proxy_pass命令定义
这个stream模块的上下文必须不包含协议。这两个可选的timeout参数被指定如下含义:proxy_connect_timeout设置建立一个连接与某个server的请求的超时时间,而proxy_time是代理已经建立之后的超时时间。
 
这个backend组由三个运行同样内容的,每个server命令后缀一个固定的端口号。连接被分配到每个server中去,而这种分配方式是:最少连接数。
 
这第二个虚拟server监听在12346端口号上,并且代理TCP连接到backend4逻辑server上,这个server或许被解析到一个serverIP上,而且这个地址将会做轮询的方式负载均衡。

nginx如何做到TCP的负载均衡的更多相关文章

  1. Nginx基于TCP的负载均衡的配置例子

    原文:https://blog.csdn.net/bigtree_3721/article/details/72833955 nginx-1.9.0 已发布,该版本增加了 stream 模块用于一般的 ...

  2. 简单测试nginx1.90做TCP协议负载均衡的功能

    最近工作中需要做TCP层面的负载均衡,以前网站用的反向代理nginx只支持应用层的负载均衡,对于TCP协议是无能为力的,需要使用LVS(linux虚拟服务器). LVS的特点是高性能和极复杂的配置.对 ...

  3. 图文解说:Nginx+tomcat配置集群负载均衡

    图文解说:Nginx+tomcat配置集群负载均衡 博客分类: appserver nginxTomcatUbuntuLinux网络应用  作者:niumd Blog:http://ari.iteye ...

  4. Nginx的反相代理, 负载均衡

    转自 http://freeloda.blog.51cto.com/2033581/1288553 大纲 一.前言 二.环境准备 三.安装与配置Nginx 四.Nginx之反向代理 五.Nginx之负 ...

  5. 搭建 Keepalived + Nginx + Tomcat 的高可用负载均衡架构

    1 概述 初期的互联网企业由于业务量较小,所以一般单机部署,实现单点访问即可满足业务的需求,这也是最简单的部署方式,但是随着业务的不断扩大,系统的访问量逐渐的上升,单机部署的模式已无法承载现有的业务量 ...

  6. Keepalived + Nginx + Tomcat 的高可用负载均衡架构搭建

    Keepalived + Nginx + Tomcat 的高可用负载均衡架构搭建 Nginx 是一个高性能的 HTTP反向代理服务器 Keepalived 是一个基于VRRP协议来实现的LVS服务高可 ...

  7. Nginx+proxy实现简单的负载均衡

    环境说明:操作系统centos6.6 64位web操纵系统是:web1=192.168.10.10(LAMP) web2=192.168.10.11(LNMP),这里只是测试nginx实现负载均衡效果 ...

  8. 搭建Keepalived + Nginx + Tomcat的高可用负载均衡架构

    1 概述 初期的互联网企业由于业务量较小,所以一般单机部署,实现单点访问即可满足业务的需求,这也是最简单的部署方式,但是随着业务的不断扩大,系统的访问量逐渐的上升,单机部署的模式已无法承载现有的业务量 ...

  9. nginx,lvs,haproxy负载均衡对比

    Nginx/LVS/HAProxy是目前使用最广泛的三种负载均衡软件,一般对负载均衡的使用是随着网站规模的提升根据不同的阶段来使用不同的技术,具体的应用需求还得具体分析. 如果是中小型的Web应用,比 ...

随机推荐

  1. java 空语句

    输入的字符不是回车就重新输入: import java.io.IOException; public class HelloWorld { public static void main(String ...

  2. 解决js跨域

    这里说的js跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同域的框架中(iframe)的数据.只要协议.域名.端口有任何一个不同,都被 ...

  3. springMVC入门-05

    接着上一讲,介绍如何查询单个数据,此处介绍show()方法的实现.显示单条数据需要使用Users对象中的一个字段作为入参来进行对象查询,将查询出来的数据放在Model中,并且将model中的user对 ...

  4. SQL Server FOR XML PATH 和 STUFF函数的用法

    FOR XML PATH ,其实它就是将查询结果集以XML形式展现,将多行的结果,展示在同一行. 下面我们来写一个例子: 假设我们有个工作流程表: CREATE TABLE [dbo].[Workfl ...

  5. 进程间协作---wait,notify,notifyAll

    转自牛客网的一篇评论,解释的十分详细 在 Java 中,可以通过配合调用 Object 对象的 wait() 方法和 notify()方法或 notifyAll() 方法来实现线程间的通信.在线程中调 ...

  6. [swift] Async

    Async https://github.com/duemunk/Async Syntactic sugar in Swift for asynchronous dispatches in Grand ...

  7. LinkedHashSet 元素唯一,存储取出有序

      package cn.itcast_04; import java.util.LinkedHashSet; /* * LinkedHashSet:底层数据结构由哈希表和链表组成. * 哈希表保证元 ...

  8. 教你用 jVectorMap 制作属于自己的旅行足迹

    jVectorMap JVectorMap 是一个优秀的.兼容性强的 jQuery 地图插件. 它可以工作在包括 IE6 在内的各款浏览器中,矢量图输出,除官方提供各国地图数据外,用户可以使用数据转换 ...

  9. echo,die(),print(),print_r(),var_dump()的区别

    echo是PHP语句, print和print_r是函数,语句没有返回值,函数可以有返回值(即便没有用)  print()   只能打印出简单类型变量的值(如int,string)  例子 输出 3 ...

  10. nginx alias

    A path to the file is constructed by merely adding a URI to the value of the root directive. If a UR ...