内容


WebSphere 迁移

将 WebLogic 服务器和应用程序配置迁移到 WebSphere Application Server

Comments

系列内容:

此内容是该系列 # 部分中的第 # 部分: WebSphere 迁移

敬请期待该系列的后续内容。

此内容是该系列的一部分:WebSphere 迁移

敬请期待该系列的后续内容。

引言

本文旨在帮助您将 Java™ 2 Platform, Enterprise Edition (J2EE) 应用程序从 BEA WebLogic Server 迁移到 IBM WebSphere Application Server 平台。

在其他一些 developerWorks 文章(请参阅参考资料)中讨论了 WebLogic 迁移规划,包括开发环境、产品运行库、应用程序代码等的迁移。本文着重介绍 J2EE 应用程序中存在的两类配置,以对这些参考资料及其他资料进行补充。这两类配置分别是:

  • 服务器配置指的是不在应用程序文件中,但包含在开放源代码环境的域配置中的设置。要迁移服务器配置,需要将特定于 WebLogic 的资源(例如 JMS 连接工厂、JMS 队列、JMS 主题、JDBC 数据源、JavaMail 会话等)映射到 WebSphere Application Server 上的等价体。

  • 应用程序配置指的是企业存档 (EAR) 文件的应用程序目录结构中自包含的设置。要迁移应用程序配置,需要将特定于 WebLogic 的部署描述符映射到 WebSphere Application Server 上的等价体。

本文讨论的内容直接适用于将 J2EE 1.3(或更高版本)的应用程序从 WebLogic Server 7.0 和 8.1 迁移到 WebSphere Application Server V6.x。这里的大多数信息也适用于从早期版本的 WebLogic Server 迁移应用程序。

迁移服务器配置

迁移服务器配置实质上指的是将 WebLogic Server 上的位于应用程序文件外(但包含在域配置中)的设置移到 WebSphere Application Server 上。这些设置可以是 JMS 连接工厂和目的地、JDBC 数据源、J2EE 安全设置、邮件会话等等。

要迁移该配置,您必须知道需要迁移什么设置。然而,您很可能没有任何关于这些设置的文档或脚本(创建服务器配置可能要用到它们)可供参考。如果是这样,您需要登录到每个域中的 WebLogic 管理控制台来查找该设置,以确定需要在 WebSphere Application Server 环境中创建哪些设置。

但如果您无法(或没有权限)访问 WebLogic 管理控制台呢?

对于任何一种方式,收集 WebLogic 服务器配置信息的最有效方法就是检查 WebLogic 域配置文件 config.xml 和 WebLogic 启动脚本。WebLogic 管理员通常会向您提供这些文件的副本,因为查看这些副本文件不会影响任何正在运行的系统。

  • WebLogic config.xml 文件是 WebLogic 管理控制台存储所有资源定义的地方。没有恰当地映射这些资源可能导致应用程序失败。

  • 管理员通常创建一个自定义的启动脚本,然后向其添加系统属性、JVM 参数和类。没有将这些设置成功地迁移到新的环境中可能会对应用程序的性能和可伸缩性造成负面影响。最好对该启动脚本加以检查,不管是查看 config.xml 文件还是查看管理控制台。

在收集到此信息后,务必让开发人员和管理员检查您收集的信息。这是为了:

  • 确认您收集的信息所包含的设置最新且最准确。
  • 找出任何可以删除的死代码。

此外,还能保证您查看的是正确的 WebLogic 服务器配置;在开发过程中,J2EE 应用程序可能会安装在许多不同的运行时环境(开发、测试、QA 等)中,每个环境都会有略微不同的配置设置。因此,要确保所使用的 WebLogic 服务器配置是您打算使用的那个。同样地,当您在每个开发阶段安装应用程序时,请确保在每个相应的环境中映射了合适的服务器配置。

对于手头需要迁移的特定运行时配置设置,接下来的步骤是将它们提取出来并将信息插到 WebSphere Application Server 管理控制台中。虽然这是一个手动过程,但是一旦知道需要创建哪些设置,创建起来并不困难。使用 WebSphere Application Server 管理控制台来设置这些属性可以使您从修改 XML 文件或编写脚本中脱身出来。如果您愿意,也有指导操作可帮助您执行常见任务,例如创建数据源、启用 J2EE 应用程序安全性。一旦完成后,您可以编写脚本来自动创建服务器配置,特别是在生产环境中。

图 1 阐释了从 WebLogic 到 WebSphere Application Server 的服务器迁移。这里显示的设置并非只是服务器配置设置,而是涵盖您在此类迁移的过程中所看到的大多数设置。您看到的其他设置可能是与安全性和邮件会话相关的,但是从整体上讲,如果您可以处理图中所示的资源,您就离成功迁移服务器不远了。

图 1. 服务器配置迁移
图 1. 服务器配置迁移
图 1. 服务器配置迁移

迁移应用程序配置

迁移应用程序配置实质上指将包含在特定于 WebLogic 的部署描述符中的设置移到 WebSphere Application Server 中。这些设置包括从 EJB 组件到全局 JNDI 命令空间的映射、各种性能相关的设置(例如池大小)、事务的隔离级别、EJB 查询语言的扩展,等等。部署描述符描述了 J2EE 应用程序所需的执行环境,它有两种常规变体:

  • 行业标准部署描述符(图 2)是可移植的,通常不需要做任何更改,但 WebLogic 和 WebSphere Application Server 之间的一些区别值得一提。例如,IBM 的标准部署描述符使用 ID 来对标准描述符中的信息与特定于供应商的描述符中的信息进行关联,而 WebLogic 则使用 ejb-name 进行关联。因此,当您迁移 WebLogic 部署描述符并创建特定于 IBM 的描述符时,需要向其添加适当的 ID。您可以让您的组装工具(例如 IBM Rational® Application Developer)来为您创建这些 ID;如果您试图自己创建这些 ID,出错时解决这些错误会很棘手。

    图 2. 行业标准部署描述符
    图 2. 行业标准部署描述符
    图 2. 行业标准部署描述符
  • 特定于供应商的部署描述符(图 3)必须迁移。图 3 显示了特定于 WebLogic 的部署描述符和相应的特定于 WebSphere 的部署描述符。

    图 3. 特定于供应商的部署描述符
    图 3. 特定于供应商的部署描述符
    图 3. 特定于供应商的部署描述符

    IBM 提供了大量工具来帮助您将 WebLogic 部署描述符迁移到 WebSphere Application Server,包括:

    • Xdoclet 标记
    • WebSphere Rapid Deployment 标记
    • Application Server Toolkit(部署描述符编辑器)
    • IBM J2EE Competitive Migrator Plug-in for Rational Application Developer V6。

    请查看 Migrating Applications from WebLogic, JBoss and Tomcat to WebSphere V6 来了解这些工具的用途、使用方法和使用时机、如何获得帮助等。了解这些工具并在恰当时候使用它们是很重要的。虽然这些工具会映射特定于供应商的部署描述符中的一些扩展,但不会映射所有扩展,所以检查部署描述符并了解如何映射在其中发现的扩展是很重要的。了解这些内容后,使用组装工具(如 Application Server Toolkit)是十分有效的。

映射 config.xml 元素

本部分描述如何将这些服务器配置元素从 WebLogic 映射到 WebSphere Application Server:

  1. JMSConnectionFactory
  2. JMSFileStore
  3. JMSServer
  4. ForeignJMSServer
  5. JDBCConnectionPool 和 JDBCDataSource

