关于weblogic的Persistence

发布: 2009-6-15 12:17 | 作者: miaomiao | 来源: 应用交付网络专业站点

看了metoo的最常用的50个irules,其中有关于BEA Weblogic Persistence的一个irules。内容如下:


#  BEA Weblogic Persistence
#  CPU impact:   Medium
#  Requirement:  HTTP profile, Weblogic v8+
#
#  Weblogic servers have the ability to replicate session information
#  to a backup server.  Should the first primary server that a user is
#  using become unavailable, then the LTM should send a user to a specific
#  secondary server, rather than simply reloadbalancing to a new server.
#  For typical deployments, it is recommend to start with the LTM's built
#  in cookie persistence or the JSessionID persistence iRule.


when RULE_INIT {
  # set the name of the persistence token (cookie) here
  set ::SessionIDName "WebDomain_PORTALSESSION"
  set ::X_WebLogic_Cluster_List ""
}

when HTTP_REQUEST {
    if { [HTTP::cookie exists $::SessionIDName] } {
      set session_id [ substr [HTTP::cookie $::SessionIDName] 0 "!" ]
      set session_id_len [expr {[string length $session_id] + 1}]
      set primary_server_jvmid  [ substr [HTTP::cookie $::SessionIDName] $session_id_len "!" ]
      set primary_server_jvmid_len [expr {[string length $primary_server_jvmid] + 1}]
      set str_len [expr {$session_id_len + $primary_server_jvmid_len}]
      set secondary_server_jvmid  [ substr [HTTP::cookie $::SessionIDName] $str_len "!" ]
      persist uie $session_id

      # get primary server information from persistence record
      set LBPool [ persist lookup uie $session_id pool ]
      set LBMember [ persist lookup uie $session_id node ]
      set LBPort [ persist lookup uie $session_id port ]

      # start delete this section once tested and server addr is decoded
      set secondary_id [findstr $::X_WebLogic_Cluster_List $secondary_server_jvmid 0 "!-1|"]
      set secondary_server_jvmid_len [expr {[string length $secondary_server_jvmid] + 1}]
      set secondary_server_addr_str  [ substr $secondary_id $secondary_server_jvmid_len "!" ]
      set secondary_server_port  [ substr $secondary_id [expr {$secondary_server_jvmid_len + [string length $secondary_server_addr_str] + 1}] "!" ]

      # convert secondary string address to ipaddr
      set hex_ip [format %x $secondary_server_addr_str]

      set a [string range $hex_ip 0 1]
      set b [string range $hex_ip 2 3]
      set c [string range $hex_ip 4 5]
      set d [string range $hex_ip 6 7]
      set secondary_server_addr "[format %i 0x$a].[format %i 0x$b].[format %i 0x$c].[format %i 0x$d]"

      # heath check primary member
      if { $LBPool != "" } {   
        if {[LB::status pool $LBPool member $LBMember $LBPort] ne "up"} {
          # if primary failed, search header
          set secondary_id [findstr $::X_WebLogic_Cluster_List $secondary_server_jvmid 0 "!-1|"]
          set secondary_server_jvmid_len [expr {[string length $secondary_server_jvmid] + 1}]
          set secondary_server_addr_str  [ substr $secondary_id $secondary_server_jvmid_len "!" ]
          set secondary_server_port  [ substr $secondary_id [expr {$secondary_server_jvmid_len + [string length $secondary_server_addr_str] + 1}] "!" ]
          # binary format i3 {3 -3 65536 1}   
          # convert secondary string address to ipaddr
          set hex_ip [format %x $secondary_server_addr_str]

          set a [string range $hex_ip 0 1]
          set b [string range $hex_ip 2 3]
          set c [string range $hex_ip 4 5]
          set d [string range $hex_ip 6 7]
         
          set secondary_server_addr "[format %i 0x$a].[format %i 0x$b].[format %i 0x$c].[format %i 0x$d]"
          # health check secondary
          if {[LB::status pool $LBPool member $secondary_server_addr $secondary_server_port] eq "up"} {
            persist delete uie $session_id
            pool $LBPool member $secondary_server_addr $secondary_server_port
          } else {   
            # if secondary failed then re-load balance
            HTTP::redirect http://[getfield [HTTP::host] ":" 1][HTTP::uri]
          }
        }
      }
    }
    # This header instructs Weblogic to return cluster information
    HTTP::header insert X-Weblogic-Request-ClusterInfo true
}

