在GlassFishVersion2中实现集群

本文将讨论GlassFish Version2的集群功能,帮助您将自己的应用程序部署在GlassFish集群上。

Sun Java System Application Server 9.1是开放源码GlassFish version 2应用服务器的Sun发行版。本文使用GlassFish version 2这个名称表示这两者。

基本概念

应用服务器中的集群可增强可伸缩性和可用性,而这两者是彼此相关的。

为了提供高可用性的服务,软件系统必须具有以下功能:

系统必须能够创建并运行服务提供的实体的多个实例。在应用服务器中,服务提供的实体是在集群中运行的Java EE应用服务器实例,服务是部署的Java EE应用程序。

为了处理增加的服务负载,系统必须能够在集群中添加应用服务器实例,从而适应更大的部署。

如果集群中的一个应用服务器实例发生了故障,那么必须能够故障转移到另一个服务器实例,使服务不会中断。尽管服务器实例或物理机器的故障会使服务的总体质量有所下降,但是在高可用性环境中服务完全中断是不可接受的。

如果某个进程要修改用户会话的状态,那么会话状态必须被持久化,能够在进程重新启动之后恢复。最简单的方法是维护一个可靠的会话状态副本;如果进程终止了,那么在进程重新启动时可以恢复会话状态。这个原理与高可用性RAID存储系统的原理相似。

这些要求导致系统牺牲高效率来换取高可用性。

为了支持可伸缩性和高可用性,GlassFish应用服务器提供以下服务器端实体:

服务器实例(Server Instance) – 服务器实例是一个Java EE 服务器进程(GlassFish应用服务器),该进程运行着各种Java EE应用程序。根据Java EE规范的要求,必须针对要运行的各个子系统对每个服务器实例进行配置。

节点代理(Node Agent) – 节点代理是一个代理进程,它在运行服务器实例的每个物理主机上运行。当 本文后面 描述的Domain Administration Server(DAS)发出指示时,节点代理将管理服务器实例的生命周期。

集群(Cluster) – 集群是一个逻辑实体,它决定组成集群的服务器实例的配置。集群的配置常常意味着集群中的所有服务器实例有相同的配置。管理员通常将集群看做一个单一实体,并使用GlassFish Admin Console或命令行界面(CLI)管理集群中的服务器实例。

可以在安装GlassFish时创建节点代理、服务器实例和集群,见 本文后面的说明。集群和实例被组织成管理域(administrative domain),这由Domain Administration Server(DAS)控制。

域管理体系结构

GlassFish集群体系结构的核心概念是管理域(administrative domain)。管理域表示管理员或管理员组的访问权限。下图给出域管理体系结构的概况(只包含一个域)。

图1. 域管理体系结构

管理域是一个具有双重性的实体:

在由开发人员使用时,它可以提供一个特性完整的Java EE进程,可以在其中运行应用程序和服务。

在真实的企业部署中使用时,它可以提供一个专门用于配置和管理其他进程的进程。在这种情况下,管理域将采用Domain Administration Server(DAS)的形式,并且只能用于管理目的。

在文件系统中,管理域由一组配置文件组成。在运行时,它是一个对本身、独立的服务器实例、集群、应用程序和资源进行管理的进程。

总的来说,高可用性安装需要集群,但是不一定需要独立的服务器实例。GlassFish应用服务器提供同构的集群,让我们能够把每个集群作为单一实体来管理和修改。

如图所示,每个域有一个Domain Administration Server(DAS),DAS用来管理这个域中的Java EE服务器实例。图中央的Administration Node支持DAS。应用程序、资源和配置信息存储在非常接近DAS的地方。由DAS管理的配置信息称为配置中心存储库(central reposiTory)。

每个域进程必须在一个物理主机上运行。在运行时,域本身表现为一个DAS。同样,每个服务器实例必须在一个物理主机上运行,并需要一个Java虚拟机。在运行服务器实例的每台机器上都必须安装GlassFish应用服务器。

图右边显示两个节点:Node 1和Node 2,它们各自包含两个GlassFish服务器实例。

每个节点代理控制它的机器上一个给定域中配置的实例的生命周期。每个生命周期由DAS根据管理员的请求进行管理。DAS将每个实例的实际生命周期管理委派给对应的节点代理。节点代理是一个轻型的进程,它本身并不运行Java EE应用程序。

除了控制实例的生命周期之外,节点代理还监视(“watchdogs”)它所负责的服务器实例。如果服务器实例发生故障,它的节点代理会重新启动它 — 不需要管理员或DAS干预。

