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

Filter by:
  • Solution
  • Technology
Answers

comparison other than equals

Looks like irules only support equals and not equals. Is there any way to simulate greater than and less than.

The problem.

We have a web site w/ 240 virtual directories. We want to change to distributiong to 4 web servers. So essentially I want to say something like (in Englis)
for urils who start w/ anthying less than "Ko" goto web 1 else if it start w/ anyting less than "ME" goto web to, etc....

I really want to go to the 2nd letter so I can evenly distribute.

Thanks.
0
Rate this Question

Answers to this Question

placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER
You should be able to do this with string compare (Click here):


% set string1 abc
abc
% set string2 abd
abd
% string compare $string1 $string2
-1
% string compare $string2 $string1
1
% string compare $string1 $string1
0


There might be a more efficient way of doing this though. Is there any advantage to sending requests for the same virtual directory to the same pool member? If not, could you just use least connections load balancing and distribute the requests to any node, regardless of which URI is requested?

Aaron
0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER
Thanks Aaaron
0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER
I just noticed the why question.

Our problem is that each virtual directory is attached to a Microsoft IIS application pool. With that many appliations on one IIS server, resource issues are occuring if too many applications have active users at any one time. We want to split the load among multiple servers in such a way that there is Zero chance that any one server will load more than a certain number of applications. It is not a load issue on the application, but an IIS issue w/ the number of .Net applications that can be loaded at any one time..

I know I might be asking too much, but do you have any good samples of how I fit the string compare statements into an irule that is based on URI?
0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER
Okay, I understand why you're trying to route requests to a specific server based on the requested URI. It might be easiest to create one pool per "application", create a string datagroup which has the URI tokens and the corresponding pool and then use a rule to look up the corresponding pool based on the requested URI. Having a pool per app allows you to use multiple servers to host an application and load balance between them.

If this option sounds good for you, I can give you more detailed info on configuring the various objects. If not, can you elaborate?

Thanks,
Aaron
0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER
Hi Aaron.

I fear the amount of configuration for that approach. It would mean adding 200+pools to the LTM (which already has a pretty large configuration). It would also mean LTM configuration everytime a new virtual directory was added to the web server (a fairly regular occassion).

I think the string compare has potential but might need some help getting started.

Sorry to be such a bother. I was just hoping there was a fairly simple way to say break the list of apps down alphabetibally and say the first 25% went to server A, the next to Server B, etc....
0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER
How about combining the two approaches so that you say paths starting with /?A-/?F go to pool 1, /?G-/?M to pool 2, /?N-/?T to pool 3 and /?U-/?Z to pool 4?

Something like this?


when HTTP_REQUEST {

# Parse the third character in the path
switch [string tolower [string range [HTTP::path]] 2 2] {

a - b - c - d - e - f {
pool pool_a_f
}
g - h - i - j - k - l - m {
pool pool_g_m
}
n - o - p - q - r - s - t {
pool pool_n_t
}
u - v - w - x - y - z {
pool pool_u_z
}
default {
# Requested URI was less than three characters long
pool pool_default
}
}
}


Aaron
0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER
Hi Aaron.

This looks great. Will this syntax do it by the first letter of the URI? Is the default to cover the case w/ no URI?
0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER
Sorry, when first wrote the example, I was parsing the second character in the URI. I reread your initial post and saw that you wanted to parse the third character (second after the leading forward slash), so I updated the string range, but didn't update the comments. "Parse the second character in the path" should be third.

The idea is that the first character from the path will be the leading forward slash. This is index 0. So you can take the third character (index 2), set it to lower case for the pool selection, and then select the pool based on this character. And yes, the default is there to catch any requests where the path is less than three characters long.

For details on the switch command syntax, you can check the man page (Click here).

Aaron
0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER
Hi Aaron,

The initial thought was that I would need to get to the 2nd character to equal sized chunks.

I.e if URI was from AA to DL goto pool A, if it was from DM to LI pool B, etc...

So I was not wanting to key of the 2nd character but the first 2. Given the amount of complexity that will add and after further analysys, I am ok with just keying off the first letter based on the distribution of site names.

I am now in syntax hell.

Here is what I have:

when HTTP_REQUEST {
# Parse the fist character in the path
switch {[string tolower [string range [HTTP::path]] 2 1] {
a - b - c {pool test1
}
d - e - f - g - h - i - j - k - l {pool test2
}
m - n - o - p - q - r {pool test3
}
s - t - u - v - w - x - y - z {pool test4
}
default {
# Requested URI was a leading forward slash only
pool test5
}
}
}

And here is the LTM error message


01070151:3: Rule [test] error:
line 1: [parse error: missing close-brace] [{
# Parse the fist character in the path
switch {[string tolower [string range [HTTP::path]] 2 1] {
a - b - c {pool test1
}
d - e - f - g - h - i - j - k - l {pool test2
}
m - n - o - p - q - r {pool test3
}
s - t - u - v - w - x - y - z {pool test4
}
default {
# Requested URI was a leading forward slash only
pool test5
}
}
}]
line 3: [command is not valid in the current scope] [switch {[string tolower [string range [HTTP::path]] 2 1] {
a - b - c {pool test1
}
d - e - f - g - h - i - j - k - l {pool test2
}
m - n - o - p - q - r {pool test3
}
s - t - u - v - w - x - y - z {pool test4
}
default {
# Requested URI was a leading forward slash only
pool test5
}
}
}]

Thanks again for all the help.
0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER
Can you try this?


when HTTP_REQUEST {

# Parse the second character in the path
switch [string tolower [string range [HTTP::path] 1 1]] {
a - b - c {
pool test1
}
d - e - f - g - h - i - j - k - l {
pool test2
}
m - n - o - p - q - r {
pool test3
}
s - t - u - v - w - x - y - z {
pool test4
}
default {
# Requested URI was a leading forward slash only
pool test5
}
}
}


And I need to work on my reading comprehension. I'll see about an example to parse the first two characters as you originally mentioned...

Aaron
0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER
The error is that you have an opening brace before the switch argument (before the string tolower command). Remove that and the error should go away.

One more thing, if you use the glob option on switch, you can eliminate the string allocations that are caused by the string range and tolower commands.

This should be equivalent, but likely a bit more optimal.

hen HTTP_REQUEST {
# Parse the fist character in the path
switch -glob [HTTP::path] {
"/[a-cA-C]*" {
pool test1
}
"/[d-lD-L]*" {
pool test2
}
"/[m-rM-R]*" {
pool test3
}
"/[s-zS-Z]*" {
pool test4
}
default {
# Requested URI was a leading forward slash only
pool test5
}
}
}


Hope this helps...

-Joe
0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER
Hi Joe,

That helps very much . Thanks for the suggestion. Originally I had considered using character ranges, but didn't see them mentioned on the man page for switch. I wasn't thinking about glob matching So I was just starting to futz around with an if/elseif... with string compare. Your solution is much cleaner..

Thanks,
Aaron
0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER
the -glob argument for switch put's it in "string match" compatibility mode. If you check out the docs for "string match", you'll see the options:

http://www.tcl.tk/man/tcl8.5/TclCmd/string.htm#M40
Click here


-Joe
0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER
Joe and Aaron,

You guys rock.

I have a proof of concept working w/ Aaron's

Joe's seems to all fall through to the default statement. Any chance of a syntax error in the glob?

0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER
I got Joe's version working. * missing from rules other than first one in example. Thanks again guys.
0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER
Doh! Sorry about that. I re-typed it from when I was testing it and must have left those out. I've updated my post with the fix.

-Joe
0