使用MBeans创建定制的WebLogic Server负载均衡方案

来源:互联网 发布:网络金融平台排名 编辑:程序博客网 时间:2024/06/06 03:42
本文将展示如何根据从集群的托管服务器收集的MBean信息制定一个定制负载均衡解决方案。

本文将展示如何根据从集群的托管服务器收集的MBean信息制定一个定制负载均衡解决方案。该解决方案基于BEA WebLogic Server CallRouter类和所收集MBean统计信息的组合使用。在本文中,我把使用各个服务器上的大量空闲内存作为一种策略。结果,服务器之间的大量工作将基于垂直范例(vertical paradigm)进行分布,这将导致更好地使用域中的内存资源。

简介

  使用集群应用程序的主要好处之一是可以将负载分布到几台机器上。默认情况下,WebLogic Server集群使用了一个round-robin负载均衡解决方案来分配服务器之间的负载。在选择使用round-robin算法时,来自集群存根的请求将循环遍历对象所驻留的服务器实例的列表。先选择一个特定顺序,然后按此顺序使用每台服务器,直到到达列表的末尾,接着再重复循环这一过程。

  round-robin方案简单并且可以预测。但是该策略并不根据不断变化的服务器负载作出反应。例如,如果集群中的某一台服务器负载过重,它仍将像集群中的其他服务器一样继续参与round-robining方案,因此该服务器上可能堆积很多工作。

  为了找到解决这一问题的解决方案,我们根据实际情况构建了一个用例。假设有一个应用程序,它以某种非常依赖用户交互的方式交付关键的业务功能。利用电信网络的表列数据(tabular data)生成XML文档的应用程序可能是一个好例子。根据网络拓扑和选定的区域,您可以创建一个100kb的XML文档,或者创建一个令人畏惧的1Gb的XML文档。

  因为存在上述失调情况,可能会使您在最后几个小时终止业务操作,使服务器处于过重的负载下;您可能还有一些在非常短的时间内完成的操作。

  解决这个问题的一个解决方法就是在发出调用之前调查目标节点的状态。开发人员可以有几个选择。例如,用户可以只选择不太忙的服务器。如果选择分配一组高容量的服务器来处理繁重的任务,并分配“内存小”的服务器处理基本请求,那么可能是另一番场景。无论选择哪一种策略来处理负载均衡调用,都必须了解关于weblogic.rmi.cluster.CallRouter接口的更多信息。

CallRouter类

  weblogic.rmi.cluster.CallRouter是编写定制路由策略的起点。每次调用一个EJB远程方法时,都由一个可集群的存根来调用调用路由器(call router)。该路由器负责返回该调用应该路由到的服务器的名称。集群中的每台服务器都是通过其名称惟一标识的,正如WebLogic Server Console中定义的那样。这些名称是方法路由器用来标识服务器所必须使用的名称。

  要使用此接口,则必须实现getServerList()方法,该方法在每次调用特定EJB时调用。该方法的返回值是一个字符串数组,用于指定执行此调用的服务器。服务器在此数组中的顺序非常重要。WebLogic Server根据此数组中找到的顺序联系服务器。因此,在下面的示例中,请求将转发至server1,如果该服务器处于非活动状态下,则将请求转发至server2,最后选择转发至server3:

 public String[] getServerList(Method m, Object[] params) {    String serverList[] = {"server1","server2","server3"};  return serverList; }

  该路由器类是在stateless-clustering代码段的weblogic-ejb-jar.xml中配置的,如下所示:

<weblogic-enterprise-bean>  <ejb-name>TestRouterEJB</ejb-name>  <stateless-session-descriptor>     <stateless-clustering>       <stateless-bean-is-clusterable>True</stateless-bean-is-clusterable>       <stateless-bean-call-router-class-name>test.BeanRouter</stateless-bean-call-router-class-name>       </stateless-clustering>     </stateless-session-descriptor>   <jndi-name>TestRouterEJB</jndi-name> </weblogic-enterprise-bean>

  在这里,test.BeanRouter指定了用来路由针对特定EJB的bean方法调用的定制类。在调用每个方法之前,将调用此类的一个实例,并给出一个基于方法参数选择将路由到哪一台服务器的机会。它将返回一个服务器名称或者null,后者表示应该使用默认负载算法挑选服务器。

  如果目标是根据服务器的负载分配负载,那么可以根据空闲内存的数量或总分配内存(可以二者结合使用)进行您的选择。JDK提供了一个通过Runtime类检索此信息的简单方法。一个中立方法可能是将每个服务调用的内存信息持久存储在某个地方,如下所示:

