<< 同一个Weblogic两个Domain CookieName冲突导致session失效问题 | 首页 | Exception java.lang.OutOfMemoryError ...growableArray.cpp. Out of swap space >>

Weblogic集群HTTP会话复制失败故障诊断

问题描述
Http 会话状态没有从 Primary 服务器复制到 Secondary 服务器。下面是一些故障症状:
  • 使用 http 会话的应用程序没有按设计运行,并且会话数据有所丢失
  • 即使在会话仍未超时的情况下,系统也可能提示您重新登录到应用程序中
  • 您在服务器的日志文件中看到与 Http 会话失败相关的错误和警告
  • 没有正确地将请求 Failover 到另一个服务器
故障排除
请注意,并非下面所有任务都需要完成。有些问题仅通过执行几项任务就可以解决。

快速链接

为什么发生此问题?
会话复制失败通常是因为组播/网络问题引起的。有时候,配置问题也会导致失败(请查看“验证 Weblogic.xml 条目”一节)。此外,请确保输入到会话中的数据必须是可序列化的,否则复制可能会失败。使用下列检查清单检查配置或可能导致会话复制失败的其它潜在问题。

返回页首

Http 会话复制有什么类型?
有五种不同的会话持久性实现方式:
  1. 内存(单个服务器,不复制)

当您使用基于内存的存储方式时,所有会话信息都存储在内存中,并且当您停止和重新启动 WebLogic Server 时,这些信息将会丢失。

  1. 文件系统持久性

会话信息存储在指定的 PersistentStoreDir 中的一个文件中。

  1. JDBC 持久性

会话信息存储在数据库表中。

  1. 基于 cookie 的会话持久性

会话信息存储在 cookie 中。

  1. 内存中复制(在群集内)

会话数据从一个服务器实例复制到内存中的另一个实例。

返回页首