when HTTP_RESPONSE {
    HTTP::header remove X-Powered-by
    if { [HTTP::cookie exists $::SessionIDName] } {   
      persist add uie [ substr [HTTP::cookie $::SessionIDName] 0 "!" ]   
    }
    if { [HTTP::header exists X-WebLogic-Cluster-List] }{
      set ::X_WebLogic_Cluster_List [HTTP::header X-WebLogic-Cluster-List]
      HTTP::header remove X-WebLogic-Cluster-List
    }
}

大概的意思能猜出来,但是不知道怎么用,需要weblogic进行额外配置或应用进行改造?其中WebDomain_PORTALSESSION从哪里来?用http watch看了交互过程没有发现这个head,只有:
Set-Cookie        JSESSIONID=K1zcZNfhzDKrtRQPg9Fv0TLQdznd1pbpRTZQvRMDw4DP7JqM1T1n!-1003613857!67506566; path=/
改为JSESSIONID之后应用倒是能访问,X-WebLogic-Cluster-List的值也能取到,但是当前连接的server关闭后却不能访问应用了,即使群集中的另一台server状态正常也不行。去掉irules之后却能够达到失败转移的效果,当然,这只是群集中只存在2个server的场景, 不存在选择问题。
2009-6-15 22:25:11
有没有同时关联One-Connection Profile?
2009-6-16 10:13:02
关联了.         
2009-6-17 22:48:53
关联了one-connection应该没有问题的。这个时候可能需要进一步排错的动作。
1、在不通的时候需要查看/var/log/ltm的内容,是否有报错。因为如果是不关联iRule的情况下没有问题,那说明客户端和服务器的工作机制都是正常的。如果不通的情况出现,多半是iRules执行遇到了错误,导致请求失败。
2、如果错误在应用层上,也就是说出现的是一些服务器的报错页面之类的东西,则需要用HTTP Watch分析一下请求包和回应包,看看究竟有什么不同。
2009-6-17 22:49:05
关联了one-connection应该没有问题的。这个时候可能需要进一步排错的动作。
1、在不通的时候需要查看/var/log/ltm的内容,是否有报错。因为如果是不关联iRule的情况下没有问题,那说明客户端和服务器的工作机制都是正常的。如果不通的情况出现,多半是iRules执行遇到了错误,导致请求失败。
2、如果错误在应用层上,也就是说出现的是一些服务器的报错页面之类的东西,则需要用HTTP Watch分析一下请求包和回应包,看看究竟有什么不同。
2009-6-17 23:05:00
这个问题很有意思,如果方便,给我打个电话讨论一下,我也想研究一下这个问题。
2009-6-18 15:48:41
Jun 18 15:48:19 tmm tmm[951]: 01220001:3: TCL error: Rule BEAWeblogicPersistence <HTTP_REQUEST> - expected integer but got ""     while executing "format %x $secondary_server_addr_str"
Jun 18 15:48:19 tmm tmm[951]: 01220001:3: TCL error: Rule BEAWeblogicPersistence <HTTP_REQUEST> - expected integer but got ""     while executing "format %x $secondary_server_addr_str"


server停止后第一次请求是ok,请求返回分别如下:
Cookie: BIGipServerAPPFRAME_DEV_POOL=324341932.35603.0000; JSESSIONID=K51ZWZrNC4dC16m4vn1nC6JZPnG5GyKGn1ZnFJQW8xWGtpFNgJdy!1132416384!-1338624548

Set-Cookie: JSESSIONID=K51ZWZrNC4dC16m4vn1nC6JZPnG5GyKGn1ZnFJQW8xWGtpFNgJdy!-1338624548!NONE; path=/


再下一次请求问题就来了,请求是:
Cookie: BIGipServerAPPFRAME_DEV_POOL=324341932.35603.0000; JSESSIONID=K51ZWZrNC4dC16m4vn1nC6JZPnG5GyKGn1ZnFJQW8xWGtpFNgJdy!-1338624548!NONE

HTTP Request        Check if modified since 'Wed, 29 Apr 2009 09:59:32 GMT'        ERROR_INTERNET_CONNECTION_RESET