long freeMemory = Runtime.getRuntime().freeMemory();.....// in some SQL codeINSERT into MEMORY_INFO (server_name, free_memory) values ( ?, ? )
INSERT into MEMORY_INFO (server_name, free_memory) values ( ?, ? )

  这取决于收集关于内存的统计信息并以适当方式分配调用的路由器类。不过,还有解决这个问题的更好方法,现在让我们来研究一下这个方法。


用MBeans解决这个问题 每个WebLogic Server实例都有一个自己的用来保存许多MBeans的MBean Server。MBean Server充当MBeans的注册表,为访问和操作运行在服务器上的MBeans提供服务。WebLogic Server对三组不同的MBea

用MBeans解决这个问题

  每个WebLogic Server实例都有一个自己的用来保存许多MBeans的MBean Server。MBean Server充当MBeans的注册表,为访问和操作运行在服务器上的MBeans提供服务。WebLogic Server对三组不同的MBeans进行了区分:

  • Configuration MBeans公开用来配置某一资源的属性和操作。
  • Runtime MBeans提供关于资源的运行时状态的信息。
  • Security MBeans反映了SSPI,提供对服务器安全网络配置的直接访问。

  在这里,最重要的是Runtime MBeans,它反映了资源的运行时状态。现在我们要着手做的第一件事就是找到MBean Server的主接口。主接口提供了对底层MBean服务器的访问,并允许您到达驻留在服务器上的MBeans。

  可以用两种方式检索MBeanHome。如果想使用标准Java EE方法,那么可以使用Java Naming和Directory Interface (JNDI)来检索MBeanHome:

MBeanHome home = (MBeanHome) ctx.lookup(MBeanHome.ADMIN_JNDI_NAME);

  作为一种替换,您可以使用WebLogic Server Helper类:

String url = "t3://localhost:7001";String username = "weblogic";String password = "weblogic";String msName = "MS1";MBeanHome localHome =   (MBeanHome)Helper.getMBeanHome(username, password, url,msName);

  除了检索MBeanHome范围内的所有MBeans的列表之外,还可以检索与特定类型匹配的MBeans的列表。在本例中,焦点是ServerRuntime MBeans,它收集关于WebLogic Server实例的Runtime信息:

Set mbeanSet = home.getMBeansByType("ServerRuntime");

  包含关于JVM的运行时信息的接口是JVMRuntimeMBean,对我们有用的方法(MBean属性)如下:

  • long getHeapFreeCurrent() - 返回JVM堆中空闲内存的当前数量(以字节为单位)。
  • long getHeapSizeCurrent() - 返回JVM堆的当前大小(以字节为单位)。

  以下是集群中空闲内存的数量:

Iterator mbeanIterator = mbeanSet.iterator();while(mbeanIterator.hasNext()) { serverRuntime = (ServerRuntimeMBean)mbeanIterator.next(); if (serverRuntime.isAdminServer()) {   log("Found admin Server");   continue; } String strServer = serverRuntime.getName(); long memory = serverRuntime.getJVMRuntime().getHeapFreeCurrent(); log("Free memory on server " + strServer + " : " +freeMemory );}

  注意,在进行迭代时,可以跳过AdminServer,因为您只对监视Managed Servers感兴趣。现在您要做的就是收集运行时统计信息,并根据您的标准对已排序的服务器列表进行排序。为此,您可以编写一个定制类,用它来实现保存排序模式的Comparable接口。下图综合了已经介绍过的一些概念:

 



图 1:客户机如何在负载均衡的情况下调用特定服务器

  在图1中,客户机调用了一个EJB [1],该EJB位于由两个节点组成的集群上。一旦调用EJB方法,集群感知存根将负责选择负载均衡算法。在选择采用定制负载均衡算法时,将发出对getServerList()的回调 [2]。一旦位于Router类中,就可以从JNDI树检索RuntimeMBean [3]并收集相关统计数据。在最后一步中 [4],将返回一个字符串数组,这些字符串是为了接收调用而分配的托管节点。

