Forum Discussion
F5 irule for multi-pool base on http_response
I have an iRule that distributes traffic between two different pools based on weights defined in data groups. If the application in one pool is down, it receives a 503 response, allowing the traffic to be forwarded to the other pool. This functionality is working as expected. However, when this situation occurs, the browser briefly displays a "page can't be reached" error before retrying and successfully loading the page. I want the iRule to attempt both pools before displaying an error to the user.
when CLIENT_ACCEPTED {
# Initialize variables
set ab_class "/imc/Shared/vs_lb_svc_kube_system_f5_nginx_deployment_dg"
set ab_rule [class match -value "/" equals $ab_class]
set retries 0
set request_headers ""
set pool_list [list]
set active_pool ""
# Populate the pool list and determine the active pool
if {$ab_rule != ""} then {
set service_rules [split $ab_rule ";"]
foreach service_rule $service_rules {
set fields [split $service_rule ","]
set pool_name [lindex $fields 0]
lappend pool_list $pool_name
if { [active_members $pool_name] >= 1 } {
set active_pool $pool_name
}
}
}
# Select the initial pool based on weights
if {$ab_rule != ""} then {
set weight_selection [expr {rand()}]
foreach service_rule $service_rules {
set fields [split $service_rule ","]
set pool_name [lindex $fields 0]
set weight [expr {double([lindex $fields 1])}]
if {$weight_selection <= $weight} then {
# Check if active pool members are available
if { [active_members $pool_name] >= 1 } {
pool $pool_name
return
} else {
# Select other pool with active members
if {$active_pool != ""} then {
pool $active_pool
return
}
}
}
}
}
# If no active pool members are found, return a 503 (Service Unavailable)
if {$active_pool == ""} then {
TCP::respond 503
return
}
}
when HTTP_REQUEST {
# Save the request headers if it is a GET request and not a retried request
if { [HTTP::method] eq "GET" && $retries == 0 } {
set request_headers [HTTP::request]
log local0. "Saving HTTP request headers: $request_headers"
}
}
when HTTP_RESPONSE {
# Check if we got a 503 response
if { [HTTP::status] == 503 } {
# Log the 503 response for debugging purposes
log local0. "Received 503 response, retrying request with next pool"
# Increment the retry counter
incr retries
# Get the current pool
set current_pool [LB::server pool]
# Find the next pool in the list
set next_pool ""
foreach pool $pool_list {
if { $pool == $current_pool } {
continue
}
if { [active_members $pool] >= 1 } {
set next_pool $pool
break
}
}
# If a next pool is found, retry the request with the next pool
if { $next_pool != "" } {
log local0. "Retrying with next pool: $next_pool"
pool $next_pool
HTTP::retry $request_headers
} else {
log local0. "No next pool found, responding with 503"
TCP::respond 503
}
}
}
1 Reply
- Injeyan_Kostas
Nacreous
Hi avinashc
If you wait for HTTP_RESPONSE is already too late.You should try second pool in LB_FAILED event
Help guide the future of your DevCentral Community!
What tools do you use to collaborate? (1min - anonymous)Recent Discussions
Related Content
* Getting Started on DevCentral
* Community Guidelines
* Community Terms of Use / EULA
* Community Ranking Explained
* Community Resources
* Contact the DevCentral Team
* Update MFA on account.f5.com
