69 lines
4.8 KiB
Text
69 lines
4.8 KiB
Text
[[sticky-sessions]]
|
|
=== Sticky sessions
|
|
|
|
Typical cluster deployment consists of the load balancer (reverse proxy) and 2 or more {project_name} servers on private network. For performance purposes,
|
|
it may be useful if load balancer forwards all requests related to particular browser session to the same {project_name} backend node.
|
|
|
|
The reason is, that {project_name} is using Infinispan distributed cache under the covers for save data related to current authentication session and user session.
|
|
The Infinispan distributed caches are configured with one owner by default. That means that particular session is saved just on one cluster node and the other nodes need
|
|
to lookup the session remotely if they want to access it.
|
|
|
|
For example if authentication session with ID `123` is saved in the Infinispan cache on `node1`, and then `node2` needs to lookup this session,
|
|
it needs to send the request to `node1` over the network to return the particular session entity.
|
|
|
|
It is beneficial if particular session entity is always available locally, which can be done with the help of sticky sessions.
|
|
The workflow in the cluster environment with the public frontend load balancer and two backend {project_name} nodes can be like this:
|
|
|
|
* User sends initial request to see the {project_name} login screen
|
|
* This request is served by the frontend load balancer, which forwards it to some random node (eg. node1). Strictly said, the node doesn't need to be random,
|
|
but can be chosen according to some other criterias (client IP address etc). It all depends on the implementation and configuration of underlying load balancer (reverse proxy).
|
|
* {project_name} creates authentication session with random ID (eg. 123) and saves it to the Infinispan cache.
|
|
* Infinispan distributed cache assigns the primary owner of the session based on the hash of session ID.
|
|
See link:https://infinispan.org/docs/8.2.x/user_guide/user_guide.html#distribution_mode[Infinispan documentation] for more details around this.
|
|
Let's assume that Infinispan assigned `node2` to be the owner of this session.
|
|
* {project_name} creates the cookie `AUTH_SESSION_ID` with the format like `<session-id>.<owner-node-id>` . In our example case, it will be `123.node2` .
|
|
* Response is returned to the user with the {project_name} login screen and the AUTH_SESSION_ID cookie in the browser
|
|
|
|
From this point, it is beneficial if load balancer forwards all the next requests to the `node2` as this is the node, who is owner of the authentication session with ID `123`
|
|
and hence Infinispan can lookup this session locally. After authentication is finished, the authentication session is converted to user session, which will be also saved on
|
|
`node2` because it has same ID `123` .
|
|
|
|
The sticky session is not mandatory for the cluster setup, however it is good for performance for the reasons mentioned above. You need to configure your loadbalancer to sticky
|
|
over the `AUTH_SESSION_ID` cookie. How exactly do this is dependent on your loadbalancer.
|
|
|
|
It is recommended on the {project_name} side to use the system property `jboss.node.name` during startup, with the value corresponding
|
|
to the name of your route. For example, `-Djboss.node.name=node1` will use `node1` to identify the route. This route will be used by
|
|
Infinispan caches and will be attached to the AUTH_SESSION_ID cookie when the node is the owner of the particular key. Here is
|
|
an example of the start up command using this system property:
|
|
[source]
|
|
----
|
|
cd $RHSSO_NODE1
|
|
./standalone.sh -c standalone-ha.xml -Djboss.socket.binding.port-offset=100 -Djboss.node.name=node1
|
|
----
|
|
|
|
Typically in production environment the route name should use the same name as your backend host, but it is not required. You can
|
|
use a different route name. For example, if you want to hide the host name of your {project_name} server inside your private network.
|
|
|
|
==== Disable adding the route
|
|
|
|
Some load balancers can be configured to add the route information by themselves instead of relying on the back end {project_name} node.
|
|
However, as described above, adding the route by the {project_name} is recommended. This is because when done this way performance improves,
|
|
since {project_name} is aware of the entity that is the owner of particular session and can route to that node, which is not necessarily the local node.
|
|
|
|
You are permitted to disable adding route information to the AUTH_SESSION_ID cookie by {project_name}, if you prefer, by adding the following
|
|
into your `RHSSO_HOME/standalone/configuration/standalone-ha.xml` file in the {project_name} subsystem configuration:
|
|
|
|
[source,xml]
|
|
----
|
|
<subsystem xmlns="urn:jboss:domain:keycloak-server:1.1">
|
|
...
|
|
<spi name="stickySessionEncoder">
|
|
<provider name="infinispan" enabled="true">
|
|
<properties>
|
|
<property name="shouldAttachRoute" value="false"/>
|
|
</properties>
|
|
</provider>
|
|
</spi>
|
|
|
|
</subsystem>
|
|
----
|