问题看来就出在这个NONE上啊,是转换不成ip的.
我想主要还是因为server只要2个吧,如果其中1个down了,找不到服务器来做会话保持了,所以返回的是NONE,如果还有其他服务器应该是不会报错的,测试环境没有3台以上群集的,所以没有测试.

另外,我一直以为f5是能够自动进行这个irules进行的工作的,不是说f5和bea是战略合作伙伴吗,这个过程咋还要另外进行处理呢?

[ 本帖最后由 miaomiao 于 2009-6-18 15:52 编辑 ]
2009-6-18 16:16:46
oneconnect是不是会影响负载均衡策略?
我感觉使用了之后负载不是特别平均,使用的轮询策略,有人说是我们的连接基数过少,看不出来....
2009-6-18 22:34:10
赞同楼上的猜测,如果Weblogic得集群配置没有问题的话,这个rules应该在3台以上的情况才能正常工作。出现NONE的原因是不是因为这台Server发现在集群里面只有自己一台机器了,因此就无法把自己的Session复制到其他Server上去。所以就在Secondary server 的地方写了一个NONE。当然,如果只有两台Server集群的情况下,是完全不需要这个Rule的。

原来在4.5的时候F5是把这个功能做到图形界面里的,打钩就可以用了。但后来每次Weblogic升级都在变化,因此在9.0版本出来的时候就通过rules方式来提供了。随时可以根据版本的不同来修改。

One Connect对负载均衡策略有影响。加了One Connect之后,负载均衡的处理都会变成按照每一个Request处理,而不是按照连接处理。
2009-6-19 08:49:19
明白了.感谢ls的解答.
另:关于oneconnect,如果是按照Request进行处理,同时又受会话保持限制,轮询的效果很有问题啊,如果想尽量平均分摊一下压力,应该怎么配置策略?
oneconnect感觉复用连接的效果是明显的,但是如果是多台群集,压力又不是特别大的话是否也没必要使用?btw,我们是局域网.
2009-6-20 00:33:29
在One connect里面可以配置掩码,如果不需要进行多个用户的连接复用,把掩码设置为255.255.255.255就可以了,这样只是针对每一个用户起作用。

另外负载均衡的算法可以不用轮询,用最小连接数、predictive或者Observe都可以。要有兴趣的还可以测试一下SNMP、WMI之类的算法,这样可以根据后台的CPU资源占用率来进行连接分配。
2009-6-20 00:33:38
在One connect里面可以配置掩码,如果不需要进行多个用户的连接复用,把掩码设置为255.255.255.255就可以了,这样只是针对每一个用户起作用。

另外负载均衡的算法可以不用轮询,用最小连接数、predictive或者Observe都可以。要有兴趣的还可以测试一下SNMP、WMI之类的算法,这样可以根据后台的CPU资源占用率来进行连接分配。
2010-5-24 09:51:48
测试的时候如果使用两台server会有问题,如果down掉一台后,只剩一台server,所以这台server在返回的cookie中的secondry-server=none。导致这个irule在执行:
set hex_ip [format %x $secondary_server_addr_str]

      set a [string range $hex_ip 0 1]
      set b [string range $hex_ip 2 3]
      set c [string range $hex_ip 4 5]
      set d [string range $hex_ip 6 7]
      set secondary_server_addr "[format %i 0x$a].[format %i 0x$b].[format %i 0x$c].[format %i 0x$d]"
的时候会报错,所以页面打不开。
解决方法 只需要在前面做一个单台保护的判断:
if { $secondary_server_jvmid eq "NONE" } {
           pool pool_web member $LBMember
          }
就ok了。
不过这个irule有个地方要注意,就是在做字符串和地址转化的时候,如果服务器ip是192或172开头的没问题,但开头ip要是两位如:10.1.1.1就要改一下了。
2010-6-02 18:16:08
丁哥的irules很赞,经过测试很OK,这里更新一下,pool这个最好也使用变量。。否则一个不小心就会发现即使没关联上pool,VS也显示为绿色的情况了,这个困扰了我们好几天,最后想想还是检查不太认真的问题。。。
        if { $secondary_server_jvmid eq "NONE" } {
           pool $LBPool member $LBMember
          }
2010-9-09 08:53:26
都是高手啊