有关每个元素的详细信息,请参阅 WebLogic Server Configuration Reference

  1. JMSConnectionFactory

    JMSConnectionFactory 元素创建连接工厂对象并将其绑定到 JNDI 命名空间。对于此应用程序,config.xml 文件中配置了三个连接工厂,每个连接工厂都启用了 XA:

    <JMSConnectionFactory 
          JNDIName="jms/Operations"
          Name="Operations" Targets="myserver" 
          XAConnectionFactoryEnabled="true"
    />
    
    <JMSConnectionFactory 
          JNDIName="jms/Mailing"
          Name="Mailing" Targets="myserver" 
          XAConnectionFactoryEnabled="true"
    />
    
    <JMSConnectionFactory 
          JNDIName="jms/Administration"
          Name="Administration" Targets="myserver" 
          XAConnectionFactoryEnabled="true"
    />

    为了将此配置映射到 WebSphere Application Server,您通常会在 WebSphere 缺省消息传递提供程序中创建 JMS 连接工厂,如上所示。其他一些预防措施包括:

    • 在 WebSphere Application Server 中配置这些 JMS 连接工厂时使用正确的 JNDIName。如果 JNDI 名称不正确,则应用程序将无法定位连接工厂。

    • 确认消息驱动 bean (MDB) 是否为事务型的,因为对于指定事务属性为 “NotSupport” 的非事务型 MDB,禁用 XA 会使性能有所提高。非事务型 MDB 不能参与 XA 事务,不需要已启用 XA 的连接工厂。另一方面,如果 MDB 指定事务属性为 “Required”,则应该为其 connection-factory-jndi-name 启用 XA。

    • 当您在 WebSphere Application Server 中创建连接工厂时,XA 缺省为启用。

  2. JMSFileStore

    JMSFileStore 元素定义了一个基于磁盘的 JMS 文件存储,它在文件系统目录中存储持久消息(用于队列)和永久订阅者(用于主题)。以下代码片段显示了单个 JMS 文件存储的定义:

    <JMSFileStore 
          Directory="/log//weblogic/wl-myserver/rmfilestore"
          Name="FileStoreMailing" SynchronousWritePolicy="Cache-Flush"
    />

    要将此配置映射到 WebSphere Application Server,首先需要知道 WebSphere Application Server V6.0 缺省消息传递机制并不支持 JMS 文件存储。该文件存储是 Version 6.1 中的一个增强功能,如果您使用 Version 6.0,则需要为消息传递引擎定义一个 JDBC 数据源。

  3. JMSServer

    JMSServer 元素定义了一个 JMS 服务器,它管理到其 JMS 目的地的连接和消息(使用 JMSQueue 或 JMSTopic 元素)。以下取自 config.xml 文件的代码片段显示了三个 JMS 服务器,每个服务器都包含两个 JMS 目的地,这里使用 JMS 队列:

    <JMSServer Name="JMSServerOperations" Targets="myserver">
          <JMSQueue CreationTime="1149493675734"
                JNDIName="jms/Queue/EntryOperations" 
                Name="EntryOperations"/>
          <JMSQueue CreationTime="1161679692974"
                JNDIName="jms/Queue/ExitOperations" 
                Name="ExitOperations"/>
    </JMSServer>
    
    <JMSServer Name="JMSServerMailing" Store="FileStoreMailing" Targets="myserver">
          <JMSQueue CreationTime="1161682828610"
                JNDIName="jms/Queue/RequestEntryMailing" 
                Name="RequestEntryMailing"/>
    <JMSQueue CreationTime="1161682915323"
          JNDIName="jms/Queue/RequestMailing" 
          Name="RequestMailing"/>
    </JMSServer>
    
    <JMSServer Name="JMSServerAdministration" Targets="myserver">
          <JMSQueue CreationTime="1161683412185"
                JNDIName="jms/Queue/EntryAdministration" 
                Name="EntryAdministration"/>
          <JMSQueue CreationTime="1161683429724"
                JNDIName="jms/Queue/ExitAdministration" 
                Name="ExitAdministration"/>
    </JMSServer>

    在此 WebLogic 配置中,只有其中一个 JMS 服务器 (JMSServerMailing) 使用文件存储。其他两个没有指定任何 JMS 存储,所以在这些 JMS 服务器中的队列不支持持久消息。

    除非应用程序显式设置目的地的传递模式(PERSISTENT 或 NON_PERSISTENT),否则 WebLogic config.xml 文件将指定消息是否是持久性的。因此,具有非空文件存储的 JMS 服务器到目的地的传递将使用持久传递模式,而没有文件存储的 JMS 服务器将使用非持久传递模式。

    要将此配置映射到 WebSphere Application Server,请对 JMSServerMailing JMS 服务器中定义的两个目的地使用持久消息传递机制,对其他所有目的地使用非持久传递模式。再次说明,在 WebSphere Application Server 中配置这些 JMS 队列时务必使用正确的 JNDIName。如果 JNDI 名称不正确,则客户机应用程序将无法定位 JMS 目的地。

  4. ForeignJMSServer

    ForeignJMSServer 元素定义了一个 JNDI 提供者,它位于 WebLogic JMS 服务器外,是 ForeignJMSConnectionFactory 和 ForeignJMSDestination 元素的父元素。总之,这些元素提供了使 WebLogic Server 能够连接到远程 JNDI 提供者的信息,以便客户机可以使用本地的 JNDI 名称来指向远程连接工厂和目的地对象。您在使用 WebSphere MQ 作为 JMS 提供者时将会经常看到这一点。以下取自 config.xml 文件的代码片段显示一个外部 JMS 服务器、一个外部 JMS 连接工厂和两个外部 JMS 目的地:

    <ForeignJMSServer ConnectionURL="file:/var/mqm/qmgrs"
          InitialContextFactory="com.sun.jndi.fscontext.RefFSContextFactory"
          JNDIProperties="" Name="JMSServerMailingMq" Targets="myserver">
          <ForeignJMSConnectionFactory
                LocalJNDIName="jms/MailingMq"
                Name="MailingMq" 
                RemoteJNDIName="MYSERVER"/>
          <ForeignJMSDestination
                LocalJNDIName="jms/Queue/RequestMailingMq"
                Name="RequestMailingMq" 
                RemoteJNDIName="J2EE_MVS_OFF_IN"/>
          <ForeignJMSDestination
                LocalJNDIName="jms/Queue/RespuestaMailingMq"
                Name="RespuestaMailingMq" 
                RemoteJNDIName="J2EE_MVS_OFF_OU"/>
    </ForeignJMSServer>

    此配置中的外部服务器、连接工厂和目的地将映射到 WebSphere MQ JMS 提供者。正确配置 LocalJNDINames 和 RemoteJNDINames 是很重要的。

  5. JDBCConnectionPool 和 JDBCDataSource

    JDBCConnectionPool 和 JDBCTxDataSource 元素定义了 JDBC 资源的配置。以下取自 config.xml 文件的代码片段显示了单个连接工厂和数据源的配置:

    <JDBCConnectionPool DriverName="oracle.jdbc.driver.OracleDriver"
                        Name="MyJDBCConnectionPool"
                        PasswordEncrypted="{3DES}B2Bl+tp70Eh3D1pT53/anw=="
                        Properties="user=wles" Targets="myserver"
                         URL="jdbc:oracle:thin:@localhost:1521:ASI"
                         InitialCapacity="25" MaxCapacity="125"
                         TestTableName="SQL SELECT 1 FROM DUAL"/>
      <JDBCTxDataSource JNDIName="jdbc/MyDataSource"
                        Name="MyJDBCDataSourceName"
                        PoolName="MyJDBCConnectionPool"
                         Targets="myserver"/>

    在此代码中:

    • JDBCConnectionPool 元素定义了当对数据源调用 getConnection 时从连接池中返回的属性连接。

    • JDBCTxDataSource 元素定义了一个启用事务的 JDBC 数据源,并指定绑定数据源的 JNDI 名称和与此数据源相关联的连接池。

    映射连接池和数据源到 WebSphere Application Server,需要配置 JDBC 提供者、JDBC 数据源和 JCA 身份验证数据项。其中最重要的元素是 JNDIName、DriverName、URL、PasswordEncrypted 和 Properties。(您需要从数据库管理员那里获得密码,因为它在 config.xml 文件中是加密的。)

    要映射 TestTableName 属性,请使用名称为 PreTest SQL 字符串的 WebSphere 属性,在这里您可以设置一条 SQL 语句来测试每个 JDBC 连接。您还可以设置连接的重试时间间隔。

    您还应该根据“InitialCapacity”和“MaxCapacity”元素配置池大小。在缺省情况下,WebSphere Application Server 连接池最少为一个连接,最多为十个连接。WebLogic 连接池配置为初始有 25 个连接,所以您需要配置 WebSphere 池大小。要完成此任务,请执行以下操作:

    1. 打开 WebSphere Application Server 管理控制台,选择 Resources => JDBC Providers
    2. 选择提供者的名称。
    3. 选择 Additional Properties 下的 Data Sources 项。
    4. 单击数据源的名称。
    5. 选择 Connection pool properties
    6. 使用 minimum and maximum connection 字段来配置池大小。