图1左边显示几个管理客户机。DAS中的管理基础结构基于Java Management Extensions(JMX)技术。DAS中的基础结构符合JAX规范的instrumentation级别,并以Managed Beans(MBeans)的形式使用管理信息(MBeans是代表要管理的资源的Java对象)。

因为MBeans符合JMX标准,所以可以用任何远程的标准JMX客户机(比如随Java SE 5.0发行的JConsole)浏览它们。图1所示的内置客户机使用JMX API来管理域。这些客户机需要具有管理特权才能管理域。管理客户机包括:

Admin Console – Admin Console 是一个用来管理中心存储库的基于浏览器的界面。中心存储库提供DAS级的配置。

命令行界面 – asadmin命令提供与Admin Console相同的功能。另外,有一些操作只能通过asadmin执行,比如创建域或创建节点代理。如果没有DAS,就不能运行Admin Console,而这意味着必须要有域和节点代理。asadmin命令提供建立这个体系结构的方法。

IDE – 图中显示一个JSP(JavaServer Page)编辑器的快照,它是NetBeans IDE的一部分。NetBeans IDE这样的工具可以在开发期间使用DAS连接并管理应用程序。NetBeans IDE还支持集群模式部署。大多数开发人员在一个域和一台机器上工作,这称为开发人员配置(developer profile)。在开发人员配置中,DAS本身作为所有应用程序的主机。

Sun Provisioning Server – Sun Provisioning Server用来在经过基本配置的机器上安装和配置DAS。例如,假设要在一个大型数据中心中添加一台新机器。在这种情况下,会在机器上安装操作系统,然后安装所需的所有软件产品。在此之后,可以创建一个节点代理,根据需要,还可以创建一个DAS。最后,启动节点代理,将这台机器合并到现有的域中。Sun Provisioning Server可以完成所有这些任务,避免管理员在新机器上执行手工安装。

集群体系结构

图2按照以运行时为中心的视角描述GlassFish集群体系结构。这个图强调体系结构的高可用性方面。图2中没有显示DAS,节点和它们的应用服务器实例组合在一起,形成集群的实例。

图2. 集群体系结构概况

在图2的顶部,显示各种传输协议(HTTP、JMS、RMI-IIOP),它们通过一个负载平衡层与集群的实例通信。定制的资源(比如企业信息系统)通过Java连接器体系结构中的资源适配器连接负载平衡器。可以跨集群对所有传输协议进行负载平衡,这可以提高可伸缩性,而且可以通过为单点故障提供冗余可用单元实现容错策略。

图的底部是一个High-Availability Application State ReposiTory,这是会话状态存储的抽象。这个存储库存储会话状态,包括HTTP会话状态、有状态EJB会话状态和单点登录信息。可以通过内存复制或数据库方式存储这些状态信息。

替代High-Availability Database的技术

在历史上,Sun Microsystems曾经为应用服务器提供一种基于High-Availability Database(HADB)技术的健壮的高可用性解决方案。HADB为维护会话状态信息提供百分之99.999(“5个9”)的可用性。但是,它的实现和维护成本相当高,而且尽管可以免费获得,但是在开放源码版本中没有提供它。

为了给开放源码的GlassFish应用服务器提供一种轻型的开放源码替代技术,在GlassFish version 2中提供了内存复制特性。内存复制依靠集群中的实例将另一个实例的状态信息存储在内存中,而不是存储在数据库中。但是,HADB解决方案仍然是可用的,而且在许多环境中是首选方案。

集群中的内存复制

对于在内存中维护状态信息的与GlassFish兼容的容错系统,需要几个特性。系统必须为HTTP会话状态、单点登录状态和EJB会话状态提供高可用性。另外,它必须与现有的基于HADB的体系结构兼容。

内存复制特性利用GlassFish的集群特性,提供HADB策略的大多数优点,而安装和管理开销却小得多。

在GlassFish应用服务器中,集群实例组织成一个环形拓扑结构。环中的每个成员将内存状态数据发送给环中的下一个成员(即它的复制伙伴),并接收来自前一个成员的状态数据。当在任何成员中更新状态数据时,数据会沿着环复制。图3给出这个拓扑结构的简化形式。

图3. 集群拓扑结构

拓扑结构形成环形的方式由实例名称的字母表次序决定。所以,如果实例名称像图3中这样,那么Instance 1将向Instance 2复制,Instance 2向Instance 3复制,以此类推。

典型的集群拓扑结构见图4。在这个图中,显示的实例驻留在不同的物理机器上。将Instances 1和Instances 3放在一台机器上,将Instances 2和Instances 4放在另一台机器上,这可以提高可用性。如果其中一台机器发生灾难性故障,那么另一台机器上会保留所有数据(按照原来的形式,或者作为故障机器上实例的副本)。

