Hi All!
I don't see a lot of documentation about sticky sessions implementation, so I have a couple of questions:
- Does traefik generates sticky session itself or it just reuses cookie value that's already there, for example jsessionid?
- if traefik can generate sticky session cookie, what it uses for value? some instance-id?
- if request goes to another traefik instance node, does it understand existing sticky session cookie or it creates new?
Also let's look from specific architecture.
Approach 1. Classic sticky sessions.
- Java Tomcat backend generates jsessionid cookie
- Traefik remembers combination jsessionid:server-instance-id and puts it in memory
- Client sends new request with same jsessionid cookie value
- Traefik looks up in memory map, finds corresponding server-instance-id and routes request
- Traefik sends combination jsessionid:server-instance-id to other instances of Traefik cluster in background.
Main disadvantage: each session requires in memory space of each traefik node. This information must be synched between traefik nodes.
Which generally not linearly scalable.
Approach 2. Lightweight sticky sessions:
- Client sends request to traefik
- Traefik doesn't see any sticky session cookie, sends request to some backend node
- Backend node responds,
- Traefik discovers no session cookie value.
- Traefik generates it's own sticky session cookie value which is just a server-instance-id
- Client sends another request to traefik
- Traefik reads cookie and just routes request to specified server-instance-id
Ideal solution, no cons. Any traefik node may serve any request with sticky session cookie and route request without any additional in memory map. It only requires mapping server-instance-id - host:port, which is already inside traefik node.
Question:
Is it possible to use approach 2 with traefik?
Some additional info:
I'm trying to build client/server architecture that uses docker, traefik, spring mvc and websockets via sockjs. SockJS has special fallback option which switches communication from websockets to streaming or http polling. In latter case multiple http request might be sent from a client. As I understand server implementation expects them all to route to the same backend instance, otherwise they won't be properly handled, for example server messages would not arrive to client, because client request was handled by another instance.
SockJS documentation is vague, but it mentions that every request contains server-id as part of an url:
All transport requests have the following URL structure:
http://host:port/myApp/myEndpoint/{server-id}/{session-id}/{transport}
-
{server-id}
- useful for routing requests in a cluster but not used otherwise. -
{session-id}
- correlates HTTP requests belonging to a SockJS session. -
{transport}
- indicates the transport type, e.g. "websocket", "xhr-streaming", etc.
Another question:
Is it possible to route to specific backend service node using server-instance-id from client http request. (server-instance-id may be extracted from url as shown above, or we can just add it as a cookie, as http header, as request parameter - any way, we have complete control over both server/client sides)