Learn F5 Technologies, Get Answers & Share Community Solutions Join DevCentral

Filter by:
  • Solution
  • Technology
Answers

Advantages of Local Traffic Policies VS iRules?

Prior to 11.4 we have been using a simple iRule on our port 80 virtual servers to force traffic to HTTPS.

when HTTP_REQUEST {
    HTTP::respond 301 "Location" "https://[HTTP::host][HTTP::uri]"
}

We are currently in the processing of migrating to new 11.6 boxes and I was curious if there's any reason to move away from the iRule to a local traffic policy as described here:

https://support.f5.com/kb/en-us/solutions/public/14000/900/sol14996.html

Are there any advantages of Local Traffic Policies vs iRules?

0
Rate this Discussion

Replies to this Discussion

placeholder+image

It`s a matter of preference. No big deal.

One advantage of using Local Traffic Policies is that generally they are easier to read and understand for non-technical guys. Note that this cannot be said in case of this HTTP-to-HTTPS redirect policy. Another advantage may be that it would be considerably harder to make a major service-impacting mistake when updating Local Traffic Policies. If an inexperiened junior modifies iRules, incidents are more likely to occur.

Overall, iRules beat Local Traffic Policies just because you can do much more with them. With the use of Local Traffic Policies, you can only solve a handful of basic problems.

Update: As Brad pointed out, Local Traffic Policies can outperform (well-written) iRules due to parallel (conditions & actions) evaluation and short-circuits. Therefore, do not consider this feature a mere "Demo Version of iRules". The performance aspect is a quite strong argument to support the migration to Local Traffic Policies whenever the functionality of your existing iRules can be replicated. Ref Article (by Steve McCarthy): https://devcentral.f5.com/articles/ltm-policy

3
Comments on this Reply
Comment made 20-Jan-2016 by Kai Wilke 7294
I'd like to second this... ;-)
0
placeholder+image

Hi Folks,

I was curious to get some hopefully reliable numbers how much faster the LTM Policies would be. So I've developed a test scenario to meassure the performance differences between LTM Policies and iRules...

Test Setup

Due to missing/comparable performance counters I've used [clock clicks] timestamps to meassure elapsed time. The starting timestamp was insert into a CLIENT_DATA event and the ending timestamp was insert into an HTTP_REQUEST. The request pipeline for every tests was...

when CLIENT_ACCEPTED {
    set time("CLIENT_ACCEPTED-to-HTTP_REQUEST") [clock clicks]
    set time("CLIENT_ACCEPTED-to-CLIENT_DATA") [clock clicks]
    # Collect the HTTP requests to rule out any network latency. 
    TCP::collect
}
when CLIENT_DATA {
    lappend time("CLIENT_ACCEPTED-to-CLIENT_DATA") [clock clicks]
    set time("CLIENT_DATA-to-HTTP_REQUEST") [clock clicks]
    # Release the current HTTP requests
    TCP::release
    TCP::collect
}

# HTTP Profile + LTM Policy or iRule

when HTTP_REQUEST {
    lappend time("CLIENT_DATA-to-HTTP_REQUEST") [clock clicks]
    lappend time("CLIENT_ACCEPTED-to-HTTP_REQUEST") [clock clicks]
}

# Timestamp calculation iRule

Timestamp Calculation

The timestamps where then meassured using an homegrown iRule, which calculates the timestamp differences and then stores the individual values of each request into the session [table] for average calculations. The iRule outputs a web page containing several HTLM tables showing the time taken for...

  • The current request (it supports different timestamps at the same time)
  • A raw min, max and average time taken of the stored [table] data (a sliding window)
  • A configurable cutoff of the min, max and average data to chancel outliers.

Image Text

Note: Feel free to use this iRule to meassure performance differences of a certain code block while developing. Its much easier to handle than timing on and gives a pretty good first impression of performance differences between different coding techniques...

Rule set

The test scenarios where based on a comparable traffic pattern (new connection for every request with same RPS frequency) and an indentical set of checks and actions to perfor. Where both rule sets where checking for a single [HTTP::host] name with 49 wildcard [HTTP::uri]'s (forwarded to [pool] 1) and a default action (forwarded to [pool] 2). Each test was performed using the 1st (fast) and default (slow) condition of the given rule set.

Note: At the bottom of this post you'll find the iRule and LTM Policy configuration used for the test.

Results

It seems that the best comparsion between the two techniques can be done based on the cutoff min value. The output of this value is somewhat reproduceable across different tests and is IMHO also be able to rule out TMM connection parking situations.

Image Text

The results are clearly showing, that LTM Policies are outperforming well written iRule code. A [class] based ruleset could probably save some additional clicks, but the difference shouldn't be that much for 50 test conditions...

Cheers, Kai

4
Comments on this Reply
Comment made 21-Jan-2016 by Brad Parker 4475
Awesome Kai! We should talk to Jason Rahm and get this in to an article. Good stuff.
0
Comment made 21-Jan-2016 by Kai Wilke 7294
You're welcome... ;-) I don't have any contact to Jason Rahm. Feel free to forward my test to him. Hopefully he would add some realiable Spirent Avalanche&Reflector data on top of it ;-)
0
placeholder+image

One reason to move to policies is ease of use for those "programmatically challenged". I've implemented policies before which enabled our NOC to better read and configure them, instead of them having to understand iRules.

One caution--don't mix policies and iRules. There's no definitive guide for which one will process first!

1
Comments on this Reply
Comment made 20-Jan-2016 by Kai Wilke 7294
Hi Theo, there is a guide available which states that LTM Policies are processed before iRules... "For supported events (such as HTTP_REQUEST or HTTP_RESPONSE), LTM Policy evaluation occurs before iRule evaluation. This means that it is possible to write an iRule to override an LTM Policy decision." See: https://devcentral.f5.com/articles/ltm-policy Basically you can set TCL variables using LTM Policies which would then trigger additional iRules code to perform the rather complex manipulations. So both techniques can work hand in hand... Cheers, Kai
1
Comment made 20-Jan-2016 by Theo 390
I've had mixed results mixing Policies and iRules...but I'm not currently in an environment that uses Policies. However, I'm willing to revise and say "use caution when mixing Policies and iRules". :-)
0
Comment made 20-Jan-2016 by Kai Wilke 7294
Yep, I'm currently developing a new version of my homegrown iRule framework. I've included a special mode, to use Policies to parse URLs and make the content switching decicions (its fast and save to use) and then call the iRules framework by passing a single profile variable (is granular as needed). It works like a charm... In addition If using ASM you have to use at least one LTM Policy to select the initial ASM Policy (aka. a dummy policy). Once done you could change the ASM Policy using iRules... Cheers, Kai
0
placeholder+image

An additional note on top of the previous good responses, if you can do something in a local traffic policy it will generally perform better than an equivalent iRule. Built in functionality will almost always outperform iRules. If that functionality doesn't, let F5 know so they can optimize.

Don't get me wrong, I LOVE iRules, but built-in = more better.

1
Comments on this Reply
Comment made 20-Jan-2016 by Hannes Rapp 3890
Thanks for your input. Do you know for sure that there is a notable performance gain over iRules in general, or are you just referring to a fact that most people do not optimize their custom iRules as much as F5 optimizes their own built-in features? No doubt that a Local Traffic Policy will outpeform a poorly written iRule. To the best of my knowledge, a well-written iRule will perform the same. If that's not the case, I would like to learn more (please send me any reference links, or just share what you have tested for yourself). I talked to a F5 field engineer about Local Traffic Policies a while ago and as much as I remember the conversation, the Local Traffic Policies use pointers to the same Event-based system that iRules utilize. The engine powering this new system appears to be the same. Taking that into consideration, i'd say that Local Traffic Policies are a demo version of iRules with no significant improvements besides the easy-to-understand configuration interface.
0
Comment made 20-Jan-2016 by Brad Parker 4475
Hannes, here is a great write-up about Local Traffic Policies. The biggest performance factor I see with a policy over an iRule is an "LTM Policy can evaluate all conditions in parallel. When one or more policies are applied to a virtual server, they go through a compilation step that builds a combined, high-performance internal decision tree for all of the rules, conditions, and actions. This optimized representation of a virtual server's policies guarantees that every condition is only evaluated once and allows for parallel evaluation of all conditions, as well as other performance boosts, such as short-circuit evaluation."
3
Comment made 20-Jan-2016 by Hannes Rapp 3890
I've completely missed that article. Thanks for enlightening an uneducated slob :)
0
Comment made 20-Jan-2016 by Brad Parker 4475
Highly doubt the uneducated slob part!
0
placeholder+image

Statistic iRule

when RULE_INIT {
    set static::sample_frame 60     ;# sec
    set static::sample_cutoff 10    ;# #
}
when HTTP_REQUEST priority 501 {

    # Enumarating current time frames

    foreach temp(timeframe_name) [array names time] {

        # Checking validity of current time frame

        if { [llength $time($temp(timeframe_name))] == 2 } then {

            # Calculating the total time of current time frame

            set temp(timeframe_last_sum) [expr {[lindex $time($temp(timeframe_name)) 1] - [lindex $time($temp(timeframe_name)) 0] - 2 }]

            # Preparing HTML table for current time frame

            append temp(http_response_table_last) "
            <tr>
                <td>$temp(timeframe_name)</td><td>$temp(timeframe_last_sum)</td>
            </tr>"

            # Storing the total time of current time frame into session table

            table set -subtable $temp(timeframe_name) [lindex $time($temp(timeframe_name)) 0] $temp(timeframe_last_sum) indef $static::sample_frame

            # Init statistics calculation 

            set temp(timeframe_table_keys_values) ""

            # Enumarating the stored time frame values for current time frame

            foreach temp(timeframe_table_key) [table keys -subtable $temp(timeframe_name)] {

                # Fetching next stored time frame for current time frame

                set temp(timeframe_table_key_value) [table lookup -subtable $temp(timeframe_name) $temp(timeframe_table_key)]

                # Checking if next stored time frame still exist (race conditions)

                if { $temp(timeframe_table_key_value) ne "" } then {

                    lappend temp(timeframe_table_keys_values) $temp(timeframe_table_key_value)

                }

            }

            if { $temp(timeframe_table_keys_values) ne "" } then {

                # Calculating raw statistics for current time frame

                set temp(timeframe_table_keys_values_sorted) [lsort -integer $temp(timeframe_table_keys_values) ]
                set temp(timeframe_table_keys_count) [llength $temp(timeframe_table_keys_values_sorted)]
                set temp(timeframe_table_keys_min) [lindex $temp(timeframe_table_keys_values_sorted) 0]
                set temp(timeframe_table_keys_max) [lindex $temp(timeframe_table_keys_values_sorted) end]
                set temp(timeframe_table_keys_sum) [expr "[join $temp(timeframe_table_keys_values_sorted) " + " ]"]
                set temp(timeframe_table_keys_avg) [expr { $temp(timeframe_table_keys_sum) / $temp(timeframe_table_keys_count) }]

                # Preparing HTML table for raw statistics of current time frame

                append temp(http_response_table_avg) "
                <tr>
                    <td>$temp(timeframe_name)</td><td>$temp(timeframe_table_keys_min)</td><td>$temp(timeframe_table_keys_max)</td><td>$temp(timeframe_table_keys_avg)</td><td>$temp(timeframe_table_keys_count)</td>
                </tr>"

                # Calculating cutoff statistics for current time frame

                set temp(timeframe_table_keys_count_cutoff_mask) [expr { int($temp(timeframe_table_keys_count) * "0.$static::sample_cutoff" )}]
                set temp(timeframe_table_keys_values_cutoff) [lrange $temp(timeframe_table_keys_values_sorted) [expr { 0 + $temp(timeframe_table_keys_count_cutoff_mask) }] [expr { $temp(timeframe_table_keys_count) - 1 - $temp(timeframe_table_keys_count_cutoff_mask) }]]
                set temp(timeframe_table_keys_count_cutoff) [llength $temp(timeframe_table_keys_values_cutoff)]
                set temp(timeframe_table_keys_min_cutoff) [lindex $temp(timeframe_table_keys_values_cutoff) 0]
                set temp(timeframe_table_keys_max_cutoff) [lindex $temp(timeframe_table_keys_values_cutoff) end]
                set temp(timeframe_table_keys_sum_cutoff) [expr "[join $temp(timeframe_table_keys_values_cutoff) " + " ]"]
                set temp(timeframe_table_keys_avg_cutoff) [expr { $temp(timeframe_table_keys_sum_cutoff) / $temp(timeframe_table_keys_count_cutoff) }]

                # Preparing HTML table for cutoff statistics of current time frame

                append temp(http_response_table_avg_cutoff) "
                <tr>
                    <td>$temp(timeframe_name)</td><td>$temp(timeframe_table_keys_min_cutoff)</td><td>$temp(timeframe_table_keys_max_cutoff)</td><td>$temp(timeframe_table_keys_avg_cutoff)</td><td>$temp(timeframe_table_keys_count_cutoff)</td><td>2 * $temp(timeframe_table_keys_count_cutoff_mask)</td>
                </tr>"

            }

        }

    }

    # Rendering HTML response page

    set temp(http_response) "
<html>
    <head>
        <title>Debug Page</title>
    </head>
    <body>
        </table>
        <h4>Request Information:</h4>
        <table border=1>
            <tr>
                <td>Requested Host#</td><td>[HTTP::host]</td>
            </tr>
            <tr>
                <td>Requested URI</td><td>[HTTP::uri]</td>
            </tr>
            <tr>
                <td>Selected Pool</td><td>[LB::server pool]</td>
            </tr>
            <tr>
                <td>Current TMM_cmp_unit</td><td>[TMM::cmp_unit]</td>
            </tr>
        </table>
        <h4>Last CPU clicks</h4>
        <table border=1>
            <tr>
                <td>Counter Name</td><td>Last CPU Clicks</td>
            </tr>
$temp(http_response_table_last)
        </table>
        <h4>Avg CPU clicks (raw)</h4>
        <table border=1>
            <tr>
                <td>Counter Name</td><td>Min CPU Clicks</td><td>Max CPU Clicks</td><td>Avg CPU Clicks</td><td># Samples</td>
            </tr>
$temp(http_response_table_avg)
        </table>
        <h4>Avg CPU clicks (-$static::sample_cutoff % cutoff)</h4>
        <table border=1>
            <tr>
                <td>Counter Name</td><td>Min CPU Clicks</td><td>Max CPU Clicks</td><td>Avg CPU Clicks</td><td># Samples</td><td># Cutoff</td>
            </tr>
$temp(http_response_table_avg_cutoff)
        </table>
    </body>
</html>"


    HTTP::respond 200 content $temp(http_response) noserver "Content-Type" "text/html"

    unset -nocomplain temp
    unset -nocomplain time
}
0
placeholder+image

Used iRule

if { [string tolower [HTTP::host]] equals "www.itacs.de" {
    switch -glob -- [string tolower [HTTP::uri]] "/somepath/somepath0*" { 
        pool app.itacs.de
    } "/somepath/somepath1*" { 
        pool app.itacs.de
    } "/somepath/somepath2*" { 
        pool app.itacs.de
    } "/somepath/somepath3*" { 
        pool app.itacs.de
    } "/somepath/somepath4*" { 
        pool app.itacs.de
    } "/somepath/somepath5*" { 
        pool app.itacs.de
    } "/somepath/somepath6*" { 
        pool app.itacs.de
    } "/somepath/somepath7*" { 
        pool app.itacs.de
    } "/somepath/somepath8*" { 
        pool app.itacs.de
    } "/somepath/somepath9*" { 
        pool app.itacs.de
    } "/somepath/somepath0*" { 
        pool app.itacs.de
    } "/somepath/somepath11*" { 
        pool app.itacs.de
    } "/somepath/somepath12*" { 
        pool app.itacs.de
    } "/somepath/somepath13*" { 
        pool app.itacs.de
    } "/somepath/somepath14*" { 
        pool app.itacs.de
    } "/somepath/somepath15*" { 
        pool app.itacs.de
    } "/somepath/somepath16*" { 
        pool app.itacs.de
    } "/somepath/somepath17*" { 
        pool app.itacs.de
    } "/somepath/somepath18*" { 
        pool app.itacs.de
    } "/somepath/somepath19*" { 
        pool app.itacs.de
    } "/somepath/somepath20*" { 
        pool app.itacs.de
    } "/somepath/somepath21*" { 
        pool app.itacs.de
    } "/somepath/somepath22*" { 
        pool app.itacs.de
    } "/somepath/somepath23*" { 
        pool app.itacs.de
    } "/somepath/somepath24*" { 
        pool app.itacs.de
    } "/somepath/somepath25*" { 
        pool app.itacs.de
    } "/somepath/somepath26*" { 
        pool app.itacs.de
    } "/somepath/somepath27*" { 
        pool app.itacs.de
    } "/somepath/somepath28*" { 
        pool app.itacs.de
    } "/somepath/somepath29*" { 
        pool app.itacs.de
    } "/somepath/somepath30*" { 
        pool app.itacs.de
    } "/somepath/somepath31*" { 
        pool app.itacs.de
    } "/somepath/somepath32*" { 
        pool app.itacs.de
    } "/somepath/somepath33*" { 
        pool app.itacs.de
    } "/somepath/somepath34*" { 
        pool app.itacs.de
    } "/somepath/somepath35*" { 
        pool app.itacs.de
    } "/somepath/somepath36*" { 
        pool app.itacs.de
    } "/somepath/somepath37*" { 
        pool app.itacs.de
    } "/somepath/somepath38*" { 
        pool app.itacs.de
    } "/somepath/somepath39*" { 
        pool app.itacs.de
    } "/somepath/somepath40*" { 
        pool app.itacs.de
    } "/somepath/somepath41*" { 
        pool app.itacs.de
    } "/somepath/somepath42*" { 
        pool app.itacs.de
    } "/somepath/somepath43*" { 
        pool app.itacs.de
    } "/somepath/somepath44*" { 
        pool app.itacs.de
    } "/somepath/somepath45*" { 
        pool app.itacs.de
    } "/somepath/somepath46*" { 
        pool app.itacs.de
    } "/somepath/somepath47*" { 
        pool app.itacs.de
    } "/somepath/somepath48*" { 
        pool app.itacs.de
    } default { 
        pool www.itacs.de
    }
}
0
placeholder+image

Used LTM Policy

tmsh create ltm policy Parse_HOST_and_URI_then_SELECT_NODE controls add { forwarding } requires add { http } strategy first-match 
tmsh modify ltm policy Parse_HOST_and_URI_then_SELECT_NODE rules add { "Rule 0" { conditions add { 0 { http-host host values { www.itacs.de } } 1 { http-uri starts-with values { /somepath/somepath0 } } } actions add { 0 { forward select pool app.itacs.de } } ordinal 0 } }
tmsh modify ltm policy Parse_HOST_and_URI_then_SELECT_NODE rules add { "Rule 1" { conditions add { 0 { http-host host values { www.itacs.de } } 1 { http-uri starts-with values { /somepath/somepath1 } } } actions add { 0 { forward select pool app.itacs.de } } ordinal 1 } }
tmsh modify ltm policy Parse_HOST_and_URI_then_SELECT_NODE rules add { "Rule 2" { conditions add { 0 { http-host host values { www.itacs.de } } 1 { http-uri starts-with values { /somepath/somepath2 } } } actions add { 0 { forward select pool app.itacs.de } } ordinal 2 } }
tmsh modify ltm policy Parse_HOST_and_URI_then_SELECT_NODE rules add { "Rule 3" { conditions add { 0 { http-host host values { www.itacs.de } } 1 { http-uri starts-with values { /somepath/somepath3 } } } actions add { 0 { forward select pool app.itacs.de } } ordinal 3 } }
tmsh modify ltm policy Parse_HOST_and_URI_then_SELECT_NODE rules add { "Rule 4" { conditions add { 0 { http-host host values { www.itacs.de } } 1 { http-uri starts-with values { /somepath/somepath4 } } } actions add { 0 { forward select pool app.itacs.de } } ordinal 4 } } 
tmsh modify ltm policy Parse_HOST_and_URI_then_SELECT_NODE rules add { "Rule 5" { conditions add { 0 { http-host host values { www.itacs.de } } 1 { http-uri starts-with values { /somepath/somepath5 } } } actions add { 0 { forward select pool app.itacs.de } } ordinal 5 } } 
tmsh modify ltm policy Parse_HOST_and_URI_then_SELECT_NODE rules add { "Rule 6" { conditions add { 0 { http-host host values { www.itacs.de } } 1 { http-uri starts-with values { /somepath/somepath6 } } } actions add { 0 { forward select pool app.itacs.de } } ordinal 6 } } 
tmsh modify ltm policy Parse_HOST_and_URI_then_SELECT_NODE rules add { "Rule 7" { conditions add { 0 { http-host host values { www.itacs.de } } 1 { http-uri starts-with values { /somepath/somepath7 } } } actions add { 0 { forward select pool app.itacs.de } } ordinal 7 } } 
tmsh modify ltm policy Parse_HOST_and_URI_then_SELECT_NODE rules add { "Rule 8" { conditions add { 0 { http-host host values { www.itacs.de } } 1 { http-uri starts-with values { /somepath/somepath8 } } } actions add { 0 { forward select pool app.itacs.de } } ordinal 8 } } 
tmsh modify ltm policy Parse_HOST_and_URI_then_SELECT_NODE rules add { "Rule 9" { conditions add { 0 { http-host host values { www.itacs.de } } 1 { http-uri starts-with values { /somepath/somepath9 } } } actions add { 0 { forward select pool app.itacs.de } } ordinal 9 } } 
tmsh modify ltm policy Parse_HOST_and_URI_then_SELECT_NODE rules add { "Rule 10" { conditions add { 0 { http-host host values { www.itacs.de } } 1 { http-uri starts-with values { /somepath/somepath10 } } } actions add { 0 { forward select pool app.itacs.de } } ordinal 10 } } 
tmsh modify ltm policy Parse_HOST_and_URI_then_SELECT_NODE rules add { "Rule 11" { conditions add { 0 { http-host host values { www.itacs.de } } 1 { http-uri starts-with values { /somepath/somepath11 } } } actions add { 0 { forward select pool app.itacs.de } } ordinal 11 } } 
tmsh modify ltm policy Parse_HOST_and_URI_then_SELECT_NODE rules add { "Rule 12" { conditions add { 0 { http-host host values { www.itacs.de } } 1 { http-uri starts-with values { /somepath/somepath12 } } } actions add { 0 { forward select pool app.itacs.de } } ordinal 12 } } 
tmsh modify ltm policy Parse_HOST_and_URI_then_SELECT_NODE rules add { "Rule 13" { conditions add { 0 { http-host host values { www.itacs.de } } 1 { http-uri starts-with values { /somepath/somepath13 } } } actions add { 0 { forward select pool app.itacs.de } } ordinal 13 } } 
tmsh modify ltm policy Parse_HOST_and_URI_then_SELECT_NODE rules add { "Rule 14" { conditions add { 0 { http-host host values { www.itacs.de } } 1 { http-uri starts-with values { /somepath/somepath14 } } } actions add { 0 { forward select pool app.itacs.de } } ordinal 14 } } 
tmsh modify ltm policy Parse_HOST_and_URI_then_SELECT_NODE rules add { "Rule 15" { conditions add { 0 { http-host host values { www.itacs.de } } 1 { http-uri starts-with values { /somepath/somepath15 } } } actions add { 0 { forward select pool app.itacs.de } } ordinal 15 } } 
tmsh modify ltm policy Parse_HOST_and_URI_then_SELECT_NODE rules add { "Rule 16" { conditions add { 0 { http-host host values { www.itacs.de } } 1 { http-uri starts-with values { /somepath/somepath16 } } } actions add { 0 { forward select pool app.itacs.de } } ordinal 16 } } 
tmsh modify ltm policy Parse_HOST_and_URI_then_SELECT_NODE rules add { "Rule 17" { conditions add { 0 { http-host host values { www.itacs.de } } 1 { http-uri starts-with values { /somepath/somepath17 } } } actions add { 0 { forward select pool app.itacs.de } } ordinal 17 } } 
tmsh modify ltm policy Parse_HOST_and_URI_then_SELECT_NODE rules add { "Rule 18" { conditions add { 0 { http-host host values { www.itacs.de } } 1 { http-uri starts-with values { /somepath/somepath18 } } } actions add { 0 { forward select pool app.itacs.de } } ordinal 18 } } 
tmsh modify ltm policy Parse_HOST_and_URI_then_SELECT_NODE rules add { "Rule 19" { conditions add { 0 { http-host host values { www.itacs.de } } 1 { http-uri starts-with values { /somepath/somepath19 } } } actions add { 0 { forward select pool app.itacs.de } } ordinal 19 } } 
tmsh modify ltm policy Parse_HOST_and_URI_then_SELECT_NODE rules add { "Rule 20" { conditions add { 0 { http-host host values { www.itacs.de } } 1 { http-uri starts-with values { /somepath/somepath20 } } } actions add { 0 { forward select pool app.itacs.de } } ordinal 20 } } 
tmsh modify ltm policy Parse_HOST_and_URI_then_SELECT_NODE rules add { "Rule 21" { conditions add { 0 { http-host host values { www.itacs.de } } 1 { http-uri starts-with values { /somepath/somepath21 } } } actions add { 0 { forward select pool app.itacs.de } } ordinal 21 } } 
tmsh modify ltm policy Parse_HOST_and_URI_then_SELECT_NODE rules add { "Rule 22" { conditions add { 0 { http-host host values { www.itacs.de } } 1 { http-uri starts-with values { /somepath/somepath22 } } } actions add { 0 { forward select pool app.itacs.de } } ordinal 22 } } 
tmsh modify ltm policy Parse_HOST_and_URI_then_SELECT_NODE rules add { "Rule 23" { conditions add { 0 { http-host host values { www.itacs.de } } 1 { http-uri starts-with values { /somepath/somepath23 } } } actions add { 0 { forward select pool app.itacs.de } } ordinal 23 } } 
tmsh modify ltm policy Parse_HOST_and_URI_then_SELECT_NODE rules add { "Rule 24" { conditions add { 0 { http-host host values { www.itacs.de } } 1 { http-uri starts-with values { /somepath/somepath24 } } } actions add { 0 { forward select pool app.itacs.de } } ordinal 24 } } 
tmsh modify ltm policy Parse_HOST_and_URI_then_SELECT_NODE rules add { "Rule 25" { conditions add { 0 { http-host host values { www.itacs.de } } 1 { http-uri starts-with values { /somepath/somepath25 } } } actions add { 0 { forward select pool app.itacs.de } } ordinal 25 } } 
tmsh modify ltm policy Parse_HOST_and_URI_then_SELECT_NODE rules add { "Rule 26" { conditions add { 0 { http-host host values { www.itacs.de } } 1 { http-uri starts-with values { /somepath/somepath26 } } } actions add { 0 { forward select pool app.itacs.de } } ordinal 26 } } 
tmsh modify ltm policy Parse_HOST_and_URI_then_SELECT_NODE rules add { "Rule 27" { conditions add { 0 { http-host host values { www.itacs.de } } 1 { http-uri starts-with values { /somepath/somepath27 } } } actions add { 0 { forward select pool app.itacs.de } } ordinal 27 } } 
tmsh modify ltm policy Parse_HOST_and_URI_then_SELECT_NODE rules add { "Rule 28" { conditions add { 0 { http-host host values { www.itacs.de } } 1 { http-uri starts-with values { /somepath/somepath28 } } } actions add { 0 { forward select pool app.itacs.de } } ordinal 28 } } 
tmsh modify ltm policy Parse_HOST_and_URI_then_SELECT_NODE rules add { "Rule 29" { conditions add { 0 { http-host host values { www.itacs.de } } 1 { http-uri starts-with values { /somepath/somepath29 } } } actions add { 0 { forward select pool app.itacs.de } } ordinal 29 } } 
tmsh modify ltm policy Parse_HOST_and_URI_then_SELECT_NODE rules add { "Rule 30" { conditions add { 0 { http-host host values { www.itacs.de } } 1 { http-uri starts-with values { /somepath/somepath30 } } } actions add { 0 { forward select pool app.itacs.de } } ordinal 30 } } 
tmsh modify ltm policy Parse_HOST_and_URI_then_SELECT_NODE rules add { "Rule 31" { conditions add { 0 { http-host host values { www.itacs.de } } 1 { http-uri starts-with values { /somepath/somepath31 } } } actions add { 0 { forward select pool app.itacs.de } } ordinal 31 } } 
tmsh modify ltm policy Parse_HOST_and_URI_then_SELECT_NODE rules add { "Rule 32" { conditions add { 0 { http-host host values { www.itacs.de } } 1 { http-uri starts-with values { /somepath/somepath32 } } } actions add { 0 { forward select pool app.itacs.de } } ordinal 32 } } 
tmsh modify ltm policy Parse_HOST_and_URI_then_SELECT_NODE rules add { "Rule 33" { conditions add { 0 { http-host host values { www.itacs.de } } 1 { http-uri starts-with values { /somepath/somepath33 } } } actions add { 0 { forward select pool app.itacs.de } } ordinal 33 } } 
tmsh modify ltm policy Parse_HOST_and_URI_then_SELECT_NODE rules add { "Rule 34" { conditions add { 0 { http-host host values { www.itacs.de } } 1 { http-uri starts-with values { /somepath/somepath34 } } } actions add { 0 { forward select pool app.itacs.de } } ordinal 34 } } 
tmsh modify ltm policy Parse_HOST_and_URI_then_SELECT_NODE rules add { "Rule 35" { conditions add { 0 { http-host host values { www.itacs.de } } 1 { http-uri starts-with values { /somepath/somepath35 } } } actions add { 0 { forward select pool app.itacs.de } } ordinal 35 } } 
tmsh modify ltm policy Parse_HOST_and_URI_then_SELECT_NODE rules add { "Rule 36" { conditions add { 0 { http-host host values { www.itacs.de } } 1 { http-uri starts-with values { /somepath/somepath36 } } } actions add { 0 { forward select pool app.itacs.de } } ordinal 36 } } 
tmsh modify ltm policy Parse_HOST_and_URI_then_SELECT_NODE rules add { "Rule 37" { conditions add { 0 { http-host host values { www.itacs.de } } 1 { http-uri starts-with values { /somepath/somepath37 } } } actions add { 0 { forward select pool app.itacs.de } } ordinal 37 } } 
tmsh modify ltm policy Parse_HOST_and_URI_then_SELECT_NODE rules add { "Rule 38" { conditions add { 0 { http-host host values { www.itacs.de } } 1 { http-uri starts-with values { /somepath/somepath38 } } } actions add { 0 { forward select pool app.itacs.de } } ordinal 38 } } 
tmsh modify ltm policy Parse_HOST_and_URI_then_SELECT_NODE rules add { "Rule 39" { conditions add { 0 { http-host host values { www.itacs.de } } 1 { http-uri starts-with values { /somepath/somepath39 } } } actions add { 0 { forward select pool app.itacs.de } } ordinal 39 } } 
tmsh modify ltm policy Parse_HOST_and_URI_then_SELECT_NODE rules add { "Rule 40" { conditions add { 0 { http-host host values { www.itacs.de } } 1 { http-uri starts-with values { /somepath/somepath40 } } } actions add { 0 { forward select pool app.itacs.de } } ordinal 40 } } 
tmsh modify ltm policy Parse_HOST_and_URI_then_SELECT_NODE rules add { "Rule 41" { conditions add { 0 { http-host host values { www.itacs.de } } 1 { http-uri starts-with values { /somepath/somepath41 } } } actions add { 0 { forward select pool app.itacs.de } } ordinal 41 } } 
tmsh modify ltm policy Parse_HOST_and_URI_then_SELECT_NODE rules add { "Rule 42" { conditions add { 0 { http-host host values { www.itacs.de } } 1 { http-uri starts-with values { /somepath/somepath42 } } } actions add { 0 { forward select pool app.itacs.de } } ordinal 42 } } 
tmsh modify ltm policy Parse_HOST_and_URI_then_SELECT_NODE rules add { "Rule 43" { conditions add { 0 { http-host host values { www.itacs.de } } 1 { http-uri starts-with values { /somepath/somepath43 } } } actions add { 0 { forward select pool app.itacs.de } } ordinal 43 } } 
tmsh modify ltm policy Parse_HOST_and_URI_then_SELECT_NODE rules add { "Rule 44" { conditions add { 0 { http-host host values { www.itacs.de } } 1 { http-uri starts-with values { /somepath/somepath44 } } } actions add { 0 { forward select pool app.itacs.de } } ordinal 44 } } 
tmsh modify ltm policy Parse_HOST_and_URI_then_SELECT_NODE rules add { "Rule 45" { conditions add { 0 { http-host host values { www.itacs.de } } 1 { http-uri starts-with values { /somepath/somepath45 } } } actions add { 0 { forward select pool app.itacs.de } } ordinal 45 } } 
tmsh modify ltm policy Parse_HOST_and_URI_then_SELECT_NODE rules add { "Rule 46" { conditions add { 0 { http-host host values { www.itacs.de } } 1 { http-uri starts-with values { /somepath/somepath46 } } } actions add { 0 { forward select pool app.itacs.de } } ordinal 46 } } 
tmsh modify ltm policy Parse_HOST_and_URI_then_SELECT_NODE rules add { "Rule 47" { conditions add { 0 { http-host host values { www.itacs.de } } 1 { http-uri starts-with values { /somepath/somepath47 } } } actions add { 0 { forward select pool app.itacs.de } } ordinal 47 } } 
tmsh modify ltm policy Parse_HOST_and_URI_then_SELECT_NODE rules add { "Rule 48" { conditions add { 0 { http-host host values { www.itacs.de } } 1 { http-uri starts-with values { /somepath/somepath48 } } } actions add { 0 { forward select pool app.itacs.de } } ordinal 48 } } 
tmsh modify ltm policy Parse_HOST_and_URI_then_SELECT_NODE rules add { "Rule 49" { conditions add { 0 { http-host host values { www.itacs.de } } } actions add { 0 { forward select pool www.itacs.de } } ordinal 49 } }
0
placeholder+image

Hi Folks,

I've optimized the test routine a little bit, to get more accurate numbers. I've also performed several additional tests to compare the different LTM Policy strategies...

Slightly Optimized Pipeline

I've stripped the calculation iRule so that it just stores the data without performing any time consuming operations. In addition I've now included a check to see if the entire [HTTP::request] was received before releasing the [TCP::payload] and included the [TCP::notify request] command...

The new pipeline now look like that...

when CLIENT_ACCEPTED {
    set time("CLIENT_ACCEPTED-to-HTTP_REQUEST") [clock clicks]
    set time("CLIENT_ACCEPTED-to-CLIENT_DATA") [clock clicks]
    # Collect the HTTP requests to rule out any network latency. 
    TCP::collect
}
when CLIENT_DATA {
    # Additional check to make sure the entire HTTP request has arived
    if { [TCP::payload] contains "\r\n\r\n" } then {
        # Release the current HTTP requests if complete
        lappend time("CLIENT_ACCEPTED-to-CLIENT_DATA") [clock clicks]
        set time("CLIENT_DATA-to-HTTP_REQUEST") [clock clicks]
        TCP::release
        TCP::notify request
        TCP::collect
    } else {
        # Collect additional packets
        TCP::collect
    }
}

# HTTP Profile + LTM Policy or iRule

when HTTP_REQUEST priority 501 {
    lappend time("CLIENT_DATA-to-HTTP_REQUEST") [clock clicks]
    lappend time("CLIENT_ACCEPTED-to-HTTP_REQUEST") [clock clicks]
}

# Timestamp calculation iRule (now without the complex calculation on each request)

Test Setup

The Rule-Sets has remained identical. For the LTM Policy "All-Match" test, I've changed the default rule so that no overlappings would ocour.

The request rate has been decreased a little bit. Its now approximately 10 RPS but still a total of 1250 request for each test.

New Results

The trend remains the same. LTM Policies are somewhat faster than iRules. The new findings are...

  • When using a First-Match policy strategy, it seems now that it doesn't make any difference if the 1st or 50th rule was hitted. I've repeated this test multiple times to really get sure, but interestingly the 50th hit was now always one or two clicks faster than the 1st hit^^
  • Using First-Match, Best-Match or All-Match doesn't have any performance differences for the tested Rule-Set.

Image Text

Note: The outlined numbers are always the -10% cutoff values. Compare the different tests using the Min. values. It seems they are somewhat comparable. The Max values may still include some CPU spikes (even with cutoff calculation) and the Avg data seems to include an unknown mix off TMM connection parking situations.

Cheers, Kai

0
placeholder+image

There's also this article out there now - To iRule, or not to iRule: Introduction to Local Traffic Policies

0