图4. 典型的集群拓扑结构

典型的故障转移场景

GlassFish应用服务器的设计方式让负载平衡器层在发生故障时不需要特殊信息就能够执行负载平衡。例如,假设负载平衡器将一个会话分派给Instance 1,当Instance 1发生故障时,它不需要知道应该将会话分派给Instance 2。负载平衡器可以向集群中的任何实例发送一个故障转移请求,这种情况常常称为位置透明性。在集群中对故障进行响应。当负载平衡器将一个会话重新分派给一个正在工作的实例时,如果需要的话,这个实例会从另一个实例获得它需要的会话信息。

来自负载平衡器的故障转移请求属于两种情况之一:

第一种情况:接收故障转移请求的实例已经存储会话数据的副本。在这种情况下,实例获得会话的所有权并继续处理。

第二种情况:接收故障转移请求的实例没有所需的会话数据副本。在这种情况下,实例广播一个self-addressed-stamped-envelope(SASE)形式的请求来请求数据。拥有数据副本的实例将数据传输给请求者,并在收到确认消息(表示已经成功地接收了数据)之后删除它的副本。这个数据交换过程是通过 JXTA (Juxtapose)技术完成的。

图5 给出更详细的集群结构。左边是负载平衡层,它可能在一个web服务器上。在每个服务器实例中,一个本地缓存存储HTTP会话信息,这个缓存被复制到下一个实例的复制缓存。

图5. 带负载平衡器的典型集群拓扑结构

图6说明故障转移的第一种情况,在这种情况中重新分派的服务器实例可以直接访问会话状态数据。在图中,Instance 1发生故障,负载平衡器的服务请求被分派给Instance 2,而Instance 2包含所需的会话状态信息的副本。

图6. 故障转移,第一种情况

图7说明故障转移的第二种情况,在这种情况中负载平衡器层将会话重新分派给一个服务器实例,但是这个实例无法直接访问会话状态数据。在图中,Instance 4发现它没有所需的会话状态数据,因此向集群中的其他实例广播一个SASE请求来请求数据。这个请求用黄色箭头表示。

图7. 故障转移,第二种情况

一个实例(图7中的Instance 2)发现它的复制缓存包含所需的数据,就对这个SASE请求进行回复。Instance 2将会话数据的所有权转交给Instance 4,然后Instance 4就开始为这个会话服务。

当一个实例使用数据副本为会话服务时(无论是第一种情况,还是第二种情况),首先要检查数据副本,确保它是正确的版本。

集群动态变形

当集群中的一个实例发生故障或者根据管理员的指示离线时,集群的拓扑结构就需要改变。

在我们的示例中,因为Instance 1发生故障,所以必须改变集群的拓扑结构来维持会话缓存复制过程。在图8中,Instance 2和Instance 4发现Instance 1消失了。因为Instance 1发生故障,所以与它的通信由于I/O异常而失败。如果一个实例是根据指示关闭的,那么JXTA技术会发送消息,指出Instance 1已经关闭。

图8. 集群发现发生故障的实例

在发现Instance 1消失之后,Instance 4会选择一个新的复制伙伴,见图9。Instance 4取消原来的连接并建立到Instance 2的连接。集群现在从4个服务器实例缩减到3个。

图9. 集群动态变形

注意,在会话活动量相同的情况下,比较小的集群中的每个实例现在要负担更多的工作。在进行资源规划时,还要考虑到内存复制会使用堆内存。为了提供高可用性,每个实例的内存必须留有足够的裕量,以便应付集群收缩的情况。

当一个实例加入(或重新加入)集群时,发生本质上相反的过程。当集群中的新实例从负载平衡层接收请求时,这个实例广播一个寻找复制伙伴的请求,选择一个复制伙伴,拓扑结构会自动调整来接纳这个新实例。

Group Management Service

Group Management Service(GMS)提供关于集群和它的成员实例的动态成员关系信息。它的设计借鉴了 Shoal项目 的许多思想,Shoal是一种基于Java技术的集群框架。GMS也是基于JXTA技术的。

GMS管理GlassFish中的集群变形事件,根据成员加入、成员正常关闭或成员故障等事件进行调整。内存复制通过GMS用必要操作响应这些事件,提供连续的服务可用性。

在GlassFish应用服务器中,使用GMS监视集群的状态并支持内存复制模块。

总之,GMS支持以下功能:

集群成员关系变化通知和集群状态

整个集群范围内的或成员之间的消息传递

面向恢复的计算,包括恢复成员选择、故障保护和针对多个故障的恢复链