示例代码,获得展示这样一个实现的完整类清单。

Workload Management in WebLogic Server 9.0获得有关的细节信息。 汇总 既然已经查看了MBeans和CallRouter,现在让我们来查看如何将它们汇总在一起。因此,您要做的第一件事是编写您自己的定制路由器类。在准备好

Workload Management in WebLogic Server 9.0获得有关的细节信息。

汇总

  既然已经查看了MBeans和CallRouter,现在让我们来查看如何将它们汇总在一起。因此,您要做的第一件事是编写您自己的定制路由器类。在准备好该类之后,应该让应用程序可以看见它。如果该路由器类将由您的应用程序使用,最好的选择是将该类添加到EJB的JAR中。此外,可以考虑将路由器类(及其依赖项)添加到Weblogic Server的类路径中。记住,无论如何,启动时在服务器的类路径中引用的所有类和库都是由根类路径的类加载器加载的,所以在服务器运行时,您不能卸载(或刷新)这些类中的任何类。

  因此让我们来考虑第一个选择。您已经添加了一些类到EJB的JAR中,所以现在可以动态修改路由器类,不需要重新启动服务器。现在需要在weblogic-ejb-jar.xml中包含路由器类声明,正如上面所指示的那样。注意,不需要对ejb-jar.xml文件进行任何更改。一旦完成这一步骤,应用程序就准备就绪,可以为您的集群对其进行部署了。

  我尚未提及的一件事是哪些类型的EJB可以在此场景中使用。仔细观察一下WebLogic Server 8.1 DTD,您就会发现,路由器类名称只可以用于无状态会话bean。为什么呢?因为无状态会话bean类型的所有实例都是相同的,主存根或远程存根可以在任何服务器上保存它们通过任何可用对象接收的请求。这使得无状态会话bean成为定制负载均衡策略的理想候选。

  另一方面,当您处理有状态的会话bean时,客户机被“牵制”在它创建的服务器对象上。结果,因为客户机的这种受实例牵制的特性,远程存根被连接到特定服务器,而定制负载均衡没有任何意义。默认情况下,相同的情况也出现在实体bean上(读/写),在那里,负载均衡和故障转移功能只限定于主存根。

Caveats

  在规划WebLogic Server集群时,常常忽略的一个方面是:WebLogic Server并不总是对某一对象的方法调用进行负载均衡。在多数情况下,使用与存根本身搭配在一起的副本而不是使用位于远程服务器上的副本会更有效。

  配置优化也经常使每次进行方法调用时都期望或需要负载均衡的管理员或开发人员感到困惑。如果您的Web应用程序被部署到单个集群,那么配置优化会重写副本感知存根中固有的任何负载均衡逻辑。该优化声称,如果当对象调用某一副本时,该副本可在相同服务器实例上使用,则无法对该调用进行负载均衡,因为使用本地副本更有效。

  如果需要在某一集群对象的每个方法调用上进行负载均衡。则必须遵从BEA的Recommended Multi-Tier Architecture,它解释了如何相应地规划您的WebLogic Server集群。简言之,您可能需要让EJB客户机和EJB类驻留在单独的集群上。例如,您可以将servlet驻留在一个集群上,将EJB驻留在另一个单独的集群上;在此servlet中,EJB的方法调用可以在几台服务器之间进行负载均衡。

 

结束语

  通过将集群应用程序与CallRouter接口集成,您要负责设置自己的负载均衡算法。在负载均衡模式不可行,且必须在运行时根据一些变量选择服务器时,上述方法可能特别有用。BEA WebLogic Server MBeans支持您的应用程序访问运行企业应用程序的多功能环境。检索集群中单个节点的内存信息提供了获得统计数据的关键,而您的负载均衡策略需要这些数据作为基础。在使用RuntimeMBean提供的其他功能时,可能为上述示例添加额外的复杂性。这些可能就是收集关于集群节点的统计数据的管理工具的基础,也可能是执行维护活动的基础。


原创粉丝点击