关于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的场景, 不存在选择问题。
# 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的场景, 不存在选择问题。

1、在不通的时候需要查看/var/log/ltm的内容,是否有报错。因为如果是不关联iRule的情况下没有问题,那说明客户端和服务器的工作机制都是正常的。如果不通的情况出现,多半是iRules执行遇到了错误,导致请求失败。
2、如果错误在应用层上,也就是说出现的是一些服务器的报错页面之类的东西,则需要用HTTP Watch分析一下请求包和回应包,看看究竟有什么不同。
1、在不通的时候需要查看/var/log/ltm的内容,是否有报错。因为如果是不关联iRule的情况下没有问题,那说明客户端和服务器的工作机制都是正常的。如果不通的情况出现,多半是iRules执行遇到了错误,导致请求失败。
2、如果错误在应用层上,也就是说出现的是一些服务器的报错页面之类的东西,则需要用HTTP Watch分析一下请求包和回应包,看看究竟有什么不同。
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 编辑 ]
我感觉使用了之后负载不是特别平均,使用的轮询策略,有人说是我们的连接基数过少,看不出来....
原来在4.5的时候F5是把这个功能做到图形界面里的,打钩就可以用了。但后来每次Weblogic升级都在变化,因此在9.0版本出来的时候就通过rules方式来提供了。随时可以根据版本的不同来修改。
One Connect对负载均衡策略有影响。加了One Connect之后,负载均衡的处理都会变成按照每一个Request处理,而不是按照连接处理。
另:关于oneconnect,如果是按照Request进行处理,同时又受会话保持限制,轮询的效果很有问题啊,如果想尽量平均分摊一下压力,应该怎么配置策略?
oneconnect感觉复用连接的效果是明显的,但是如果是多台群集,压力又不是特别大的话是否也没必要使用?btw,我们是局域网.
另外负载均衡的算法可以不用轮询,用最小连接数、predictive或者Observe都可以。要有兴趣的还可以测试一下SNMP、WMI之类的算法,这样可以根据后台的CPU资源占用率来进行连接分配。
另外负载均衡的算法可以不用轮询,用最小连接数、predictive或者Observe都可以。要有兴趣的还可以测试一下SNMP、WMI之类的算法,这样可以根据后台的CPU资源占用率来进行连接分配。
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就要改一下了。
if { $secondary_server_jvmid eq "NONE" } {
pool $LBPool member $LBMember
}