It is true that additional cases in rules may impact performance, but what makes you believe that complex direct node select expression is going to be any better? Moreover, the bulk of performance impact of rules is due to late-binding which is necessary in order to collect data for the loadbalancing decision. Rule evaluation (especially on a well structured rule set) is a minor portion of the CPU time spent on rules. The only expesive operation during rule evaluation is regular expression matching (which can be avoided in majority of cases). Data collection (such as extraction of http_uri, cookies, headers, etc.) is performed only once (on each request) and results are cached. They key to well performing rule set is proper structure. You need to:
a) filter as much as possible via virtual server matching. So, for
example matching server address or port in a rule used by a wildcard
virtual server delivers much worse performance than several
address/port specific virtual servers,
b) match common conditions only once,
c) test for the most likely cases first
d) use classes (as opposed to chains of if-then-elses) as much as
possible
Stretching capabilities of direct node select in a pool is not a good idea in general for (at least) 2 reasons:
1) the select statement cannot be stretched too far because the
expression on the right-hand side needs to return "node type" value,
which pretty mcuh prevents
any use of logical expressions,
2) even if it did allow the same flexibility as a rule, it would
definitely not deliver better performance, because it uses the same
evaluation engine.
Let me illustrate a little bit the performance aspect. Let's say that you have 2 layer structure, in which the first layer picks a pool and the second layer does additional checks and in some special cases picks a particular node. This can be implemented with a rule like this:
pool p1 {
member server1:port1
member server2:port1
}
pool pref_server1 {
member server1:port1 priority 10
member server2:port1
}
rule theRule {
if(top_level_expression1) {
if(special_case_expression1) {
use pool pref_server1
}
use pool pool1
} else
if(top_level_expression2) {
...
} else
if ...
}
Even if the same functionality could actually be implemented in a select statement, the above would deliver same or better performance than:
pool p1 {
select special_case_expression1_evaluating_to_node1;
member server1:port1
member server2:port1
}
rule theRule {
if(top_level_expression1) {
use pool pool1
} else
if(top_level_expression2) {
...
} else
if ...
}
If you post (at least) a mock-up of the configuration you are working on, I can help you to convert/improve it.
In any case, if flexibility and performance of iRules in 4.6 does not meet your requirements, you can always upgrade to BIG-IP version 9 which has significantly more flexible rule engine and also typically delivers much better performance than version 4.x on the same hardware. BIG-IP 540 is supported in version 9.2.