Forum Discussion
Persist based on query string
Our QA team needs a way to specify a backend node via a query string and have all subsequent queries persist to that node for testing purposes.
I have written the following irule which send the request to a specified node - the problem is that associated requests to things like images, javascript, style sheets don't match the irule and thus get sent to a random backend web server:
DESCRIPTION:
This if the URI contains a query parameter named server this irule attempts
to match the server name to a datagroup named servername2ip_datagroup and
use that to send the user to the appropriate back end server.
1) This rule relies on the servername2ip_datagroup datagroup. Which is a
server name to IP datagroup on the load balancer. This needs to be maintained
/ updated as server IPs or names change.
when HTTP_REQUEST {
If the uri contains a query parameter named server
if { [HTTP::uri] contains "server" } {
Define a lowercase variable to store the server name
set webserver [URI::query [string tolower [HTTP::uri]] server]
Define a variable to store the port to make this rule https/http agnostic
set prt [TCP::local_port]
If the server query parameter matches an entry in the datagroup
if { [class match $webserver equals servername2ip_datagroup] } {
Direct traffic to that node.
node [class lookup $webserver servername2ip_datagroup] $prt
}
}
}
I think perhaps I need to add persistence after: node [class lookup $webserver servername2ip_datagroup] $prt
I tried adding persist source_addr 1800
But that's not working. Can any irule guru's out there help me get this working. Is persistence what I need - if so what's wrong with how I'm using it?
Thanks Brad
- Vijay_ECirrus
Your iRule seems to be just performing a load balancing decision and not persisting. So, you can use something like this:
when HTTP_REQUEST { If the uri contains a query parameter named server if { [HTTP::uri] contains "server" } { Define a lowercase variable to store the server name set webserver [URI::query [HTTP::uri]] If the server query parameter matches an entry in the datagroup if { [class match $webserver equals servername2ip_datagroup] } { pool POOL_WITH_NODE } } }
- jgranieriNimbostratus
If you are trying to persist based off of a string use a line similar to this, the value after the variable is how long the persisted string should remain in the UIE table.
persist uie $variable 518400
- Brad_BakerCirrus
This sort of seems to be working:
Direct traffic to that node. pool [LB::server pool] member [class lookup $webserver servername2ip_datagroup] $prt persist uie $webserver 518400
The first request for index.php goes to the correct node, whereas the resources (css, js, images) go to a random backend server. If I refresh the page though all requests seem to go to the correct server.
I don't suppose there's a way to make it work consistently for the very first request?
- Vijay_ECirrus
You don't need persistence, if you are selecting a pool member based on the query string value. I misunderstood your initial request.
I am assuming, you are sending it to port 80 on the pool member and this could work:
when HTTP_REQUEST { if { [HTTP::uri] contains "server" } { set query_value [URI::query [string tolower [HTTP::uri]] server] pool [LB::server pool] [member $query_value 80] } }
- Brad_BakerCirrus
You're right that persistence doesn't seem to be required for this to work but the issue I mention above still exists. So for example:
1st Request
URL: index.php?server=web-server1 Resource: index.php Served by: web-server1 Resource: mylogo.jpg Served by: web-server2 Resource: index.css Served by: web-server2
2st Request and subsequent requests (refresh)
URL: index.php?server=web-server1 Resource: index.php Served by: web-server1 Resource: mylogo.jpg Served by: web-server1 Resource: index.css Served by: web-server1
I'm assuming this behavior is perhaps due to chrome and other browsers making parallel requests and thus even though I've set a pool member it doesn't honor it for all requests until I refresh a second time? If so I'm wondering if that's avoidable anyway?
- Vijay_ECirrus
Did you try enabling OneConnect ?
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