负载均衡下,WEB集群session管理

jopen 10年前

    通常状况下,在部署项目时,我们会考虑访问量过高带来的一系列问题,解决这个问题的一种做法是,使用WEB集群来分布式部署项目,即负载均衡。负载均衡可以通过软件,硬件等多种方式去实现。下面说说这个方法的区别。

      软件实现的负载均衡:这一类的软件常用的有nginx,这里也可以将nginx看做成一个网关,通常一个nginx最多可以配置6个tomcat。nginx实现原理就是在中间层作为一个网关,然后地址转发到不同的tomcat(注:每个tomcat都拥有一个唯一的端口号)。优点是性价比高,而且可以根据系统与应用的状况来分配负载。

     硬件实现的负载均衡:硬件实现的负载均衡,通常需要一个服务器集群,加上一个负载的服务器。冗余较高。从而带来成本的上升,而且对于负载的服务器来说,一旦出现问题,整个应用就会瘫痪掉,硬件负载只会关注网络层状况,而不会像软件负载一样可以根据系统与应用的状况去灵活分配负载。

   简单的介绍了负载均衡的简单概念后,在实际应用的时候,我们通常会遇到session保持的问题,举个简单的例子,以tomcat为例,我们都知道session存在于服务器端,对于不是分布式部署,整个系统的session都会是这唯一的服务器来管理。这点没问题。但是对于分布式部署来说,假设有tomcatA与tomcatB,但用户user访问系统时,通过负载均衡,此user访问了位于tomcatA上的应用。系统给此用户分配了一个session来标识用户身份,并返回sessionID给浏览器。这时user又向服务器发送个请求。假设这时候负载均衡到了tomcatB,但是此时tomcatB上并没有存有user相应的session信息。根据一般应用的设置,会提示user重新登录,试想下user就这样一直登录,一直被提示未登录,这样肯定行不通。

    在实际应用中,有很多解决这种问题的方法,下面来介绍几种解决方法及其优点与弊端。

------------------------------------------------------------------------------------------------------------------------------------

  1、 session复制:看到标题,顾名思义就是复制session的意思,继续引用上面的例子来说明,当user访问应用时,第一次被负载均衡到了 tomcatA,tomcatA给用户分为一个session的同时,会向tomcatB同时复制一份,这样当user下次访问应用时,即使被负载均衡到了tomcatB,tomcatB上也会有相对应的session信息。但缺点也显而易见,试想一下,当我们采用很多tomcat进行负载时,每次一个 user访问时,产生的session都会复制到其他tomcat上面。很容易造成大量的网络通信,这样的效率会低很多。

------------------------------------------------------------------------------------------------------------------------------------

2、terracotta : 是由terracotta公司生产的用于集群间共享数据的工具,可以应用于session同步。即tomcatA与tomcatB各节点中的session 信息全部交由terracotta统一管理。且支持容灾处理。

------------------------------------------------------------------------------------------------------------------------------------

3、粘性session : 还是用上面的例子,当user访问应用的时候,被转发到了tomcatA上,这时候使用粘性session,当user下次在访问应用时,会被负载均衡到同一节点上,即tomcatA。这样就很简单的实现了session保持的问题。但是session粘性不具备容灾处理,所以当某个tomcat挂掉后,这台tomcat上管理的所有session信息都会失效。

-------------------------------------------------------------------------------------------------------------------------------------

4、nginx中的ip_hash:

         在官网上可以看到这样的解释:

This directive causes requests to  be distributed between upstreams based on the IP-address of the client.
The key for the hash is the class-C network address or the entire IPv6-address of the client. IPv6 is supported for ip_hash since 1.3.2 or 1.2.2. This method guarantees that the client request will always be transferred to the same server. But if this server is considered inoperative, then the request of this client will be transferred to another server. This gives a high probability clients will always connect to the same

         大致意思为:将客户IP化转化为c类网络地址,然后将这网络地址作为hash关键字,来保证这个客户的请求总是被转发到一台服务器上。

         该类方法实现的前提是使用nginx来做负载均衡,当我们配置ip_hash时,user去访问应用,假设会被nginx转发到tomcatA上,当下次去访问应用时,nginx会根据ip转化为的网络地址作为  hash 关键字来识别是否是同一用户。这样user又会被转发到tomcatA上。