还有其他一些特定于 WebLogic 的属性可以用来配置 JDBC 资源,但以上列出的属性是最常碰到的。

映射 WebLogic 启动脚本

本部分描述如何将这些服务器配置元素从 WebLogic 映射到 WebSphere Application Server:

  1. JVM 参数
  2. 系统参数
  3. 类路径

有关 WebLogic 配置元素的更多信息,请参阅参考资料

  1. JVM 参数

    在自定义的启动脚本中指定 JVM 参数是很常见的 WebLogic 实践。请确保您获得了正确环境的正确启动脚本。下面是正在使用的 Sun™ JVM 选项的一个示例:

    -server -Xms1024m -Xmx1024m 
    -verbose:gc -Xloggc:wls-gc.log  -XX:+PrintGCDetails -XX:+PrintGCTimeStamps 
    -XX:ParallelGCThreads=8 -XX:PermSize=128m -XX:MaxPermSize=128m

    假设您运行 WebSphere Application Server 所在的 JVM 正是针对 WebLogic 进行调整的那个 JVM,则以上扩展应该是针对 WebSphere Application Server 调整 JVM 的一个良好起点,但您可能会根据负载测试进行调整。要将这些 JVM 参数添加到 WebSphere Application Server,请执行以下操作:

    1. 从管理控制台中选择 Servers => Application Servers -=> server_name => Process Definition => Java Virtual Machine
    2. 选中 Verbose Garbage Collection(要记得将其关闭)。
    3. 将 Initial Heap Size 设置为 1024
    4. 将 Maximum Heap Size 设置为 1024
    5. 添加 -server,作为 Generic JVM 参数框中的第一个参数,然后在现有的其他参数后面添加以下参数:
      -XX:ParallelGCThreads=8 
      -XX:PermSize=128m 
      -XX:MaxPermSize=128m
      -Xloggc:wls-gc.log  
      -XX:+PrintGCDetails 
      -XX:+PrintGCTimeStamps

    牢记以下事项:

    • 详细垃圾回收是通过 -verbose:gc 选项启用的。在负载测试过程中收集垃圾回收统计数据是很有帮助的,但大大小小的每次回收都会被记录下来,所以请记住在运行最终的基准之前要禁用详细垃圾回收。

    • 类垃圾回收在缺省情况下是启用的,它负责删除不再拥有任何活动实例的类。类垃圾回收在其他 WebLogic 迁移中带来了性能和可伸缩性的问题,所以请通过添加此 JVM 参数来禁用它:

      -Xnoclassgc

    有关调整 Sun 和其他 JVM 的更多信息,请参阅 Tuning Java virtual machines

  2. 系统参数

    在 WebLogic 启动脚本中指定的所有 -D 参数都应该映射到 WebSphere Application Server。没有成功映射系统参数非常有可能导致迁移问题。要将系统参数映射到 WebSphere Application Server ,请执行以下操作:

    1. 从管理控制台中选择 Application servers => server_name => Process Definition => Java Virtual Machine
    2. 在这个示例中,启动脚本中有一个参数用于启用缓存,另一个参数用于指定 log4j 配置文件的位置。您应该将这些参数添加到 Generic JVM arguments 框中现有的所有 JVM 参数后面:
      -Dtangosol.coherence.distributed.localstorage=true 
      -Dlog4j.configuration=file:///myprojects/config/log4j.xml
  3. 类路径

    您经常会发现启动脚本中 WebLogic 类路径被修改。添加没有包含在企业存档中的 JAR,或者添加用于增加目录以便搜索应用程序所加载的配置文件的 JAR,都有可能修改类路径。在每种情况下,要映射它们,请执行以下操作:

    1. 从管理控制台中选择 Application servers => server_name => Process Definition => Java Virtual Machine
    2. 在这个示例中,WebLogic 启动脚本添加了一个目录到类路径中,所以您也要将它添加到 WebSphere Application Server 类路径中。将此文件夹添加到 Classpath 框中:

      C:\myprojects

      向类路径添加 JAR 时要十分谨慎,只有在您确定它们没有包含在 WebSphere Application Server 分发中时才可以这样做。

映射 weblogic-ejb-jar 元素

本部分描述如何将这些服务器配置元素从 WebLogic 映射到 WebSphere Application Server:

  1. jndi-name
  2. local-jndi-name
  3. max-beans-in-free-pool 和 initial-beans-in-free-pool
  4. max-beans-in-cache 和 idle-timeout-seconds
  5. trans-timeout-seconds
  6. concurrency-strategy
  7. enable-call-by-reference
  8. cache-between-transactions
  9. delay-updates-until-end-of-tx
  10. finders-load-bean
  11. resource-description
  12. resource-env-description