当会话复制失败时如何诊断此问题?
考虑一个群集中有两个服务器(MyServer-1,MyServer-2)的情况。当您启用调试标志后,如果从某个客户端发送了一个请求,您将会立即看到下面的消息(请参阅启用调试标志跟踪会话复制失败

在 MyServer-1 上:

<Oct 9, 2003 12:38:21 PM PDT> <Debug> <Cluster> <000000> <Creating primary 5165892837402719733> 

<Oct 9, 2003 12:38:21 PM PDT> <Debug> <Cluster> <000000> <Created secondary for 5165892837402719733 on -7957889153726652135S: 210.23.23.1: [9001,9001, -1, -1,9001, -1, -1]: mydomain: MyServer-2>

上面的记录消息意味着 Primary 服务器是 MyServer-1,并且在 Myserver-2 上创建了一个 Secondary 服务器,而且您将看到在 MyServer-2 中记录了类似下面的确认消息。

在 MyServer-2 上:

ExecuteThread: '1' for queue: 'Replication'> <kernel identity> <> <000000> <Creating secondary 5165892837402719733> 

####<Oct 9, 2003 12:38:21 PM PDT> <Debug> <Cluster> <machine1-c840> <MyServer-2> <ExecuteThread: '1' for queue: 'Replication'> <kernel identity> <> <000000> <Updated local secondary of 5165892837402719733>

如果您检查 JsessionId,其形式如下:

   JSESSIONID=1E9Xwn7nLYfOsc1obgRZIwW5s72an7HPPvSD7iaWHMXzpHga5cQj!-1587343083!-1587348922

JSESSIONID 是缺省的 cookie 名称,可以在 weblogic.xml 中将其更改为任何内容。

JSESSIONID 的格式为:

   SessionId!PrimaryServer JVM Hash!SecondaryServer JVMHash

Every time data is changed (either set/get or removed) in the session you'll see the logging message.

在 MyServer-1 上:

<Oct 9, 2003 12:38:21 PM PDT> <Debug> <Cluster> <000000> <Updated remote secondary for 5165892837402719733>

在 MyServer-2 上:

####<Oct 9, 2003 12:38:21 PM PDT> <Debug> <Cluster> <machine1-c840> <MyServer-2> <ExecuteThread: '1' for queue: 'Replication'> <kernel identity> <> <000000> <Updated local secondary of 5165892837402719733>

如果因为任何原因而导致会话复制失败,您将在 MyServer-1 日志中看到下面的消息。


<Nov 6, 2003 12:59:12 PM EST> <Debug> <Cluster> <000000> <Unable to create secondary for -5165892837402719733> 

<Nov 6, 2003 12:59:12 PM EST> <Debug> <Cluster> <000000> <Error creating secondary 5165892837402719733 on -7957889153726652135S: 210.23.23.1:[9001,9001,-1,-1,9001,-1,-1]:mydomain:MyServer-2>

上面的消息意味着会话复制已失败。

JSESSIONID 也会显示为如下形式:

   JSESSIONID=1E9Xwn7nLYfOsc1obgRZIwW5s72an7HPPvSD7iaWHMXzpHga5cQj!-1587343083!NONE

Secondary 服务器散列信息将变为 NONE。

返回页首

启用调试标志跟踪会话复制失败:
您可以启用 DebugCluster、DebugClusterAnnouncements、DebugFailOver、DebugReplication、DebugReplicationDetails 标志。  

若要启用:

  1. 可以使用 weblogic.Admin 命令行实用程序来动态地启用或关闭调试选项。
    例如,若要在 ServerDebug Mbean 的所有管理实例(即管理服务器或托管服务器)上启用 DebugCluster

    java weblogic.Admin -url t3://localhost:6151 -username system -password weblogic SET -type ServerDebug -property DebugCluster true
  1. 另外,对于要调试的每个服务器,可以编辑 <ServerDebug/> 节中的 config.xml  Mbean 要素,将值设置为“true”表示启用,或设置为“false”表示禁用。然后必须重新启动管理服务器。托管服务器将重新连接到管理服务器,然后调试标志将动态生效。示例:

    <ServerDebug DebugCluster="true" Name="myserver"/>
  1. 在设置了所有标志后,在 config.xml 的末尾处,ServerDebug 标记将类似于如下形式:

    <ServerDebug ClassFinder="true" DebugCluster="true" DebugClusterAnnouncements="true" DebugFailOver="true" DebugReplication="true" DebugReplicationDetails="true" Name="MyServer1"/> 

    确保服务器的 stdOutSeverity 级别为 INFO,且 StdoutDebugEnabled 被设置为“true”。调试信息将被记录到服务器日志以及标准输出中。

返回页首

所使用的每个会话持久性类型的检查清单:

内存(单个服务器,不复制)   
  1. 当您使用基于内存的存储方式时,所有会话信息都存储在内存中,并且当您停止和重新启动 WebLogic Server 时,这些信息将会丢失。
  2. 确保您在运行 WebLogic Server 时已分配足够的堆大小;否则,您的服务器可能在大量负载情况下用尽内存。
  3. 不是群集配置的推荐类型(因为数据保存在堆中,且不可用于任何其它服务器)。
文件系统持久性
  1. 确认已在 weblogic.xml 中正确指定了 WebLogic Server 存储会话的目录。您还必须自行创建此目录,并确保已分配访问此目录的适当权限。
  2. 确保拥有足够的磁盘空间。
JDBC 持久性
  1. 确保连接到数据库的连接池拥有对所用数据库表的读/写权限。
基于 Cookie 的持久性
  1. 确保在 http 会话中没有存储 java.lang.String 以外的任何内容。
  2. 不要刷新您的应用程序代码中的 Http 响应对象。
  3. 确保响应的信息长度超过所设置的缓冲区大小(缺省值为 8192 字节)。
  4. 确保在浏览器中启用了 cookie。
  5. 确保在使用基于 cookie 的会话持久性时,没有在字符串中使用逗号 (,)。
内存中复制
  1. 确保仅通过代理服务器或硬件负载平衡器来访问 Weblogic Server。
  2. 硬件负载平衡器应支持兼容的被动或主动 cookie 持久性机制以及 SSL 持久性。
  3. 群集中的推荐类型。

返回页首

验证 Weblogic.xml 条目:
确保 weblogic.xml 含有需要为每个“会话复制”类型设置的所有参数。 例如,当使用内存中复制时,样本 weblogic.xml 将类似于如下形式:

        <session-descriptor> 
          <session-param> 
             <param-name>
                   PersistentStoreType
             </param-name>
             <param-value> 
                   replicated 
             </param-value> 
          </session-param> 
        </session-descriptor>

返回页首

会话数据必须可序列化
为了支持 HTTP 会话状态的内存中复制,所有 servlet 和 JSP 会话数据都必须是可序列化的,否则会话复制将会失败。当启用了调试标志时,Weblogic Server 将在下面输出警告消息,指示会话仍未被复制。您必须使该对象变为可序列化的对象,这样才能复制它。其它对象的会话复制将会正常进行。

调试消息:

<Oct 8, 2003 2:10:45 PM PDT> <Error> <Cluster> <000126> <All session objects should be serializable to replicate. Please check the objects in your session. Failed to replicate non-serializable object>

解决办法:找到从中抛出错误的页面,并确保输入会话中的所有数据是可序列化的。

返回页首

检查网络/组播问题:
确保网络是完好的,且没有组播问题。您可以执行组播测试来确保组播 IP 工作正常。

  1. 运行 utils.MulticastTest 实用程序
    语法形式类似于:

    java utils.MulticastTest -n name -a address [-p portnumber] [-t timeout] [-s send]

  1. 您也可以参阅 http://e-docs.bea.com/wls/docs81/admin_ref/utils.html#1199798

返回页首

验证群集配置:
从群集列表中选择 Primary 服务器和 Secondary 服务器。在一个由两个服务器组成的群集中,如果该群集没有包含所有服务器,则不能选择 Secondary 服务器,从而导致会话数据不能被复制。

若要验证,可执行下列命令:

  1. 确保 weblogic.jar 在类路径中。
  1. 若要获得群集中的所有服务器:

    java weblogic.Admin -username weblogic -password weblogic -url http://oneofthemanagedserverurlinthecluster:6151/ GET -type ClusterRuntime .pretty

这样将列出群集中的所有服务器。可以将 URL 改变为群集中的每个服务器,以确保他们拥有相同的条目。

返回页首

应用程序代码诊断:
确保仅在应用程序代码中使用 HttpSession 中的 setAttribute/removeAttribute 方法来更新 Http 会话。如果您使用其它设置方法来更改会话内的对象,WebLogic Server 将不复制这些更改。

请不要使用 http 会话的 putValue removeValue 方法,因为它们不受支持,并且当您在应用程序中使用这些方法时,可能会出现会话数据复制问题。相反,请仅使用 HttpSession 的setAttribute/removeAttribute 方法。

返回页首

Cookie 与 URL Rewriting :
在某些情况下,浏览器或无线设备可能不接受 cookie,这样会使利用 cookie 的会话跟踪不能进行。当 WebLogic Server 检测到浏览器不接受 cookie 时,URL Rewriting 是对这种情况的一个可自动替换的解决方法。

通过设置 WebLogic-specific 部署描述符 weblogic.xml 中、<session-param> 元素下的 URLRewritingEnabled 属性,在 WebLogic Server 中启用 URL Rewriting。此属性的缺省值为 true。

返回页首

性能问题:

考虑序列化系统开销
序列化会话数据会给复制会话状态带来一些系统开销。系统开销随序列化对象大小的增大而增加。如果您想在会话中创建很大的对象,请测试您的 servlet 的性能,以确保性能是可接受的。

控制对会话数据的帧访问
如果您正在设计使用多帧的 Web 应用程序,请记住给定帧集中的帧无法执行任何请求同步。

例如,尽管在逻辑上客户端应当仅创建单个会话,但帧集中的多个帧可以代表客户端应用程序创建多个会话。

为了避免意外的应用程序行为,您应认真规划如何利用帧访问会话数据。可以应用下列其中一个一般规则来避免常见问题:

  • 在一个给定帧集中,确保只有一个帧创建和修改会话数据。
  • 始终在应用程序使用的第一个帧集内的某个帧中创建会话(例如,在所访问的第一个 HTML 页面中创建会话)。
  • 在创建会话后,仅在除第一个帧集外的其它帧集中访问会话数据。

在会话中存储更大量的数据
JDBC 持久性和文件持久性的速度将不会更快,因为会话数据必须存储在外部资源中并从中检索,并且也会因为 JDBC 访问每个会话的更新信息而存在性能开销。如果您想在会话中存储大型对象,则应考虑 JDBC 或文件持久性。

在会话中存储小量的数据
当您不需要在会话中存储大量数据时,基于 cookie 的会话持久性是最有用的。基于 cookie 的会话持久性可以使 WebLogic Server 安装的管理更加容易,因为不需要群集 Failover 逻辑。

 




发表评论 发送引用通报