• Web集群


    Web集群是由多台Web服务器主机相互联结而形成的一种服务器体系结构,包括WEB负载均衡和HTTP Session失效转移。Web集群的一般结构主要由负载均衡器和后端多个Web节点组成,负载均衡器可以是软件也可以是硬件,Web节点可以是同构或异构的服务器。用户访问请求首先进入负载均衡器,由它根据负载均衡策略将请求分配给后端某个Web应用节点。对使用软件的负载均衡,我们可以使用lvs搭建Web服务器集群,也可以使用Apache+Tomcat或Nginx+Tomcat集群方案。

    在Apache+Tomcat或Nginx+Tomcat集群方案中,负责负载均衡主要Apache或Nginx负责,而TOMCAT主要负责SESSION复制和SESSION共享。Nginx ("engine x") 是一个高性能的HTTP和反向代理服务器,占有内存少,并发能力强,网上有文章称使用Nginx作负载均衡服务能力远超过Apache,同样的情况下,推荐使用Nginx+Tomcat方案。

    关于Apache+Tomcat或Nginx+Tomcat集群方案,目前网络上相关的文章也非常多了。具体可以google之。

    Nginx采用反向代理将请求均匀转发给多台服务器,从而达到负载均衡的目的。使用反向代理的好处是,可以将负载均衡和代理服务器的高速缓存技术结合在一起。但同时,针对每一次代理,反向代理服务器必须维护一个对外的连接和一个对内的连接,虽然反向代理可能应用优化的负载均衡策略,使每次访问路由到最空闲的Web服务器,但是随着并发连接数量的增加,代理服务器负载也会变得越来越大,并可能成为服务的瓶颈。

    负载均衡的算法一般有:轮循(Round-Robin)、权重轮循均衡(Weighted Round Robin)、最小连接数(Least Connections First)、快速响应优先(Faster Response Precedence)、随机均衡(Random)、处理能力均衡和DNS响应均衡(Flash DNS)等。而Nginx做负载均衡有以下几种策略:

    1、轮询

    后端Web服务器形成一个环队列,对每个到达的请求按照时间顺序顺次分配给这些服务器。前端调度器和后端服务器之间采用心跳进行状态检查,如果发现后端服务器宕机,则将其删除。

    轮询的特点是简洁,但缺点是无法进行最优化调度,有可能有的请求需要耗时较久,这样会带来一定的不平衡。

    2、基于ip的hash分配策略(ip_hash)

    一种非轮询式方式,对于每个到达的请求,直接通过其请求IP进行哈希的映射,通过映射结果获得那一台后端服务器要处理这个请求,这种方式有一个明显的好处是能够保证session的唯一性,即这样每个访客固定访问一个后端服务器,可以解决session的问题。

    3、基于URL的哈希方式(url_hash)

    这种方式与IP的哈希方式类似,是对客户机请求的URL进行哈希操作,这样的方式有一个明显的好处是,使每个url定向到同一个后端服务器,能够便于内容缓存的实现(后端服务器为缓存时比较有效),对于经常性的资源访问,采用这样的方式会获得非常好的质量。如果将$request_uri换成$remote_addr就可以实现基于ip地址的策略。

    4、基于服务响应方式fair

    按后端服务器的响应时间来分配请求,响应时间短的优先分配。这种方式能够自动根据当前的后端实际负载来优化。

    当浏览器访问有状态的WEB应用程序,这个应用程序可能在内存创建了会话对象用于保存信息以供后面的请求使用,同时,发送给浏览器一个唯一的HTTP Session ID用于标识这个会话对象,浏览器将这个ID保存Cookie中,并当它下次再请求同一WEB应用程序的页面时,会将Cookie发还给服务器。为了支持会话失效转移,WEB服务器将在一定的时候把会话对象备份到其他地方以防止服务器失效后丢失会话信息。负载均衡器检测到这个失败,并将后续的请求分发到装有相同应用程序的服务器实例中,由于会话对象已经备份到其他地方了,这个新的服务器实例可以恢复会话正确地处理请求。

    HTTP Session失效转移将涉及到一些问题:全局HTTP Session ID;会话状态的备份以及备份的频率和粒度。

    会话状态备份可以采用数据库备份或内存复制。内存复制方式是目前大多数J2EE服务器采用的方式,内存复制又分为多服务器复制(将会话数据复制到集群中的所有结点)、对等服务器复制。对等服务器复制最具可扩展性,也是大多数J2EE服务器采用的方案。

    备份频率可以按Web请求或按固定时间间隔来备份。备份频率要考虑备份动作发生太频繁,性能将急剧下降;如果两次备份间隔太长,那么在这间隔之间服务器失效后,很多会话信息将会丢失。

    备份粒度常见的策略分为:整个会话、修改过的会话和修改过的属性。

    Web集群中,Tomcat主要解决SESSION共享问题,除了采用Tomcat本身的Session失效转移策略外,也可以利用memcached来保存session,这样多台TOMCAT服务器就可共享SESSION了。

    Cluster

    Tomcat集群的主元素,在Cluster元素里面配置了集群的详细信息。目前Tomcat仅提供了org.apache.catalina.ha.tcp.SimpleTcpCluste作为唯一的实现类。

    <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster" channelSendOptions="8">

    下面是Cluster详细属性:

    属性

    描述

    className

    Cluste的实现类,当前org.apache.catalina.ha.tcp.SimpleTcpCluste作为唯一的实现类。

    channelSendOptions

    Session发送方式,默认值为:8。当消息通过SimpleTcpCluster发送时,用来决定如何发送信息。

    int options= Channel.SEND_OPTIONS_ASYNCHRONOUS |

    Channel.SEND_OPTIONS_SYNCHRONIZED_ACK | Channel.SEND_OPTIONS_USE_ACK;

    Channel.SEND_OPTIONS_SYNCHRONIZED_ACK = 0x0004

    Channel.SEND_OPTIONS_ASYNCHRONOUS = 0x0008

    Channel.SEND_OPTIONS_USE_ACK = 0x0002

    如果使用异步(ASYNCHRONOUS)加应答(USE_ACK)方式来发送消息,那么值应该是10(8+2)或者0x000B。

    Manager

    Manager用来在Tomcat节点之前复制Session,当前有两个实现类,分别为:

    org.apache.catalina.ha.session.DeltaManagert和org.apache.catalina.ha.session.BackupManager。DeltaManager调用SimpleTcpCluster.send方法来发送信息,复制并发送Session到集群下所有的节点,不管这个节点有没有部署当前程序。

    BackupManager通过自己直接调用channel来发送信息,复制并发送Session到集群下部署了当前程序的节点。

    DaltaManager的优点是经过实践确认和证明的,非常可靠,而BackupManager在可靠性上不如DaltaManager。DaltaManager缺点是要求集群节点必须部署了同样的程序,节点必须是同种类的。

    <Manager className="org.apache.catalina.ha.session.DeltaManager" expireSessionsOnShutdown="false" notifyListenersOnReplication="true"/>

    下面是Manager的属性描述:

    属性

    描述

    className

    Manager的实现类。

    notifyListenersOnReplication

    如果设置为true,当session属性被复制和移动的时候,session listener被通知

    expireSessionsOnShutdown

    当一个web程序被结束时,tomcat分发销毁命令到每个Session,并通知所有session listener执行。当集群下某个节点被停止时,如果想销毁所有节点下的的Session,设置为true,默认为false

    BackupManager属性:

    属性

    描述

    mapSendOptions

    BackupManager通过一个可复制的map来实现session接受和发送,通过设置mapSendOptions来设定这个map以何种方式来发送信息,默认为:6(asynchronous)。

    Channel

    Channel是Apache Tribes的主组件,channel管理一组子组件,并和它们一起组成了tomcat实例间的通讯框架。在tomcat集群中,DeltaManager通过SimpleTcpCluster调用channel来实现信息传递,而BackupManager自己调用channel以及子组件这些组件来实现信息传递。ReplicatedContext也会调用channel传递context属性。

    <Channel className="org.apache.catalina.tribes.group.GroupChannel">

    下面是channel子组件

    * MemberShip: MemberShip组件自动检索发现集群里的新节点或已经停止工作的节点,并发出相应的通知。默认使用组播(Multicast)实现。

    * Sender: Sender组件管理从一个节点发送到另外一个节点的出站连接和数据信息,允许信息并行发送。默认使用TCP Client Sockets。

    * Receiver: Receiver组件负责监听接收其他节点传送过来的数据。默认使用non-blocking TCP Server sockets。

    * Interceptor: Channel通过Interceptor堆栈进行消息传递,在这里可以自定义消息的发送和接收方式,甚至MemberShip的处理方式。

    Value

    Cluster下的Value同其他tomcat value一样,value在调用Http Request 链中起着拦截器的作用,用来决定什么情况下数据需要被复制。

    <Valve className="org.apache.catalina.ha.tcp.ReplicationValve" filter=" .*\.gif;.*\.js;.*\.jpg;.*\.png;.*\.css;.*\.txt; "/>

    <Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/>

    org.apache.catalina.ha.tcp.ReplicationValve,ReplicationValue在Http Request结尾判断当前数据是否需要被复制。它的具体属性描述如下表所示:

    属性

    描述

    className

    org.apache.catalina.ha.tcp.ReplicationValve,ReplicationValue

    filter

    Filter内容为url或者文件结尾,当访问链接配置filter时,不论实际session有没有改变,集群会认为session没有任何变化,从而不会复制和发送改变的session属性。Filter写法如下:filter=" .\.gif;.\.js;.\.jpg;.\.png;.\.css;.\.txt; "。filter使用正则表达式,每个url或者后缀以逗号分开。

    Deployer

    使集群支持farmed deployment。这个功能还很弱,在变化和更改中。

    ClusterListener

    Clusterlistener用来追踪信息发送和接收。JvmRouteSessionIDBinderListener用来监听session id的变化。这个listener仅当使用mod_jk并且属性有jvmRoute时才起作用。当session id 改变后,JvmRouteBinderValve将广播这个信息并被此listener捕获。ClusterSessionListener用来监听集群组件接收信息,当使用DeltaManager的时候,信息被集群接收,并通过ClusterSessionListener传递给Session Manager。

    <ClusterListener className="org.apache.catalina.ha.session.JvmRouteSessionIDBinderListener"/>

    <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/></Cluster>

     在部署Web集群,我们还需要考虑一些特定的问题:

    1。Web应用中文件的处理。比如用户上传文件或应用动态生成的文件。这些文件没有必要在集群中的每个实例间进行同步,便很多情况下,需要考虑集群中每个实例都能访问到这些文件。

    2。定时任务或者某些由外部消息或事件触发的任务。这些任务也许只需要在集群的一个实例中运行就可以了。这就需要部署时能保证这些任务仅运行一次,避免任务被多次执行。

    3。应用中的单例设计。如果应用中存在单例设计来共享对象状态,那么在集群环境中需要改变这样的设计。

    4。如果集群后端采取的是并置结构,要根据业务谨慎考虑写操作的并发。诸如类似火车票在线订票的情况,它存在明显‘资源’竟争,对同一资源的写操作需要路由到集群的单一实例上进行操作。对其它事务要求不高的情况下,写操作可以在多个集群实例上进行。

     如果我们要搭建带负载均衡的高可用的Web集群,还需要集成keepalived组件。keepalived是一个实现了失效转发机制的软件,工作机制上类似于layer3, 4 & 5交换机制。它的主要作用是检测web服务器的健康状态以及LoadBalance主机和BackUP主机之间的failover实现。如果Keepalived将检测到有一台web服务器宕机或出现故障,它将把发生故障的web服务器从拓扑中删除。当web服务器工作恢复正常后,Keepalived又可自动将web服务器加入到集群中。这样防止了单点,同时也不影响外界与服务器之间的交互。

    具体工作原理如下:

    Keepalived使用Layer3的方式工作式时,Keepalived会定期向集群中的服务器发送一个ICMP的数据包(Ping程序)。如果发现某台服务的IP地址没有激活,Keepalived便报告这台服务器失效,并将它从服务器群中剔除,Layer3的方式是以服务器的IP地址是否有效作为服务器工作正常与否的标准。

    Keepalived使用Layer4的方式工作式时,主要以TCP端口的状态来决定服务器工作正常与否。如Keepalived检测到Web服务端口(一般为80端口)没有启动,则Keepalived将会把这台服务器从集群中剔除。

    Keepalived使用Layer4的方式工作式时,即是工作在应用层。Keepalived将根据用户的设定检查服务器程序的运行是否正常,如果与用户的设定不相符,则Keepalived将把服务器从服务器群中剔除。这种方式在网络上占用的带宽要大一些。

     这样,一般的带负载均衡高可用的Web集群架构为Nginx+Keepalived+Tomcat的架构方式。当然也可以采用HaProxy+Keepalived+tomcat的架构方式。

    关于软件级负载均衡器(LVS/HAProxy/Nginx)的特点简介和对比一文给出一个比较,更详细的内容可参考原文http://andrewyu.blog.51cto.com/1604432/697466

    LVS:使用集群技术和Linux操作系统实现一个高性能、高可用的服务器,它具有很好的可伸缩性(Scalability)、可靠性(Reliability)和可管理性(Manageability)。

    LVS的特点是:

    1、抗负载能力强、是工作在网络4层之上仅作分发之用,没有流量的产生,这个特点也决定了它在负载均衡软件里的性能最强的;

    2、配置性比较低,这是一个缺点也是一个优点,因为没有可太多配置的东西,所以并不需要太多接触,大大减少了人为出错的几率;

    3、工作稳定,自身有完整的双机热备方案,如LVS+Keepalived和LVS+Heartbeat,不过我们在项目实施中用得最多的还是LVS/DR+Keepalived;

    4、无流量,保证了均衡器IO的性能不会收到大流量的影响;

    5、应用范围比较广,可以对所有应用做负载均衡;

    6、软件本身不支持正则处理,不能做动静分离,这个就比较遗憾了;其实现在许多网站在这方面都有较强的需求,这个是Nginx/HAProxy+Keepalived的优势所在。

    7、如果是网站应用比较庞大的话,实施LVS/DR+Keepalived起来就比较复杂了,特别后面有Windows Server应用的机器的话,如果实施及配置还有维护过程就比较复杂了,相对而言,Nginx/HAProxy+Keepalived就简单多了。

    Nginx:

    Nginx的特点是:

    1、工作在网络的7层之上,可以针对http应用做一些分流的策略,比如针对域名、目录结构,它的正则规则比HAProxy更为强大和灵活,这也是许多朋友喜欢它的原因之一;

    2、Nginx对网络的依赖非常小,理论上能ping通就就能进行负载功能,这个也是它的优势所在;

    3、Nginx安装和配置比较简单,测试起来比较方便;

    4、也可以承担高的负载压力且稳定,一般能支撑超过几万次的并发量;

    5、Nginx可以通过端口检测到服务器内部的故障,比如根据服务器处理网页返回的状态码、超时等等,并且会把返回错误的请求重新提交到另一个节点,不过其中缺点就是不支持url来检测;

    6、Nginx仅能支持http和Email,这样就在适用范围上面小很多,这个它的弱势;

    7、Nginx不仅仅是一款优秀的负载均衡器/反向代理软件,它同时也是功能强大的Web应用服务器。LNMP现在也是非常流行的web架构,大有和以前最流行的LAMP架构分庭抗争之势,在高流量的环境中也有很好的效果。

    8、Nginx可用作Web反向加速缓存

    HAProxy

    HAProxy的特点是:

    1、HAProxy支持虚拟主机的。

    2、能够补充Nginx的一些缺点比如Session的保持,Cookie的引导等工作

    3、支持url检测后端的服务器出问题的检测会有很好的帮助。

    4、它跟LVS一样,本身仅仅就只是一款负载均衡软件;单纯从效率上来讲HAProxy更会比Nginx有更出色的负载均衡速度,在并发处理上也是优于Nginx的。

    5、HAProxy可以对Mysql读进行负载均衡,对后端的MySQL节点进行检测和负载均衡,不过在后端的MySQL slaves数量超过10台时性能不如LVS,所以我向大家推荐LVS+Keepalived。

    6、HAProxy的算法现在也越来越多了,具体有如下8种:

    ①roundrobin,表示简单的轮询,这个不多说,这个是负载均衡基本都具备的;

    ②static-rr,表示根据权重,建议关注;

    ③leastconn,表示最少连接者先处理,建议关注;

    ④source,表示根据请求源IP,这个跟Nginx的IP_hash机制类似,我们用其作为解决session问题的一种方法,建议关注;

    ⑤ri,表示根据请求的URI;

    ⑥rl_param,表示根据请求的URl参数'balance url_param' requires an URL parameter name;

    ⑦hdr(name),表示根据HTTP请求头来锁定每一次HTTP请求;

    ⑧rdp-cookie(name),表示根据据cookie(name)来锁定并哈希每一次TCP请求。

  • 相关阅读:
    CSS笔记
    WebStorm快捷键
    单例模式详解
    JS正则表达式
    Java NIO 详解(二)
    Java NIO 详解(一)
    【Java并发编程】之十六:深入Java内存模型——happen-before规则及其对DCL的分析(含代码)
    Go 普通LOG输出
    Go TCP网路程序编写
    Go 语言官方包函数中文翻译
  • 原文地址:https://www.cnblogs.com/jevo/p/3114545.html
Copyright © 2020-2023  润新知