有关 WebLogic 配置元素的更多信息,请参阅参考资料

  1. jndi-name

    jndi-name 元素在全局 JNDI 命名空间中指定EJB 的 JNDI 名称。要在 WebSphere Application Server 中设置 EJB 的 JNDI 名称,您需要知道 EJB 项目和正确的 EJB。要找到它们,请搜索 weblogic-ejb-jar 文件中的此元素:

    <jndi-name>

    要将 jndi-name 元素映射到 WebSphere Application Server,请执行以下操作:

    1. 启动组装工具,并打开 EJB 项目。
    2. 如果您使用的是 Rational Application Developer,请双击部署描述符。
    3. 单击适当的 EJB 组件。
    4. 向下滚动到 WebSphere Bindings 部分,键入该 bean 的 JNDI 名称。
  2. local-jndi-name

    local-jndi-name 元素在全局 JNDI 命名空间中定义 bean 本地 home 的 JNDI 名称。也就是说,WebLogic 提供了一种在全局 JNDI 命名空间中指定本地 home 的 JNDI 名称的方式——但这样做使得远程客户机可以查找全局 JNDI 命名空间中的本地接口,这样会导致运行时错误,因为本地 home 必须在与客户机相同的容器中配置。现在,在进入 WebSphere 之前,请先了解一下 JNDI 的一些背景:

    • J2EE 规范并没有规定将 EJB 映射到全局 JNDI 命名空间中。而是留给供应商自己规定。因此,大多数供应商在他们自己的特定部署中包含了一个元素,用于在全局 JNDI 命名空间中指定远程 EJB JNDI 名称。

    • 然而,根据定义,本地 home 接口只能由本地容器访问,所以供应商不需要将它们绑定到全局 JNDI 命名空间中。虽然客户机模块可能使用 JNDI 查找本地 home,但容器不需要在 JNDI 命名空间中公开它们。相反,作为查找的一部分,客户机模块应该定义对 EJB 的 JNDI 引用,并在本地命名空间中使用 java:comp/env 来访问。

    • 建议您使用 JNDI 引用来访问本地命名空间中的 EJB,而不要使用 JNDI 名称来直接访问全局命名空间中的 EJB。使用 JNDI 引用可以杜绝客户机模块更改全局 JNDI 命名空间,这在支持同一 EJB 的多版本时是必需的。也就是说,使用相同 JNDI 引用的客户机模块可以绑定到新版本的 EJB 上而不需要修改任何源代码;客户机模块只是绑定其 JNDI 引用以指向不同的 EJB。

    了解了这些背景之后,如何将 local-jndi-name 元素映射到 WebSphere Application Server 呢?

    首先,需要知道 WebSphere Application Server 并没有提供为本地 home 定义 JNDI 名称的方式。相反,必须使用本地命名空间中的 JNDI 引用来访问本地 bean——而不是全局命名空间中的 JNDI 名称。

    遗憾的是,一些 WebLogic 应用程序使用 JNDI 名称在全局 JNDI 命名空间中直接引用本地对象,而不是使用本地 JNDI 命名空间中的 JNDI 引用来间接引用它们。因此,必须对这些应用程序的代码进行一些更改。一些能够将 local-jndi-name 元素映射到 WebSphere Application Server 的方法是不受支持或者不实用的。但有一种方法可以使用,那就是向调用者模块添加本地 JNDI 引用(这是查找本地 home 的标准方式),然后在所有 JNDI 查找中使用 java:comp/env 前缀。不管访问 EJB 还是其他资源(例如 JMS 连接工厂),这种方式都是行业认可的最佳实践,所以它是您在这里应该使用的解决方案。

  3. max-beans-in-free-pool 和 initial-beans-in-free-pool

    max-beans-in-free-pool 元素定义了特定实体 bean、无状态会话 bean 或消息驱动 bean 的 EJB 空闲池的最大大小。每个 bean 类都可以使用此元素来定义自己的空闲池的大小。

    initial-beans-in-free-pool 元素定义了在启动时为特定 bean 类填充空闲池的 bean 实例的初始大小。用实例来填充空闲池可以提高初始响应时间,因为对该 bean 的初始请求不用生成新的实例即可得到满足。

    在 WebLogic 中,应用程序中的每个 bean 都可以指定最大的和初始的池大小,而不同的 bean 类的池大小会有很大的不同。要确定具体的池大小,请查看 weblogic-ejb-jar.xml 文件中的以下元素之一:

    <initial-beans-in-free-pool>
    <max-beans-in-free-pool>

    要在 WebSphere Application Server 中指定 EJB 池大小,可以在 JVM 中添加一个系统参数:

    1. 从管理控制台中选择 Application servers => server name => Process Definition => Java Virtual Machine
    2. 将 com.ibm.websphere.ejbcontainer.poolSize 添加到 Generic JVM 参数框现有的所有 JVM 参数后面。这里是一个示例,它对名为 RuleEngineEJB 的 bean 设置了池大小最小为 1,最大为 5:
      -Dcom.ibm.websphere.ejbcontainer.poolSize
      =myapp#RulesEngine.jar#example.RulesEngineEJB=1,5

    有关其他详细信息,请参阅 WebSphere EJB Container Tuning

    虽然您可以映射池大小范围,但是应用程序服务器看待空闲池的方式是不同的:

    • 如果池是空的,WebLogic 将不会创建另一个实例;对新 bean 的请求只能等待,直到现有的 bean 返回到池中。如果池大小的分配不正确,这种策略可能导致死锁的情况,但是它控制了活动对象的数量,所以可能会对可伸缩性有所帮助。
    • 如果池是空的,WebSphere Application Server 将创建新的实例(而不是让请求在那等待)。在该请求使用新的实例后,WebSphere Application Server 只有在池中没有 maxSize bean 时才会将它返回到池中。(WebSphere Application Server 中的缺省池大小是最小 50,最大500。)

    注意这些区别是很重要的,因为在特定的情况下,如果负载过大而导致 bean 池被耗尽、对象创建成本太高或者消耗太多资源,则这些区别会导致 WebSphere Application Server 出现性能和可伸缩性问题。例如,考虑这种情况:

    • 一个应用程序实现了一个创建成本非常高的会话 bean。这种会话 bean 的一个例子是向在堆中缓存其规则基础(可能有几百兆数据)的规则引擎提供接口的会话 bean。

    • 由于这种 bean 创建成本太高,并且消耗堆中太多的可用空间,所以应用程序限定空闲池中 bean 的最大数目为 5,实际上也就限定了任何给定时间下此类 bean 不超过 5 个。

    • 应用程序限定活动 bean 的数目是因为在负载过大的情况下,与频繁创建/销毁额外会话 bean 相比,通过 5 个活动会话 bean 实例为所有获得此“规则服务”的传入请求提供服务更加理想(从可伸缩性的角度看)。

    现在,您已将最小为 1,最大为 5 的池大小映射到 WebSphere Application Server。这种映射能够工作得很好,因为它的确将池大小限制在 5 之内,同时又没有将活动实例的数目限制为 5。如果有五个请求将这五个会话 bean 全部占用,则池将为空,但如果有第六个请求到来,并获得其中一个会话 bean,则会创建并使用第六个会话对象——只是不返回到池中。在 WebLogic 中,获得第六个会话对象的请求将不得不等待其中一个活动 bean 返回到池中才能得到服务。

    正如您所看到的,池大小的这种直接映射会导致创建额外的会话 bean,在负载过大的情况下,这种创建和销毁额外 bean 的做法会带来可伸缩性问题。如果应用程序要求对活动 bean 的数目进行硬性限制,则 bean 将需要跟踪空闲池中 bean 的数量,如果没有可用的,就得等待活动 bean 完成。

    从本示例中可以了解到重要的一点是,在负载测试过程中,应该关注活动 bean 的最大数目以确保它们不会超出池的最大大小。如果超出,则需要将池的大小调大一些,以避免频繁创建和销毁对象;或者是对活动 bean 的数目进行硬性限制。

  4. max-beans-in-cache 和 idle-timeout-seconds

    max-beans-in-cache 元素控制在任何给定时间都是活动状态的类对象的最大数目。当达到 max-bean-in-cache 的值时,WebLogic 将钝化一些最近没有被客户机使用的 EJB。

    idle-timeout-seconds 元素指定 bean 驻留缓存中的最长时间。当超过这个时间时,如果缓存中 bean 的数目接近 max-beans-in-cache,则容器就会删除该 bean。(在 WebLogic 8.1 SP4 之前此元素被忽略。)

    在 WebLogic 中,您可以定义各个 bean 类的缓存。内存中的对象因类而异,空闲超时时间也因类而异。要查找自定义的缓存,请搜索 weblogic-ebj-jar.xml 中的以下元素之一:

    <max-beans-in-cache>
    <idle-timeout-seconds>

    在 WebSphere Application Server 中,您无法指定每个 bean 类的缓存大小或空闲超时时间(在 WebSphere Application Server 中称为清理间隔),但您可以指定在整个 EJB 容器中处于活动状态的实例的缓存大小和清理间隔。

    WebSphere Application Server 中的缓存大小类似于 max-beans-in-cache。它指定 EJB 容器内活动实例列表中的 bucket 数目。虽然一个 bucket 可以包含多个实例,但当活动实例的数目超过 bucket 数目(缓存大小)时,容器就会尝试通过将它们钝化到磁盘的方式来删除一些实例。因此,在典型的工作负载过程中,如果将缓存大小设置为预期的最大活动实例数,则性能是最佳的。

    WebSphere Application Server 中的清理间隔类似于 idle-timeout-seconds。它指定容器每隔多长时间尝试将不使用的项从缓存中删除以将总项数减少到缓存大小。

    如果您遇到根据逐类原则调整 WebLogic 缓存大小的应用程序,则在调整 WebSphere EJB 缓存大小时应该将这些缓存大小考虑在内。有一个算法可以用来调整容器的 EJB 缓存大小,它根据不同类型的 bean 来计算平均 EJB 缓存需求。

    如果应用程序中有大量实体 bean,则应该及时使用 max-beans-in-cache 元素的值来计算任何实例上的活动在容器中的 EJB 的预期最大值,并监控负载测试过程中的缓存以确保没有出现缓存溢出;也就是说,确保没有大量 ejbStore 被调用。这个操作是很重要的,因为 WebSphere Application Server 中缺省的最大缓存大小只有区区几千,而大量使用实体 bean 的应用程序可能已经指定的池大小就有几千。

  5. trans-timeout-seconds

    trans-timeout-seconds 元素指定 EJB 的容器启动事务的最大持续时间。如果一个事务的持续时间超过 trans-timeout-seconds,则 WebLogic EJB 容器将回滚该事务。您可以通过搜索所有 weblogic-ejb-jar.xml 文件中的如下元素来查看此扩展:

    <trans-timeout-seconds>

    WebSphere Application Server 提供了两种设置事务超时时间的方式。

    选项 1:如果所有 bean 都将事务超时时间设置为相同的值,则可以使用管理控制台来设置 WebSphere 事务服务中的最大事务超时时间。

    1. 从管理控制台中选择 Servers => Application servers => server_name => Container Services => Transaction Service
    2. 将整个事务生命周期的超时时间设置为 30

    选项 2:可以在部署描述符中为 bean 设置事务超时时间。要设置事务超时时间,请执行以下操作:

    1. 在 Rational Application Developer 中,对于每个 EJB 对象,双击其部署描述符。
    2. 双击具体的 bean 来设置事务超时时间。
    3. 将组件事务超时时间设置为 30

    一般建议更改每个 bean 的部署描述符,而不是所有 bean 的事务服务。更改所有 bean 的事务超时时间会影响在容器中运行的所有应用程序。但如果应用程序对所有 bean 设置的事务超时时间都一样,并且在容器中只有该应用程序在运行,则在 WebSphere Application Server 事务服务中设置一次值比在每个 bean 中都设置值要简单。如果不是这种情况,则应该对每个 bean 都设置事务超时时间。

  6. concurrency-strategy

    concurrency-strategy 元素指定容器应该如何管理对实体 bean 的并发访问。WebLogic 支持四个不同的并发策略:

    • Exclusive 并发策略使得当一个 bean 与一个事务相关联时,WebLogic Server 会在缓存的实体 EJB 实例上放置一个排他锁。对该 EJB 实例的其他请求将被阻塞,直到该事务完成为止。

      要查找使用 Exclusive 并发策略的 bean,请搜索 weblogic-ejb-jar.xml 文件中的以下元素:

      <concurrency-strategy>Exclusive</concurrency-strategy>

      当找到这些 bean 时,请注意它们的 EJB 项目和 EJB 名称,您需要将它们映射到 WebSphere Application Server:

      1. 在 Rational Application Developer 中,打开 EJB 项目。
      2. 双击部署描述符。
      3. 双击合适的 Java bean。
      4. 向下滚动到 Bean Cache 部分。
      5. 将 Activate at 设置为 ONCE
      6. 将 Load at 设置为 ACTIVATION

      这些参数避免了调用 ejbLoad 函数,但会将对 bean 实例的访问序列化。此选项由于在缓存中维护持久状态,所以增加了内存利用率,但如果 bean 实例一般情况下不并发访问,则可以提供更快的响应时间。此选项在 EJB 规范中称为缓存选项 A。

    • ReadOnly 并发策略用于只读的实体 bean。它对每个事务激活一个新实例以便并发处理请求。WebLogic Server 在调用 ejbLoad() 处理 ReadOnly bean 时是基于“read-timeout-seconds”元素的。

      read-timeout-seconds 元素指定对只读实体 bean 的 ejbLoad() 调用之间的间隔秒数。它只适用于采用 ReadOnly 并发策略的 bean。read-timeout-seconds 值为 0 表明只读 bean 不从数据库重新加载。

      要查找只读 bean,请搜索 weblogic-ejb-jar.xml 文件中的以下元素:

      <concurrency-strategy>ReadOnly</concurrency-strategy>

      再次说明,一定要注意 EJB 项目和 EJB 名称,以便在 WebSphere Application Server 中将它们标记为只读 bean。

      1. 在 Rational Application Developer 中,打开 EJB 项目。
      2. 双击部署描述符。
      3. 双击适当的 Java bean。
      4. 向下滚动到 Bean Cache 部分。
      5. 将 Activate at 设置为 ONCE
      6. 将 Load at 设置为 INTERVAL
      7. 将重新加载时间间隔设置为适当的分钟数。(例如,如果 WebLogic <read-timeout-seconds> 元素设置为 600 秒,则对于 WebSphere Application Server,将重新加载时间间隔设置为 10 分钟。)

      如果在 WebLogic 中将 <read-timeout-seconds> 设置为 0,则只有在实例首次进入缓存时才会调用 ejbLoad。在 WebSphere Application Server 中,重新加载时间间隔值为 0 也会使容器永远不会重新加载 bean。

      (有关在 WebSphere Application Server 中开发只读 bean 的更多信息,请参阅参考资料。)

    • Database 并发策略可以使 WebLogic Server 将对实体 bean 的锁定请求委派给基础数据存储库。通过此策略,WebLogic Server 分配独立的实体 bean 实例并启用锁定和缓存来由数据库进行处理。这是缺省选项。

      WebLogic Database 并发策略意味着 bean 在事务开始时激活且添加到缓存中,并在事务结束时钝化且从缓存中删除。

      要查找使用 Database 并发策略的 EJB 组件和对象,请搜索 weblogic-ejb-jar.xml 文件中的以下元素:

      <concurrency-strategy>Database</concurrency-strategy>

      再次说明,注意 EJB 项目和 EJB 名称。要将 Database 并发策略映射到 WebSphere Application Server,请执行以下操作:

      1. 在 Rational Application Developer 中,打开 EJB 项目。
      2. 双击部署描述符。
      3. 双击适当的 Java bean。
      4. 向下滚动到 Bean Cache 部分。
      5. 将 Activate at 设置为 TRANSACTION
      6. 将 Load at 设置为 TRANSACTION

      WebSphere Application Server V6.0 bean 缓存的缺省值是 Activate at:transaction 和 Load at:transactions——因为这是缺省值,所以不必对想要应用 Database 并发策略的每个 bean 显式设置该值。此策略在 EJB 规范中称为缓存选项 C。

    • Optimistic 并发策略在事务期间不在 EJB 容器或数据库中持有任何锁。EJB 容器在事务提交之前确认由该事务更新的数据有无更改。如果事务更新的任何数据被更改了,则 EJB 容器将回滚该事务。

      要查找支持 Optimistic 并发控制的 bean,请搜索 weblogic-ejb-jar.xml 文件中的此元素:

      <concurrency-strategy>Optimistic</concurrency-strategy>

      请注意 EJB 项目和 EJB 名称。迁移数据库并发策略需要用到这些值。

      一旦您找到这些 bean,并且注意到其名称及其 EJB 项目的名称,则搜索 weblogic-cmp-rdbms-jar.xml 中的 <verify-columns> 元素;表中的这几列是您在提交数据库之前需要验证的,以确保没有其他事务修改过数据。

      现在您可以开始在 WebSphere Application Server 中配置 Optimistic 并发。

      1. 首先,在部署描述符中启用乐观锁定:

        1. 在 Rational Application Developer 中,打开 EJB 项目。
        2. 双击部署描述符。
        3. 选择 Access 选项卡。
        4. 从 Access Intent for Entities 2.x (Bean Level) 中,选择 EJB 并单击 Add 按钮。
        5. 选择 wsOptimisticUpdate 作为 Access Intent 名称,并单击 Finish 按钮。
      2. 接下来,指定在提交已修改数据时需要包含到严格限定的 Update 语句中的字段。要做到这一点,您应该拥有为从 EJB 到 DDB 的映射而定义的数据库映射。当这一步完成时:

        1. 右键单击 EJB 项目。
        2. 选择 EJB to RDB Mapping => Generate Map
        3. 在 Overview 部分的 Enterprise Beans 面板中,选择 CMP 字段,它应该作为乐观谓词包含到严格限定的 SQL Update 语句中。
        4. 在 Properties 视图中,为 OptimisticPredicate 选择 True
  7. enable-call-by-reference

    enable-call-by-reference 元素通常用于按引用传递参数,而不是按值传递,后者需要对参数做复制。当 enable-call-by-reference 为 True 时,从同一 EAR 文件或独立 JAR 文件调用 EJB 方法将按引用传递参数,这种方式提高了方法调用性能,因为不需要复制参数。

    在 WebLogic 中,您可以逐个 bean 启用按引用调用,而在 WebSphere Application Server 中,只能在容器级别启用按引用调用。因此,如果启用了按引用传递,则它将应用到应用程序中的所有远程接口,而不只是其中一个子集。

    要在 WebSphere Application Server 中启用按引用调用,请执行以下操作:

    1. 从管理控制台中选择 Servers => Application servers => server_name => Container services => ORB Services
    2. 选中 Pass by reference
  8. cache-between-transactions

    cache-between-transactions 元素指定是否在事务间缓存实体 bean 的持久状态。选择 True 则启用在事务间缓存持久状态;选择 False(缺省)则不在事务间缓存持久状态。

    是否可以在事务间缓存取决于并发策略:

    • 如果并发策略是 ReadOnly,则始终会在事务间缓存持久状态。
    • 如果并发策略是 Database,则始终不会在事务间缓存持久状态。

    因此,如果实体使用 ReadOnly 或 Database 并发策略,则对于那些 bean,EJB 容器实际上会忽略 cache-between-tansactions 元素。

    在 WebSphere Application Server 中,不需要映射 cache-between-transactions 元素,因为 WebSphere Application Server 对只读 bean 的实现始终会在事务间缓存持久状态,而 Database 并发策略的实现始终不缓存持久状态。这与 WebLogic 中的行为是一样的。

  9. delay-updates-until-end-of-tx

    delay-updates-until-end-of-tx 元素缺省为 True,在这种情况下,当事务完成时会更新事务中所有 bean 的持久存储。这与在事务结束时才批处理所有数据库操作是一致的,它也是 WebLogic 的缺省做法。如果您将此元素设置为 False,则每次调用 CMP EJB 设置方法时都会将更新写到数据库中。通常来说,将其设置为 True 会提高性能,但这样做无法在数据库事务中保持数据库更新的顺序。

    在 WebLogic 应用程序中,您可能会发现一些 bean 将 delay-updates-until-end-of-tx 设置为 False。这样可能覆盖将所有数据库操作延迟到事务结束时的缺省 WebLogic 设置。要查找禁用将更新延迟到事务结束时的 bean,请搜索 weblogic-ejb-jar.xml 文件中的此元素:

    <delay-updates-until-end-of-tx>false</delay-updates-until-end-of-tx>

    在 WebSphere Application Server 中,缺省做法是每次调用 CMP mutator 时都执行数据库操作,而不是将它们延迟到事务结束时。在 WebSphere Application Server 中,您可以将更新延迟到事务结束以获得性能的优化,但是您只能对容器中的所有 bean 打开或关闭该选项。

    当您将更新延迟到事务结束时,通常都会获得性能的提升;但批处理操作执行更新的顺序与它们在代码中的执行顺序不一致。有关其他考虑事项,请参考 enable-batch-operationsorder-database-operations

  10. finders-load-bean

    finders-load-bean 元素决定了在 finder 方法调用返回给 bean 一个引用后,WebLogic Server 是否将该 EJB 加载到缓存中。如果您将此元素设置为 True(缺省值),并且 finder 返回给 bean 一个引用,则 WebLogic Server 会立即将该 bean 加载到缓存中。如果您将此元素设置为 False,在第一次方法调用之前,WebLogic Server 都不会自动将 bean 加载到缓存中。

    在 WebSphere Application Server 中,缺省做法是在 finder 被调用时将 bean 加载到缓存中,因为此行为与 CMP 2.0 规范一致。如果您想更改此行为,以将加载 bean 到缓存的操作延迟到第一个方法被调用之后,则可以定义包含这些 EJB 的 EJB JAR 来实现 EJB1.1 规范,因为这种行为与该规范是一致的。

  11. resource-description

    resource-description 元素将 ejb-jar.xml 中定义的 <resource-ref> 映射到实际资源的 JNDI 名称。ejb-jar.xml 文件中定义的 <resource-ref> 元素的典型例子是 JDBC 数据源和 JMS 连接工厂。您可以在 WebLogic config.xml 文件中找到这些资源实际的 JNDI 名称。

    使用 <resource-description> 元素可以使客户机将资源的逻辑名称与资源实际的 JNDI 名称绑定在一起。客户机使用本地命名空间中的逻辑 JNDI 引用(例如 java:comp/env/<res-ref-name>)来查找资源,而不是使用实际的 JNDI 名称(例如 <jndi-name>),这样可以避免客户机更改 JNDI 名称。

    在 WebLogic 中,资源到 JNDI 名称的映射是在 weblogic-ejb-jar.xml 文件中指定的,例如:

    <resource-description>
          <res-ref-name>jms/Mailing</res-ref-name>
          <jndi-name>jms/Mailing</jndi-name>
    </resource-description>

    在 WebSphere Application Server 中,资源到 JNDI 名称的映射是使用组装工具指定的:

    1. 在 Rational Application Developer 中,打开适当的 EJB 项目;例如:ShippingAutoserviceEJB
    2. 双击部署描述符。
    3. 单击 References 选项卡。
    4. 展开正确的 Java Bean(例如 ShipmentManager)来查看所有的 JNDI 资源引用。您需要为每个引用指定一个 JNDI 名称。选择其中一个引用,例如 jms/MailingMq。(WebLogic 将从 <resource-ref> 到 JNDI 名称的映射与从 <resource-env-ref> 到 JNDI 名称的映射视为不同(请参考下一部分),但 WebSphere Application Server 将这二者视为等同的。因此,当您展开 Java bean 时,您将在 ejb-jar.xml 文件中看到为该 bean 定义的所有 <resource-ref> 和 <resource-env-ref>。)
    5. 向下滚动到 WebSphere Bindings 部分,为资源(在 WebLogic config.xml 文件中找到的)键入正确的 JNDI 名称。
    6. 对每个 <resource-ref>(和每个 <resource-env-ref>,如果需要)重复步骤 4-5。
  12. resource-env-description

    resource-env-description 元素将 ejb-jar.xml 中定义的 <resource-env-ref> 映射到实际资源的 JNDI 名称。ejb-jar.xml 文件中定义的 <resource-env-ref> 的典型示例是受管理对象,例如 JMS 目的地。您可以在 WebLogic config.xml 文件中找到这些资源的实际 JNDI 名称。

    使用 <resource-env-description> 元素可以使客户机将资源的逻辑名称与实际的 JNDI 名称绑定起来。客户机使用逻辑 JNDI 引用(例如 java:comp/env/<res-ref-name>)来查找资源,而不是使用实际的 JNDI 名称(例如 java:<jndi-name>),这样可以避免客户机更改 JNDI 名称。

    在 WebLogic 中,资源到 JNDI 名称的映射是在 weblogic-ejb-jar.xml 文件中指定的,例如:

    <resource-env-description>
            <res-env-ref-name>jms/Queue/RequestMailingMq</res-env-ref-name>
            <jndi-name>jms/Queue/RequestMailingMq</jndi-name>
    </resource-env-description>

    在 WebSphere Application Server 中,资源到 JNDI 名称的映射是使用组装工具指定的:

    1. 在 Rational Application Developer 中,打开 EJB 项目;例如:ShippingAutoserviceEJB
    2. 双击部署描述符。
    3. 单击 References 选项卡。
    4. 展开 Java bean(例如 ShipmentManager)来查看所有的 JNDI 资源引用。您需要为每个引用指定一个 JNDI 名称。选择其中一个引用,例如 jms/Queue/RequestMailingMq。正如前面部分提到的,WebLogic 将从 <resource-env-ref> 到 JNDI 名称的映射与从 <resource-ref> 到 JNDI 名称的映射视为不同,但 WebSphere Application Server 将这二者视为等同的。因此,当您展开正确的 Java bean 时,您将看到为该 bean 定义的所有 <resource-ref> 和 <resource-env-ref>。
    5. 向下滚动到 WebSphere Bindings 部分并键入该资源的 JNDI 名称
    6. 对每个 <resource-env-ref>(和 resource-ref>,如果需要)重复步骤 4-5。

