Forum Discussion

Simon_Wright_85's avatar
Simon_Wright_85
Icon for Nimbostratus rankNimbostratus
Dec 04, 2007

irule Performance question

Hi all

I have the following irule written on our test site and am going to be putting it on to our live one in the next week or two.

I just wanted to get some advice from people to see if i have written it in an efficient way or if i should be looking at alternative ways of doing things.

The basic idea behind the rule is that we currently have five tomcat clusters comprising of 2-4 servers in each and will be adding more in the future. The site has multiple subdomains pointing to it for use by our individual customers. Depending on which subdomain is used to access the site will determine which pool their request goes to. Each pool of servers can have several diffent sub domains that access it and from time to time depending on usage we may move them to a different pool. We manage this using datagroups for easy administration because we have several dozen subdomains for this site.

There is also a single pool for static content which has traffic directed to it depending on file extention.

The two areas i am concerned about is should i be reading in all of the datagroups in one go or should check the first and redirect if necessary followed by the second and so on. Also i am using an IF statement for this. Would a switch statement be better?

thanks in advance

Simon


when HTTP_REQUEST {
set g2filestypeIdx [matchclass [string tolower [HTTP::uri]] contains $::G2TestStaticFileTypes]
if { 0 != $g2filestypeIdx } {
pool G2TestWebClusterIIS80    
}
else {
set cluster1Idx [matchclass [string tolower [HTTP::host]] contains $::G2TestCluster1]
set cluster2Idx [matchclass [string tolower [HTTP::host]] contains $::G2TestCluster2]
set cluster3Idx [matchclass [string tolower [HTTP::host]] contains $::G2TestCluster3]
set cluster4Idx [matchclass [string tolower [HTTP::host]] contains $::G2TestCluster4]
set cluster5Idx [matchclass [string tolower [HTTP::host]] contains $::G2TestCluster5]
if { 0 != $cluster1Idx }
{
if { [HTTP::host] contains "reports." }
{
pool G2TestWebCluster1Reports
}
else {
pool G2TestWebCluster1Tomcat8080
}
}
elseif { 0 != $cluster2Idx }
{
if { [HTTP::host] contains "reports." }
{
pool G2TestWebCluster2Reports
}
else {
pool G2TestWebCluster2Tomcat8080
}
}
elseif { 0 != $cluster3Idx }
{
if { [HTTP::host] contains "reports." }
{
pool G2TestWebCluster3Reports
}
else {
pool G2TestWebCluster3Tomcat8080
}
}
elseif { 0 != $cluster4Idx }
{
if { [HTTP::host] contains "reports." }
{
pool G2TestWebCluster4Reports
}
else {
pool G2TestWebCluster4Tomcat8080
}
}
elseif { 0 != $cluster5Idx }
{
if { [HTTP::host] contains "reports." }
{
pool G2TestWebCluster5Reports
}
else {
pool G2TestWebCluster5Tomcat8080
}
}
}
}

2 Replies

  • I'll ditto Colin's comments. I've got a few more as well.

    1. Try to avoid unnecessary processing

    2. Try to avoid unnecessary use of session variables.

    With that said, here's an equivalent iRule (you better double check though) that only uses one local variable. I figured since you were doing a "string tolower" on the [HTTP::host] value in each check, it would be a bit more efficient to do it once and store it. It's probably a wash but I think it reads better personally... I didn't do it for the first "string tolower" on the "HTTP::uri" as that was done only once.

    when HTTP_REQUEST {
      set host [string tolower [HTTP::host]]
      if { 0 != [matchclass [string tolower [HTTP::uri]] contains $::G2TestStaticFileTypes] } {
        pool G2TestWebClusterIIS80    
      } elseif { 0 != [matchclass $host contains $::G2TestCluster1] } {
        if { [HTTP::host] contains "reports." } {
          pool G2TestWebCluster1Reports
        } else {
          pool G2TestWebCluster1Tomcat8080
        }
      } elseif { 0 != [matchclass $host contains $::G2TestCluster2] } {
        if { [HTTP::host] contains "reports." } {
          pool G2TestWebCluster2Reports
        } else {
          pool G2TestWebCluster2Tomcat8080
        }
      } elseif { 0 != [matchclass $host contains $::G2TestCluster3] } {
        if { [HTTP::host] contains "reports." } {
          pool G2TestWebCluster3Reports
        } else {
          pool G2TestWebCluster3Tomcat8080
        }
      } elseif { 0 != [matchclass $host contains $::G2TestCluster4] } {
        if { [HTTP::host] contains "reports." } {
          pool G2TestWebCluster4Reports
        } else {
          pool G2TestWebCluster4Tomcat8080
        }
      } elseif { 0 != [matchclass $host contains $::G2TestCluster5] } {
        if { [HTTP::host] contains "reports." } {
          pool G2TestWebCluster5Reports
        } else {
          pool G2TestWebCluster5Tomcat8080
        }
      }
    }

    Now, not that you want to go this route, but here's an alternate solution that makes use of a couple of variables and dynamic pool names that may or may not help you in the future.

    when HTTP_REQUEST {
      set host [string tolower [HTTP::host]]
      set idx 0
      if { 0 != [matchclass [string tolower [HTTP::uri]] contains $::G2TestStaticFileTypes] } {
        pool G2TestWebClusterIIS80    
      } elseif { 0 != [matchclass $host contains $::G2TestCluster1] } {
        set idx 1
      } elseif { 0 != [matchclass $host contains $::G2TestCluster2] } {
        set idx 2
      } elseif { 0 != [matchclass $host contains $::G2TestCluster3] } {
        set idx 3
      } elseif { 0 != [matchclass $host contains $::G2TestCluster4] } {
        set idx 4
      } elseif { 0 != [matchclass $host contains $::G2TestCluster5] } {
        set idx 5
      }
      if { 0 != idx } {
        if { $host contains "reports." } {
          set pool_name "G2TestWebCluster${idx}Reports"
        } else {
          set pool_name "G2TextWebCluster${idx}Tomcat8080"
        }
        if { [catch { pool $pool_name } ] } { 
          log local0. "Error assinging pool to $pool_name"
        }
      }
    }

    There are ways to optimize this as well, but I thought I'd throw it out there for the fun of it. Notice the catch command surrounding the pool assignment. This is done because when using variable names, you do not have the benefit of config time parsing errors for pools that aren't defined. The catch will cause the iRule to not halt it's processing due to the error it would produce if the pool didn't exist.

    Hope this helps...

    -Joe
  • Hi guys

     

     

    Thanks for the excelent feedback its exactly the kind of thing i was looking for. I will add your suggestions to the irule i have here.

     

     

    Cheers

     

     

    Simon