Forum Discussion
iRule for HTTP redirect, destination address persistence based on HTTP::URI
Hi All,
I have been using an iRule to elect a pool member from a pool which is closest to the client based on the client ip address. Then an HTTP redirect would be send to that client to connect to the actual server. This works well but now we are in the need of another type of iRule where we can optimize our caches. But since the web directories and files are dynamic (adaptive bitrate streaming (HLS)) we cannot use the folders or paths in the iRule code...
Lets say I have two caching reverse proxies (node1 and node2) and three clients (client1, client2 and client3) and two HLS encoded movies (movie1 and movie2).
If client1 requests movie1 "http://{BigIp_f5_ltm_VIP}/vod/movie1/movie1.m3u8" I would like to have an HTTP redirect send by the load balancer back to the client to go to "http://{node1_ip}/vod/movie1/movie1.m3u8".
Then if client 2 requests the same url "http://{BigIp_f5_ltm_VIP}/vod/movie1/movie1.m3u8" an HTTP redirect message would need to be send back to the client to connect to node1 again (because client1 was send there before).
Now if client3 comes by for movie2 "http://{BigIp_f5_ltm_VIP}/vod/movie2/movie2.m3u8" an HTTP redirect to go to node2 would need to be send back to the client.
Basically this would mean that I need HTTP redirection with destination ip address persistence based on the HTTP::URI. How can I do this?
Thanks in advance,
Jeroen
5 Replies
- j-boelhouwer_11
Nimbostratus
Ahh. Just found it.... An excellent solution can be found here: https://devcentral.f5.com/codeshare/election-hash-load-balancing-and-persistence
Thanks anyway!
- Hi Jeroen, using a hash based calculation would already make your initial election completely random, but on the other wouldn't require memory to store the [table] records. So if the randomness is not an issue, then go for it. Its a much better approach then... Cheers, Kai
Hi Jeroen,
you could store the previous elections results for a given URI/Path into LTMs memory based [table] and then query the [table] on consecutive request before electing again.
when RULE_INIT { set static::table_lifetime 86400 ; One day } when HTTP_REQUEST { if { [HTTP::path] starts_with "/vod/" } then { if { [set location [table lookup -notouch "redir_[HTTP::path]"]] ne "" } then { HTTP::redirect $location } else { Insert your election code here Change your code so that it stores the elected location into $location table set "redir_[HTTP::path]" $location indef $static::table_lifetime HTTP::redirect $location } } }Cheers, Kai
- j-boelhouwer_11
Nimbostratus
Hi Kai,
Thanks for your ideas.
Using the hash election there is no need to store the information in the memory since there will not be that many http requests hitting the LTM. It is only the first HTTP request a client makes. Consequent requests as derived from the m3u8 playlist are made to the edge server directly. So If there are say 20.000 clients in 1 hour requesting the initial m3u8 playlist then the iRule will be fired only 5.4 times per second on average (if the requests are evenly spread out) I have seen similar iRule executions well above 1000 tps. For now I have 2 edge nodes and the following iRule. For each request
Election Hash iRule Version 1.0 Jan 5th 2016 MD5 calculation of Server + URI Rule selects Server that scores highest S = Current high score N = Node being evaluated W = Winning node when HTTP_REQUEST { if {[active_members -list pool_edge_nodes] > 0 } { if { (([HTTP::method] eq "GET") && ([HTTP::uri] contains ".m3u8")) } { Election Randomizer Using md5 function + http::uri to generate a score. The highest wins. set S "" set R "" foreach N [active_members -list pool_edge_nodes] { if { [md5 $N[HTTP::uri]] > $S } { set S [md5 $N[HTTP::uri]] set W $N } } log "winning server: $W" Generate redirect set edgeip [lindex $W 0] set url "http://$edgeip[HTTP::uri]" Send Redirect message HTTP::redirect "$url" log "[IP::client_addr] - Redirected to $url" } else { Send Service Unavailable message HTTP::respond 503 log "[IP::client_addr] - Not redirected, no edge node available" } } else { Send Service Unavailable message HTTP::respond 404 log "[IP::client_addr] - Not redirected, not a valid request" } }Thanks,
Jeroen
- As i said in my last comment a stateless solution based on hashes/checksums should be alway prefered if possible. I also don't believe that 5,4 RPS would have a noticable impact on your box. But if performance would become a problem in the future, then fell free to come back to devcentral, so that we could optimize your code a little bit. On the first sight your rule has the potential to save some cycles... ;-) Cheers, Kai
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