分布式缓存,这是一个适合交换集群成员关系消息的轻型实现

一个服务提供者接口(SPI),用来加入组通信提供者;默认的提供者是基于JXTA技术的

计时器迁移 – 如果必要的话,GMS会选择一个实例来恢复故障实例的计时器

内存复制配置

为了配置集群内存复制,必须执行三个步骤:

创建一个管理域。在创建域之后,在机器上创建它的节点代理,然后创建一个集群管理配置。这个配置设置复制的默认配置,启用GMS并将persistence-type 属性设置为replicated。

创建一个集群和它的实例(见本文后面的说明)。

部署web应用程序并将availability-enabled 属性设置为true。

这些步骤可以用GUI或CLI来完成。

可能还需要做一些调整。例如,集群管理配置的默认堆大小是512 MB。对于企业部署,这个值应该增加到1 GB或更大。这很容易通过DAS完成,只需用以下标记设置JVM选项:

-Xmx1024m-Xms1024m

还要确保在web应用程序的web.xml文件中添加标记。这个标记表示这个应用程序支持集群。

要求插入标记,这提醒您先在集群环境中对应用程序进行测试,然后才能将它部署到集群中。一些应用程序在部署到单一实例时工作得很好,但是在部署到集群时就会失败。例如,在将一个应用程序成功地部署在集群中之前,属于应用程序的HTTP会话的任何对象(比如有状态会话bean)都必须是可序列化的,这样才能跨网络保留它们的状态。当部署到单一服务器实例时,不可序列化的对象可能会正常工作,但是在集群环境中就会失败。应该检查您的会话数据的内容,确保它在分布式环境中可以正常工作。

内存复制实现

在GlassFish version 2应用服务器中,内存复制特性基于JXTA技术的传输和消息传递功能。

JXTA技术是许多人熟悉的对等技术。它定义为一组基于XML的协议,这些协议让连接到网络的设备可以交换消息并进行协作,而不会受到网络拓扑的限制。在开发GlassFish version 2应用服务器时,改进了JXTA技术来处理内存复制的容量和吞吐量需求。为了提高可伸缩性和性能,内存复制特性的开发人员利用了 Grizzly项目 提供的协作功能,这个项目帮助开发人员用 Java New I/O API (NIO)构建可伸缩的健壮的服务器。

JXTA技术中的组成员关系抽象映射到GlassFish应用服务器集群和实例模型:JXTA组映射到GlassFish集群,JXTA对等体映射到GlassFish服务器实例。GMS是用于处理集群中的运行时事件的通知事件模型,它使用这些组成员关系抽象并提供内存复制等消费组件。

在开发GlassFish version 2应用服务器时,集群拓扑结构被限制在单一子网中。未来的计划包括通过JXTA支持地理上分散的集群拓扑结构。

最后,JXTA技术的API非常简单,这使GlassFish集群的配置非常简单。

应用服务器安装

安装GlassFish应用服务器的步骤如下:

输入以下命令:

java -jar filename.jar

例如:

java -jar glassfish-installer-v2-b58g.jar

接受许可协议。在接受许可协议之后,文件释放到GlassFish安装目录(默认名称为glassfish)中。

现在需要配置GlassFish应用服务器。

集群配置

安装目录包含两个ant构建脚本,可以用它们创建默认域。这两个脚本是setup.xml和setup-cluster.xml。

setup.xml脚本创建开发人员配置;setup-cluster.xml脚本创建集群配置。可以通过Sun Java System Application Server Admin Console将开发人员配置转换为集群配置。

用集群配置创建默认域的步骤如下:

在GlassFish安装目录中输入以下命令:

lib/ant/bin/ant -f setup-cluster.xml

配置脚本将存档文件释放,并创建domains子目录和一个启用集群的名为domain1的域。

GlassFish的配置现在完成了。

域检查

可以通过CLI(asadmin命令)或GUI(Sun Java System Application Server Admin Console)了解和管理域。

从命令行界面检查域

配置步骤在安装目录中创建了一个domains子目录。这个目录存储所有GlassFish域。

可以从CLI用asadmin命令与域进行交互,这个命令在安装目录下的bin子目录中。可以按照批处理模式或交互模式使用asadmin命令。

例如,可以用以下命令列出所有域及其状态:

bin/asadmin list-domains

如果还没有启动domain1,那么以上命令会产生以下输出:

domain1 not running

输入以下命令来启动domain1:

bin/asadmin start-domain domain1

如果只有一个域存在,参数domain1就是可选的。这个命令启动domain1并提供各种信息,包括日志文件的位置、服务器的版本、域名、可用的web上下文、部署的应用程序、使用的端口等等。