映射 weblogic-cmp-rdbms-jar 元素

本部分描述如何将这些元素从 WebLogic 映射到 WebSphere Applicatioin Server:

  1. use-select-for-update
  2. enable-batch-operations
  3. order-database-operations
  4. weblogic-ql
  5. max-elements

有关 WebLogic 配置元素的更多信息,请参阅参考资料

  1. use-select-for-update

    use-select-for-update 元素对每个 bean 强制执行悲观并发。选择 True 会使只要从数据库加载 bean,就会使用 select for update 扩展,并在事务持续过程中维持锁定。使用此 WebLogic 扩展会使当第一个事务正在运行时,另一个事务读取或更新数据成为可能。此扩展用维持更长时间的锁定来减少并发的代价提高数据完整性和减少死锁。

    要查找使用 select for update 扩展的 EJB,请搜索 weblogic-cmp-rdbms-jar.xml 文件中的此元素,要注意用到该元素的 EJB 项目和 EJB 名称。

    <use-select-for-update>

    要将 <use-select-for-update> 元素映射到 WebSphere Application Server,请执行以下操作:

    1. 在 Rational Application Developer 中,打开 EJB 项目。
    2. 双击部署描述符。
    3. 选择 Access 选项卡。
    4. 在 Access Intent for Entities 2.x (Bean Level) 部分,选择 Java beans 并单击 Add 按钮。
    5. 选择 wsPessimisticUpdate 作为 Access Intent 名称并单击 Finish 按钮。

    如果您设置访问目的为 wsPessimisticUpdate,则容器将始终使用 select for update,这可能带来性能问题,但会消除死锁。因此,在您有能力运行负载测试来确定是否有数据完整性、死锁或性能问题之前,请保留缺省访问目的策略不变。如果条件具备,请按照以上步骤设置访问目的。

  2. enable-batch-operations

    enable-batch-operations 元素控制 EJB 容器是否启用批处理数据库操作,包括批插入、批更新和批删除。如果启用,则 EJB 容器会将数据库操作延迟到事务提交时处理。

    缺省情况下 WebLogic 将对实体 bean 启用批处理操作,直到被显式关闭为止,您可以通过禁用 order-database-operations 和 enable-batch-operations 元素来关闭批处理操作(请参考下一部分)。要查找这些扩展,请搜索 weblogic-cmp-rdbms-jar.xml 文件中的以下元素:

    <enable-batch-operations>false</enable-batch-operations>

    再次说明,在 WebLogic 中,批处理操作缺省情况下是启用的,并且可以在 JAR 级禁用,即对 JAR 中的所有 CMP 实体 bean 禁用批处理操作。而在 WebSphere Application Server 中,批处理操作缺省情况下是禁用的,并且可以在 EJB 容器级启用,即对容器中的所有 CMP 启用批处理操作。

    由于这种扩展是孤注一掷的,所以您需要决定是否对所有 CMP 实体启用批处理操作。如果觉得存在性能问题并可以通过批处理操作来解决,您可以在开始时采用缺省设置(不启用批处理操作),然后再更改此设置。

    要在 WebSphere Application Server 中启用批处理操作,请执行以下操作:

    1. 在管理控制台中,导航到 Application servers => server_name => Process Definition => Java Virtual Machine
    2. 在 Generic JVM arguments 框的现有所有 JVM 参数后,添加以下参数:

      -Dcom.ibm.ws.pm.batch=true

    再次说明,批处理数据库操作的折衷在于,这种操作不会按与代码中相同的顺序来处理更新,但通常会带来更好的性能。因此,在开始时可以不采用批处理数据库操作(WebSphere Application Server 的缺省设置),在需要时再打开它以获得更好的性能。

  3. order-database-operations

    order-database-operations 元素将所有数据库操作延迟到事务结束时处理、自动对操作之间的依赖关系进行分类,并按照这种方式将这些操作发送到数据库以避免数据库约束错误。在 WebLogic 中,此元素缺省时是启用的,所以如果您不想对数据库操作进行排序,则必须显式禁用它。

    要禁用 order-database-operations,您必须禁用此元素和 enable-batch-operations 元素(请参阅前一部分)。如果这二者都没有禁用,则容器将继续对数据库操作进行排序。

    在 WebSphere Application Server 中,数据库操作排序(和批处理)在缺省情况下是禁用的,所以您必须显式启用它。要启用它,必须使用以下系统参数启用创建时的延迟插入:

    -Dcom.ibm.ws.pm.deferredcreate=true
    -Dcom.ibm.ws.pm.batch=true

    第一个参数会将数据库插入操作延迟到事务提交时执行;第二个参数将要发送给数据库的所有其他操作延迟到事务提交时执行。如果在负载测试过程中发现存在引用完整性违规,则可能还需要为容器管理的持久性设置顺序分组。

    为了阐释通过对数据库操作进行排序来维持引用完整性的必要性,请考虑以下示例:

    1. 假设实体 bean Cust-A 与 Sales-A 相关。
    2. 进一步假设 Sales-A 被删除,而 Cust-A 分配得到一个新的 Sales-B。
    3. 如果 Cust-A 有一个完整性约束来指明它必须拥有一个销售人员,则 Cust-A 必须先更新到新的 Sales-B,然后才能删除 Sales-A。

    要在 WebSphere Application Server 中设置顺序分组,请执行以下操作:

    1. 在 Rational Application Developer 中,打开 EJB 项目。
    2. 双击部署描述符。
    3. 单击 Overview 选项卡。
    4. 在 EJB CMP sequence groups 部分,单击 Add 来启动 EJB CMP Sequence Group 向导。
    5. 为顺序分组键入一个名称。
    6. 键入分组类型名称(全部为大写字符):RI_INSERTUPDATE_LOCK。对于删除操作的情况,持久性管理器会对 RI_INSERT 分组中的顺序进行反向,并据此删除 bean 及其相应的数据库行。
    7. 在 Available Beans 列表中,突出显示了您要放在分组中的第一个 bean。单击指向 Selected beans 列表的箭头,将它从 Available beans 列表移到 Selected beans 列表中。
    8. 重复步骤 7,将所有 bean 按照您希望持久性管理器处理的顺序添加进来。
  4. weblogic-ql

    weblogic-ql 元素向 EJB 2.0 Query Language (EJB-QL) 指定一个包含特定于 WebLogic 的扩展的查询。ejb-jar.xml 部署描述符中使用标准的 EJB-QL 语言特性,而在 weblogic-cmp-rdbms-jar.xml 中使用 WebLogic EJB-QL 扩展。查询中经常使用排序、聚合功能和子查询,但由于其他扩展也会被使用,所以要始终谨慎地检查所有的 weblogic-ql 元素。

    WebSphere Application Server 也扩展了 EJB-QL 语言特性,但与定义单独 QL 不同的是,WebSphere Application Server 向 EJB-QL 语法提供排序、子查询和聚合功能。也就是说,WebSphere 扩展 EJB-QL 语法来包括这些扩展。因此,您可以在 ejb-jar.xml 文件的标准 ejb-ql 元素中使用 EJB-QL 及其扩展。

    要将 weblogic-ql 元素映射到 ejb-ql 元素,请执行以下操作:

    1. 在 Rational Application Developer 中,打开 EJB 项目。
    2. 双击部署描述符。
    3. 单击适当的 Java bean。
    4. 向下滚动到 Queries 部分。
    5. 选择适当的查询,并单击 Edit 按钮来显示 Edit Finder Method 对话框。
    6. 按照向导中的步骤构造正确的查询语句。

    下一部分将介绍 weblogic-ql 元素到 ejb-ql 元素的查询语句映射。

    映射排序方式

    orderby WebLogic QL 扩展是一个关键字,它与 Finder 方法一起使用来指定从选择中返回结果的顺序。您也可以按多个字段排序,以及指定按升序或降序返回结果。

    • 示例 weblogic-ql 元素:

      <weblogic-ql>select object(o) from MeetingAutoservice o where o.idInternAutoservice = ?1 orderby o.numberMeeting</weblogic-ql>

    • 映射后的 ejb-ql 元素:

      <ejb-ql>select object(o) from MeetingAutoservice o where o.idInternAutoservice = ?1 order by o.numberMeeting</ejb-ql>

    映射子查询和聚合功能

    子查询 WebLogic QL 扩展允许在主查询的 WHERE 子句中嵌入一个查询,在需要进一步限制所检索数据的情况下返回数据给主查询使用。MAX WebLogic QL 扩展返回指定字段的最大值。此示例显示子查询和聚合功能及其到 WebSphere Application Server 的映射:

    • 示例 weblogic-ql 元素:

      <weblogic-ql>select OBJECT(o) from MeetingAutoservice o where o.idInternAutoservice=?1 AND o.meetingNumber = (select MAX(p.meetingNumber) from MeetingAutoservice p where p.idInternAutoservice = ?1)</weblogic-ql>

    • 映射后的 ejb-ql 元素:

      <ejb-ql>select OBJECT(o) from MeetingAutoservice o where o.idInternAutoservice=?1 AND o.meetingNumber = (select MAX(p.meetingNumber) from MeetingAutoservice p where p.idInternAutoservice = ?1)</ejb-ql>

  5. max-elements

    max-elements 元素指定 multi-finder 或 ejbSelect 方法应该返回的最大元素数。也就是说,它限制了查询返回的行数,类似于 JDBC 中的 maxRows 功能。

    根据 J2EE 规范,如果您没有限制结果集的大小,则当执行 multi-object finder 或 ejbSelect 方法时,ResultSet 将被读完,而客户机将通过遍历方式接收整个集合。显然,这种方法对于大型结果集(集合)而言效果很差。

    要查找所有出现 max-elements 的地方,请搜索 weblogic-cmp-rdbms-jar.xml 中的此元素:

    <max-elements>

    在 WebSphere Application Server 中,您无法限制从 finder 中获取的行数。如果应用程序使用 max-elements,则需要修改代码;一种可能的修改方法是在一个 Facade 中编写适当的逻辑来从结果集中获取前 n 行 (FETCH FIRST n ROWS)。

    也就是说,在一般情况下,良好的编程原则是任何结果集超过 10 的 finder 都应该用 JDBC 来实现,而避免使用相应的消耗大量内存的 EJB finder 方法,因为如果应用程序定位为大容量的,finder 返回超过十个元素,则可能会有问题。

结束语

本文描述了如何在应用程序中查找 WebLogic 专有扩展,以及如何将这些专有扩展迁移到 WebSphere Application Server——因为您能找到它们不意味着您应该将它们全部实现。通常,当将应用程序从 WebLogic 迁移到 WebSphere Application Server 时,您应该做到以下几点:

  • 仔细检查所有 WebLogic 专有扩展以便事先知道哪些扩展适用于该应用程序。这有助于您更好地测试和调整应用程序,评估迁移需要多长时间,并帮助您规避一些意外。

  • 实现那些应用程序运行必需的扩展(仅需要实现那些扩展)。必需的扩展指的是创建应用程序所需的托管资源(JDBC 连接池、JMS 连接工厂等)的扩展。

  • 一旦应用程序正在运行,实现那些为满足应用程序性能和可伸缩性需求所需的扩展。也就是说,开始时采用缺省的 WebSphere Application Server 设置,然后由负载测试指导您可能需要实现其他哪些扩展。

  • 千万不要重构应用程序——至少在迁移完成前不要这样做。例如,如果应用程序使用悲观锁定,则在迁移过程中不要将应用程序更改为使用乐观锁定。测试并调整应用程序以使其运行在最佳状态,然后再考虑重构。

知道如何识别 WebLogic 扩展以及如何将其迁移到 WebSphere Application Server,并遵循这些指导原则将有助于您实现成功迁移,同时规避迁移过程中的许多意外情况。


相关主题


评论

添加或订阅评论,请先登录注册

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=WebSphere
ArticleID=260275
ArticleTitle=WebSphere 迁移: 将 WebLogic 服务器和应用程序配置迁移到 WebSphere Application Server
publish-date=10092007