Forum Discussion
Load Balance 4 URI over 2 IPs and rewrite http response location
I have been struggling with this and I hope someone can assist.
The challenge is twofold:
1. Need Virtual Server to load balance between 4 URIs which are spread over 2 Nodes.
2. When the webservers respond, they respond with a location which points to itself instead of the FQDN the client specified
I have tried solving with numerous variations of below iRules, but fail when the client receives the Nodes http://hostname:portnumber/URi/web2.exe (which isn't reachable from client network).
@1: Irule to load balance between 4 URIs:
Virtual Server name: vs_example.com
IP: 172.16.0.1
b. Pools:
pool_example1-uri-1_81
- node_01_10.0.0.1:81
pool_example1-uri-2_81
- node_01_10.0.0.1:81
pool_example2-uri-3_81
- node_02_10.0.0.2:81
pool_example2-uri-4_81
- node_02_10.0.0.2:81
c. iRule:
when HTTP_REQUEST {
# Check if the requested URI is either / or /CAisd/pdmweb.exe
if { [HTTP::uri] eq "/" or [HTTP::uri] eq "/CAisd/pdmweb.exe" } {
# Define the possible URIs and corresponding pools
set uri_pool_map {
/URi/web1.exe pool_example1-uri-1_80
/URi/web2.exe pool_example1-uri-2_80
/URi/web3.exe pool_example1-uri-3_80
/URi/web4.exe pool_example1-uri-4_80
}
# Initialize a list of available pools
set available_uri_pool_list {}
# Check the availability of each pool and add to the list if available
for {set i 0} {$i < [llength $uri_pool_map]} {incr i 2} {
set pool_name [lindex $uri_pool_map [expr {$i + 1}]]
if {[active_members $pool_name] > 0} {
lappend available_uri_pool_list [lindex $uri_pool_map $i] $pool_name
} else {
log local0. "Pool $pool_name is not available"
}
}
# If no pools are available, send an error response
if {[llength $available_uri_pool_list] == 0} {
HTTP::respond 503 content "Service Unavailable - No available pools"
return
}
# Select the next URI and corresponding pool in a round-robin fashion from available pools
set index [expr {[clock clicks -milliseconds] % ([llength $available_uri_pool_list] / 2)}]
set next_uri [lindex $available_uri_pool_list [expr {$index * 2}]]
set next_pool [lindex $available_uri_pool_list [expr {$index * 2 + 1}]]
# Log the selected URI and pool for troubleshooting
log local0. "Selected URI: $next_uri, Pool: $next_pool"
# Replace the URI with the selected one
HTTP::uri $next_uri
# Select the corresponding pool
pool $next_pool
}
}
@2. iRule to replace location in HTTP Response
when HTTP_RESPONSE_RELEASE {
if { [HTTP::header exists "Location"] } {
set location [HTTP::header "Location"]
log local0. "Original Location header: $location"
# Modify the Location header if it contains the internal server reference
if { $location starts_with "http://webserver1" || $location starts_with "http://webserver2" } {
set new_location [string map {
"http://webserver1:81" "https://172.16.0.1"
"https://webserver1:81" "https://172.16.0.1"
"http://webserver2:81" "https://172.16.0.1"
"https://webserver2:81" "https://172.16.0.1"
} $location]
HTTP::header replace "Location" $new_location
log local0. "Modified Location header: $new_location"
}
}
}
You are better off changing the configuration on the server that is sending the redirect. The web server should send back the correct host rather than its own IP. You might be able to correct this on the F5 but it would be much more complicated.
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