用Sun Java System Application Server Admin Console检查域

可以使用Sun Java System Application Server Admin Console替代asadmin命令来控制应用服务器。下一节描述如何启动这个控制台。

Admin Console简化了从.war或.ear文件或JBI(Java Business Integration)服务配件部署应用程序的过程。在这个控制台上,可以监视资源的使用情况、搜索日志文件、启动和停止服务器、访问联机帮助并执行许多其他管理和服务器管理功能。

为现有域启用集群支持

可以在现有的域中添加集群支持。如果不修改配置的话,使用开发人员配置的域就不支持集群。在GlassFish安装目录中,使用以下命令创建一个开发人员配置域:

lib/ant/bin/ant -f setup.xml

在开发人员配置域中启用集群支持的步骤如下:

在GlassFish安装目录中输入以下命令,启动要重新配置的域:

bin/asadmin start-domain domain_name

例如:

bin/asadmin start-domain domain1

这个命令在域中启动GlassFish应用服务器,并在命令shell窗口中提供信息。最后一行信息描述域的功能;当前情况下,这一行是:

Domain does not support application server clusters and other standalone instances.

将web浏览器指向以下URL,启动Administration Console:

http://hostname:port

默认端口是4848。例如:

http://kindness.sun.com:4848

如果Administration Console在安装应用服务器的机器上运行,那么将主机名指定为localhost。在Windows上,从Start菜单启动Application Server Administration Console。

默认的登录信息是

用户名:admin

密码:adminadmin

在窗口左边的Common Tasks树中,选择Application Server。在窗口右边,选择General选项卡。

单击Add Cluster Support按钮,如下图所示。

图10. 添加集群支持

这时显示一个确认页面,它指出修改集群支持会有哪些后果。要考虑以下情况:

修改域的配置来支持集群。修改包括添加几个系统属性和模板配置。

启用集群的服务器将支持集群服务器实例和单独的服务器实例。

因为集群常常会增加对资源的需求,所以可能需要修改管理服务器的JVM设置,比如堆大小。

在启用集群的域中的服务器上,当前部署的所有应用程序都可以继续工作。

对集群支持的修改会在重新启动域服务器和asadmin CLI之后生效。

在继续进行配置之前,可能希望备份域的domain.xml文件,以防需要恢复配置的情况。

单击OK为域启用集群支持。这时打开一个页面,提示您重新启动这个域的服务器实例。

单击Stop Instance按钮。

如果asadmin命令在命令shell中运行,那么在asadmin>提示下输入quit退出这个命令。

输入以下命令从CLI重新启动域:

asadmin start-domain domain_name

例如:

asadmin start-domain domain1

如果为这个域成功地启用了集群支持,那么命令shell中的最后一行输出如下:

Domain supports application server clusters and other standalone instances

HTTP负载平衡器插件

负载平衡器将工作负载分配给多个应用服务器实例,这可以增加系统的总吞吐量。尽管在将会话请求分派给服务器实例时,负载平衡器层不需要特殊信息,但是它需要维护可用节点的列表。如果一个节点没有对请求做出预期的回复,负载平衡器就选择另一个节点。

负载平衡器可以用软件或硬件实现。关于硬件负载平衡器的实现细节,请参考硬件供应商提供的信息。

GlassFish version 2应用服务器可以使用一个HTTP负载平衡器插件。这个插件可以与Sun Java System Application Server 9.1以及Apache Web Server和Microsoft IIS配合工作。这个负载平衡器还能够将请求从一个服务器实例故障转移到另一个实例,这会提高可用性。

关于设置负载平衡器插件的更多信息,请参考Sun Java System Application Server 9.1 Admin Console提供的联机帮助。还可以参考 Sun Java System Application Server 9.1 High Availability Administration Guide中的Chapter 5, Configuring HTTP Load Balancing。

结束语

GlassFish version 2应用服务器提供一个灵活的集群体系结构,这个体系结构由管理域、域管理服务器、服务器实例和物理机器组成。这个体系结构容易使用,提供了很强的管理控制能力,可以提高可用性和水平可伸缩性。

高可用性 – 多个服务器实例能够共享状态,减少单点故障,尤其是在与负载平衡方案结合使用的情况下。服务器会话状态数据的内存复制可以减少服务器实例故障对用户的干扰。

水平可伸缩性 – 随着用户负载的增加,可以轻松地添加和配置更多的机器、服务器实例和集群来处理增加的负载。GMS降低了维护高可用性集群的管理负担。

近朱者赤,近墨者黑

在GlassFishVersion2中实现集群

相关文章:

你感兴趣的文章:

标签云: