Forum Discussion

mcris2812's avatar
mcris2812
Icon for Altostratus rankAltostratus
Dec 15, 2022
Solved

Session persistence based on http header for machine to machine calls

Hi,

Can you please help me understand what would be required(or if it is even possible) to support the following scenario:

BackendApplication(not a browser) ->API Gateway -> LB -> App Node 1, App Node 2, AppNode 3.  

I need to have the requests sent by a backend application to be routed to the same App Node based on a custom http header containing a message identifier(something similar with a session id) that is included in the request.

Before reaching the LB, the request goes through an application gateway that has multiple nodes. This means that it is possible for multiple requests with the same message identifier to reach the LB from different source ips.

Is it required that all requests with the same message identifier to be forwarded by the same gateway node for the LB to be able to do a session persistence based on the message identifier?

Can the session persistence be done by defining a custom irule that uses the message identifier from the request header?

Thank-you!

 

 

 

  • Awesome!

    Thank-you very much for your help!

6 Replies

  • I think you could be able to achieve this with cookie passive persistence 
    Otherwise, you can script an iRule that does this, with universal persistence profile

     

    when HTTP_REQUEST {
      if {[HTTP::header exists "Your header here"]}{
        if {[HTTP::header "your header here"] ne ""}{ persist add uie [HTTP::header "Your header here"] }
      }
    }

     

     

    I haven't tested this script, please do before installing 

    • mcris2812's avatar
      mcris2812
      Icon for Altostratus rankAltostratus

      Hi,

      Thank-you very much for your quick reply.

      One last thing that I want to confirm: the fact the the requests(with same msg id) will come from different api gw nodes(with different IPs)  shouldn't matter right? There is no requirement to have same source ip sending the requests to the LB, the LB should be able to figure out the destination node just by using the msg id from the header?

      Thanks!

  • Hi Mcris,

    tweaking your session persistence accordingly depends of a couple factors.

    1.) Are HTTP keep-alive sessions in use where a singe client-side TCP session needs to be forwarded to App1, App2 or App3 on a per request-basis?

    2.) Does every single request contains the HTTP header? What should happen if the HTTP header is missing?

    3.) How should a request become load balanced if the HTTP header routing was never used before?

    4.) What should happen if the HTTP header was not seen for X minutes/hours/years? Should it still persist? 

    5.) Do you have any special requirement in the case of Failovers and Failbacks?

    6.) Could you provide a sample of those message identifier headers?

    Cheers, Kai

         

    • mcris2812's avatar
      mcris2812
      Icon for Altostratus rankAltostratus

      Hi Kai_Wilke,

      Answers below in green:

      1.) Are HTTP keep-alive sessions in use where a singe client-side TCP session needs to be forwarded to App1, App2 or App3 on a per request-basis?

      No, we don't use keep alive sessions.

      2.) Does every single request contains the HTTP header? What should happen if the HTTP header is missing?

      Yes, It will actually be set by the API GW before forwarding the request to the LB

      3.) How should a request become load balanced if the HTTP header routing was never used before?

      I guess the LB should just send the request to any one of the nodes in the pool(use the default round robin strategy).

      4.) What should happen if the HTTP header was not seen for X minutes/hours/years? Should it still persist? 

      Same as for 3.

      5.) Do you have any special requirement in the case of Failovers and Failbacks?

      I guess in this case the session will be lost and a new one should the created with another available node from the pool.

      6.) Could you provide a sample of those message identifier headers?

      We can be quite flexible here. The API GW can even create a cookie header like Cookie: MsgId={id}.

      Thank-you!

      • Kai_Wilke's avatar
        Kai_Wilke
        Icon for MVP rankMVP

        Hi Mcris,

        based on your answers i would like to recommend CARP.

        CARP based distribution is a load balancing method which distributes load based on a given "INPUT" value that a transaction carries with. If all you requests are getting tagged by the API GW, then you could use the tag as input for load-balaing decission.

         

        when HTTP_REQUEST {
        	if { [HTTP::header value "API-GW-Tag"] ne "" } then {
        		persist carp [HTTP::header value "API-GW-Tag"]
        	} elseif { [HTTP::cookie value "API-GW-Tag"] ne "" } then {
        		persist carp [HTTP::cookie value "API-GW-Tag"]
        	} else {
        		persist none
        	}
        }  

         

        Benefits of this method is simplificy, a good balacing of independent Tags (the more unique tags the better the balacing will be) and a guaranteed binding of a given Tag value to one Pool member. Using CARP your F5 dont need to track anything in Memory which may time out...

        You may additionally enable OneConnect in combination with CARP. It will slightly boost the performance of your non Keep-Alive sessions (backend connection to the API will be pooled) and also allowes CARP to work in combination with Keep-Alive sessions (true per request balancing).

        Cheers, Kai