web-dev-qa-db-fra.com

Keycloak: configuration de magasin à distance pour un cluster Infinispan dédié

Récemment, j'ai renforcé mon déploiement Keycloak pour utiliser un cluster Infinispan dédié en tant que remote-store pour une couche supplémentaire de persistance pour les différents caches de Keycloak. Le changement lui-même s'est assez bien passé, bien qu'après avoir effectué ce changement, nous avons commencé à voir beaucoup d'erreurs de connexion en raison du expired_code Message d'erreur:

WARN [org.keycloak.events] (default task-2007) type=LOGIN_ERROR, realmId=my-realm, clientId=null, userId=null, ipAddress=192.168.50.38, error=expired_code, restart_after_timeout=true

Ce message d'erreur est généralement répété des dizaines de fois dans une courte période et à partir de la même adresse IP. La cause de cela semble être le navigateur de l'utilisateur final qui redirige à l'infini à la connexion jusqu'à ce que le navigateur lui-même arrête la boucle.

J'ai vu divers problèmes GitHub ( https://github.com/helm/charts/issues/8355 ) qui documentent également ce comportement, et le consensus semble être que cela est causé par le cluster Keycloak impossible de découvrir correctement ses membres via JGroups.

Cette explication est logique lorsque vous considérez que certains des caches Keycloak sont distribués sur les nœuds Keycloak dans la configuration par défaut dans standalone-ha.xml. Cependant, j'ai modifié ces caches en caches locaux avec un remote-store pointant vers mon nouveau cluster Infinispan, et je pense avoir émis des hypothèses incorrectes sur la façon dont cela fonctionne, provoquant le début de cette erreur.

Voici comment mes caches Keycloak sont configurés:

<subsystem xmlns="urn:jboss:domain:infinispan:7.0">
    <cache-container name="keycloak" module="org.keycloak.keycloak-model-infinispan">
        <transport lock-timeout="60000"/>
        <local-cache name="realms">
            <object-memory size="10000"/>
        </local-cache>
        <local-cache name="users">
            <object-memory size="10000"/>
        </local-cache>
        <local-cache name="authorization">
            <object-memory size="10000"/>
        </local-cache>
        <local-cache name="keys">
            <object-memory size="1000"/>
            <expiration max-idle="3600000"/>
        </local-cache>
        <local-cache name="sessions">
            <remote-store cache="sessions" remote-servers="remote-cache" fetch-state="false" passivation="false" preload="false" purge="false" shared="true">
                <property name="rawValues">
                    true
                </property>
                <property name="marshaller">
                    org.keycloak.cluster.infinispan.KeycloakHotRodMarshallerFactory
                </property>
            </remote-store>
        </local-cache>
        <local-cache name="authenticationSessions">
            <remote-store cache="authenticationSessions" remote-servers="remote-cache" fetch-state="false" passivation="false" preload="false" purge="false" shared="true">
                <property name="rawValues">
                    true
                </property>
                <property name="marshaller">
                    org.keycloak.cluster.infinispan.KeycloakHotRodMarshallerFactory
                </property>
            </remote-store>
        </local-cache>
        <local-cache name="offlineSessions">
            <remote-store cache="offlineSessions" remote-servers="remote-cache" fetch-state="false" passivation="false" preload="false" purge="false" shared="true">
                <property name="rawValues">
                    true
                </property>
                <property name="marshaller">
                    org.keycloak.cluster.infinispan.KeycloakHotRodMarshallerFactory
                </property>
            </remote-store>
        </local-cache>
        <local-cache name="clientSessions">
            <remote-store cache="clientSessions" remote-servers="remote-cache" fetch-state="false" passivation="false" preload="false" purge="false" shared="true">
                <property name="rawValues">
                    true
                </property>
                <property name="marshaller">
                    org.keycloak.cluster.infinispan.KeycloakHotRodMarshallerFactory
                </property>
            </remote-store>
        </local-cache>
        <local-cache name="offlineClientSessions">
            <remote-store cache="offlineClientSessions" remote-servers="remote-cache" fetch-state="false" passivation="false" preload="false" purge="false" shared="true">
                <property name="rawValues">
                    true
                </property>
                <property name="marshaller">
                    org.keycloak.cluster.infinispan.KeycloakHotRodMarshallerFactory
                </property>
            </remote-store>
        </local-cache>
        <local-cache name="loginFailures">
            <remote-store cache="loginFailures" remote-servers="remote-cache" fetch-state="false" passivation="false" preload="false" purge="false" shared="true">
                <property name="rawValues">
                    true
                </property>
                <property name="marshaller">
                    org.keycloak.cluster.infinispan.KeycloakHotRodMarshallerFactory
                </property>
            </remote-store>
        </local-cache>
        <local-cache name="actionTokens">
            <remote-store cache="actionTokens" remote-servers="remote-cache" fetch-state="false" passivation="false" preload="false" purge="false" shared="true">
                <property name="rawValues">
                    true
                </property>
                <property name="marshaller">
                    org.keycloak.cluster.infinispan.KeycloakHotRodMarshallerFactory
                </property>
            </remote-store>
        </local-cache>
        <replicated-cache name="work">
            <remote-store cache="work" remote-servers="remote-cache" fetch-state="false" passivation="false" preload="false" purge="false" shared="true">
                <property name="rawValues">
                    true
                </property>
                <property name="marshaller">
                    org.keycloak.cluster.infinispan.KeycloakHotRodMarshallerFactory
                </property>
            </remote-store>
        </replicated-cache>
    </cache-container>
    <cache-container name="server" aliases="singleton cluster" default-cache="default" module="org.wildfly.clustering.server">
        <transport lock-timeout="60000"/>
        <replicated-cache name="default">
            <transaction mode="BATCH"/>
        </replicated-cache>
    </cache-container>
    <cache-container name="web" default-cache="dist" module="org.wildfly.clustering.web.infinispan">
        <transport lock-timeout="60000"/>
        <distributed-cache name="dist">
            <locking isolation="REPEATABLE_READ"/>
            <transaction mode="BATCH"/>
            <file-store/>
        </distributed-cache>
    </cache-container>
    <cache-container name="ejb" aliases="sfsb" default-cache="dist" module="org.wildfly.clustering.ejb.infinispan">
        <transport lock-timeout="60000"/>
        <distributed-cache name="dist">
            <locking isolation="REPEATABLE_READ"/>
            <transaction mode="BATCH"/>
            <file-store/>
        </distributed-cache>
    </cache-container>
    <cache-container name="hibernate" module="org.infinispan.hibernate-cache">
        <transport lock-timeout="60000"/>
        <local-cache name="local-query">
            <object-memory size="10000"/>
            <expiration max-idle="100000"/>
        </local-cache>
        <invalidation-cache name="entity">
            <transaction mode="NON_XA"/>
            <object-memory size="10000"/>
            <expiration max-idle="100000"/>
        </invalidation-cache>
        <replicated-cache name="timestamps"/>
    </cache-container>
</subsystem>

Notez que la plupart de cette configuration de cache est inchangée par rapport à la valeur par défaut standalone-ha.xml fichier de configuration. Les modifications que j'ai apportées ici modifient les caches suivants en local et les pointent vers mon cluster Infinispan distant:

  • sessions
  • authenticationSessions
  • offlineSessions
  • clientSessions
  • offlineClientSessions
  • loginFailures
  • actionTokens
  • work

Voici la configuration de mon remote-cache serveur:

<socket-binding-group name="standard-sockets" default-interface="public" port-offset="${jboss.socket.binding.port-offset:0}">
    <!-- Default socket bindings from standalone-ha.xml are not listed here for brevity -->
    <outbound-socket-binding name="remote-cache">
        <remote-destination Host="${env.INFINISPAN_Host}" port="${remote.cache.port:11222}"/>
    </outbound-socket-binding>
</socket-binding-group>

Voici comment mes caches sont configurés du côté d'Infinispan:

<subsystem xmlns="urn:infinispan:server:core:9.4" default-cache-container="clustered">
    <cache-container name="clustered" default-cache="default">
        <transport lock-timeout="60000"/>
        <global-state/>
        <replicated-cache-configuration name="replicated-keycloak" mode="SYNC">
            <locking acquire-timeout="3000" />
        </replicated-cache-configuration>
        <replicated-cache name="work" configuration="replicated-keycloak"/>
        <replicated-cache name="sessions" configuration="replicated-keycloak"/>
        <replicated-cache name="authenticationSessions" configuration="replicated-keycloak"/>
        <replicated-cache name="clientSessions" configuration="replicated-keycloak"/>
        <replicated-cache name="offlineSessions" configuration="replicated-keycloak"/>
        <replicated-cache name="offlineClientSessions" configuration="replicated-keycloak"/>
        <replicated-cache name="actionTokens" configuration="replicated-keycloak"/>
        <replicated-cache name="loginFailures" configuration="replicated-keycloak"/>
    </cache-container>
</subsystem>

Je crois que j'ai fait des hypothèses erronées sur le fonctionnement des caches locaux avec des magasins distants, et j'espérais que quelqu'un serait en mesure de clarifier cela pour moi. Mon intention était de faire du cluster Infinispan la source de vérité pour tous les caches de Keycloak. En rendant chaque cache local, j'ai supposé que les données seraient répliquées sur chaque nœud Keycloak via le cluster Infinispan, de sorte qu'une écriture dans le cache local authenticationSessions sur keycloak-0 serait synchronisé avec persistance à keycloak-1 via le cluster Infinispan.

Je pense que l'écriture dans un cache local sur Keycloak n'est pas synchrone par rapport à la persistance de cette valeur dans le cluster Infinispan distant. En d'autres termes, lorsqu'une écriture est effectuée dans le cache authenticationSessions, elle ne se bloque pas en attendant que cette valeur soit écrite dans le cluster Infinispan, donc une lecture immédiate de ces données sur un autre nœud Keycloak entraîne un cache miss, localement et dans le cluster Infinispan.

Je cherche de l'aide pour identifier pourquoi ma configuration actuelle est à l'origine de ce problème, et des éclaircissements sur le comportement d'un remote-store - existe-t-il un moyen d'obtenir des écritures de cache dans un cache local soutenu par un remote-store pour être synchrone? Sinon, y a-t-il une meilleure façon de faire ce que j'essaie d'accomplir ici?

Quelques autres détails potentiellement pertinents:

  • Keycloak et Infinispan sont tous deux déployés dans le même espace de noms dans un cluster Kubernetes.
  • J'utilise KUBE_PING pour la découverte de JGroups.
  • En utilisant la console Infinispan, je suis en mesure de vérifier que tous les caches répliqués sur tous les nœuds Infinispan contiennent une certaine quantité d'entrées - ils ne sont pas complètement inutilisés.
  • Si j'ajoute un nouveau domaine à un nœud Keycloak, il apparaît avec succès sur d'autres nœuds Keycloak, ce qui m'amène à croire que le cache work se propage sur tous les nœuds Keycloak.
  • Si je me connecte à un nœud Keycloak, ma session reste sur d'autres nœuds Keycloak, ce qui m'amène à croire que les caches liés à la session sont propagés sur tous les nœuds Keycloak.
  • J'utilise des sessions persistantes pour Keycloak comme correctif temporaire pour cela, mais je pense que la résolution de ces problèmes de cache sous-jacents est une solution plus permanente.

Merci d'avance!

9
Michael Parker

Je vais essayer de clarifier certains points à prendre en compte lors de la configuration de Keycloak en cluster.

Parlant du sujet de "redirections infinies" , j'ai rencontré un problème similaire dans les environnements de développement il y a des années. Alors que l'équipe de keycloak a corrigé plusieurs bugs liés aux boucles infinies (par exemple KEYCLOAK-5856 , KEYCLOAK-5022 , KEYCLOAK-4717 , KEYCLOAK-4552 , KEYCLOAK-3878 ) parfois, cela se produit en raison de problèmes de configuration.

Une chose pour vérifier si le site est HTTPS est d'accéder également à un serveur Keycloak par HTTPS.

Je me souviens avoir subi un problème similaire à la boucle infinie lorsque le Keycloak a été placé derrière un proxy inverse HTTPS et que les en-têtes nécessaires n'ont pas été propagés au Keycloak (en-têtes X-FOWARDED ...). Il a été résolu en configurant bien l'environnement. Il peut se produire un problème similaire lorsque la découverte de nœuds dans le cluster ne fonctionne pas correctement (JGroups).

À propos du message d'erreur "expired_code" , je vérifierais que les horloges de chaque nœud sont synchronisées car cela peut conduire à ce type d'erreur de jeton/code expiré .

Maintenant, en comprenant mieux votre configuration, il ne semble pas inapproprié d'utiliser le mode "local-cache" avec un magasin distant, pointant vers le cluster infinispan.

Bien que, généralement, le magasin partagé (tel qu'un cache distant) est généralement utilisé avec un cache d'invalidation où il est évité de répliquer les données complètes par le cluster (voir le commentaire qui peut être appliqué ici https://developer.jboss.org/message/986847#986847 ), il ne peut pas y avoir de grandes différences avec un cache distribué ou d'invalidation.

Je crois qu'un cache distribué avec un magasin distant s'appliquerait mieux (ou un cache d'invalidation pour éviter de répliquer des données lourdes aux propriétaires) mais je ne pouvais pas garantir le fonctionnement d'un "cache local" avec un stockage distant (partagé) car je n'ai jamais essayé ce genre de configuration. Je choisirais d'abord de tester un cache distribué ou un cache d'invalidation donné par la façon dont il fonctionne avec les données expulsées/invalidées. Normalement, les caches locaux ne se synchronisent pas avec les autres nœuds distants du cluster. Si ce type d'implémentation conserve une carte locale en mémoire, il est probable que même si les données du stockage distant sont modifiées, ces changements peuvent ne pas se refléter dans certaines situations. Je peux vous donner un fichier de test Jmeter que vous pouvez utiliser afin que vous puissiez essayer d'effectuer vos propres tests avec les deux configurations.

Revenant au sujet de votre configuration, vous devez prendre en compte en plus du fait que le cache répliqué a certaines limites et est généralement un peu plus lent que ceux distribués qui ne répliquent que les données vers les propriétaires définis (les répliqués écrivent en tout les nœuds). Il existe également une variante appelée scattered-cache qui fonctionne mieux mais manque par exemple de prise en charge des transactions (vous pouvez voir ici un tableau comparatif https://infinispan.org/docs/stable/user_guide/user_guide.html#which_cache_mode_should_i_use ). La réplication ne fonctionne généralement bien que dans de petits clusters (sous 8 ou 10 serveurs), en raison du nombre de messages de réplication à envoyer. Le cache distribué permet à Infinispan d'évoluer de manière linéaire en définissant un certain nombre de répliques par entrée.

La principale raison de faire une configuration du type que vous essayez de faire au lieu d'une configuration similaire à celle proposée par Keycloak (standalone-ha.xml), est lorsque vous avez besoin de mettre à l'échelle indépendamment le cluster infinispan de l'application ou d'utiliser infinispan comme magasin persistant.

Je vais expliquer comment Keycloak gère son cache et comment il le divise en deux ou trois groupes pour que vous puissiez mieux comprendre la configuration dont vous avez besoin.

Habituellement, pour configurer Keycloak dans un cluster, il suffit de lever et de configurer le Keycloak en mode HA comme vous le feriez avec une instance traditionnelle de Wildfly. Si l'on observe les différences entre le standalone.xml et le standalone-ha.xml qui vient dans l'installation de keycloak, on remarque que fondamentalement le support est ajouté à "Jgroups", "modcluster", et les caches sont distribués (qui étaient auparavant locaux ) entre les nœuds dans Wildfly/Keycloak (HA).

En détail :

  • un sous-système jgroups est ajouté, qui sera responsable de la connexion des nœuds du cluster et de l'exécution de la messagerie/communication dans le cluster. JGroups offre des capacités de communication réseau, des communications fiables et d'autres fonctionnalités telles que la découverte de nœuds, les communications point à point, la communication multidiffusion, la détection des pannes et le transfert de données entre les nœuds du cluster.
  • le cache EJB3 passe d'un cache SIMPLE (en mémoire locale sans gestion de transaction) à un DISTRIBUÉ. Cependant, je m'assurerais que le projet Keycloak ne nécessite pas d'utiliser EJB3 selon mon expérience en étendant ce projet.
  • cache: les "domaines", les "utilisateurs", les "autorisations" et les "clés" sont conservés en local car ils sont uniquement utilisés pour réduire la charge de la base de données.
  • cache: "work" devient REPLICATED car c'est celui que Keycloak utilise pour notifier aux nœuds du cluster qu'une entrée du cache doit être supprimée/invalidée puisque son état a été modifié.
  • cache "sessions", "authenticationSessions", "offlineSessions", "clientSessions", "offlineSessions", "loginFailures" et "actionTokens" devient DISTRIBUTED car ils fonctionnent mieux que replicated-cache (voir https: // infinispan .org/docs/stable/user_guide/user_guide.html # which_cache_mode_should_i_use ) car il vous suffit de répliquer les données vers les propriétaires.
  • Les autres changements proposés par keycloak pour sa configuration HA par défaut sont de distribuer le conteneur de cache "web" et "ejb" (et au-dessus), et de changer le cache "hibernate" en un "invalidation-cache" (comme un cache local mais avec invalidation synchronisation).

Je pense que votre configuration de cache doit être définie comme "cache distribué" pour les caches comme "sessions", "authenticationSessions", "offlineSessions", "clientSessions", "offlineClientSessions", "loginFailures" et "actionTokens" (au lieu de "local" "). Cependant, comme vous utilisez un magasin partagé distant, vous devez le tester pour voir comment il fonctionne comme je l'ai dit précédemment.

De plus, le cache nommé "work" doit être "replicated-cache" et les autres ("clés", "autorisation", "realms" et "users") doivent être définis comme "local-cache".

Dans votre cluster infinispan, vous pouvez le définir comme "cache distribué" (ou "cache répliqué").

N'oubliez pas que:

Dans un cache répliqué, tous les nœuds d'un cluster contiennent toutes les clés, c'est-à-dire que si une clé existe sur un nœud, elle existera également sur tous les autres nœuds. Dans un cache distribué, un certain nombre de copies sont conservées pour assurer la redondance et la tolérance aux pannes, mais cela est généralement bien inférieur au nombre de nœuds du cluster. Un cache distribué offre un degré d'évolutivité bien supérieur à un cache répliqué. Un cache distribué est également capable de localiser de manière transparente les clés d'un cluster et fournit un cache L1 pour un accès en lecture local rapide de l'état stocké à distance. Vous pouvez en savoir plus dans le chapitre correspondant du Guide de l'utilisateur.

Doc Infinispan. ref: mode cache

Comme l'indique la documentation de Keycloak (6.0):

Keycloak a deux types de caches. Un type de cache se trouve devant la base de données pour diminuer la charge sur la base de données et pour réduire les temps de réponse globaux en conservant les données en mémoire. Le domaine, le client, le rôle et les métadonnées utilisateur sont conservés dans ce type de cache. Ce cache est un cache local. Les caches locaux n'utilisent pas la réplication même si vous êtes dans le cluster avec plus de serveurs Keycloak. Au lieu de cela, ils ne conservent des copies que localement et si l'entrée est mise à jour, un message d'invalidation est envoyé au reste du cluster et l'entrée est expulsée. Il existe un travail de cache répliqué distinct, dont la tâche consiste à envoyer les messages d'invalidation à l'ensemble du cluster concernant les entrées à supprimer des caches locaux. Cela réduit considérablement le trafic réseau, rend les choses plus efficaces et évite de transmettre des métadonnées sensibles sur le câble.

Le deuxième type de cache gère la gestion des sessions utilisateur, des jetons hors ligne et le suivi des échecs de connexion afin que le serveur puisse détecter le phishing par mot de passe et d'autres attaques. Les données contenues dans ces caches sont temporaires, en mémoire uniquement, mais peuvent être répliquées sur le cluster.

Doc. Référence: configuration du cache

Si vous voulez lire un autre bon document, vous pouvez jeter un œil à la section "cross-dc" ( mode cross-dc ) en particulier la section "3.4.6 Infinispan cache" ( infinispan cache )

J'ai essayé avec Keycloak 6.0.1 et Infinispan 9.4.11.Final, voici ma configuration de test (basée sur le fichier standalone-ha.xml).

Sous-système infinispan Keycloak :

    <subsystem xmlns="urn:jboss:domain:infinispan:8.0">
        <cache-container name="keycloak" module="org.keycloak.keycloak-model-infinispan">
            <transport lock-timeout="60000"/>
            <local-cache name="realms">
                <object-memory size="10000"/>
            </local-cache>
            <local-cache name="users">
                <object-memory size="10000"/>
            </local-cache>
            <distributed-cache name="sessions" owners="1" remote-timeout="30000">
                <remote-store cache="sessions" remote-servers="remote-cache" socket-timeout="60000" fetch-state="false" passivation="false" preload="false" purge="false" shared="true">
                <property name="rawValues">
                true
                </property>
                <property name="marshaller">
org.keycloak.cluster.infinispan.KeycloakHotRodMarshallerFactory
                </property>
                </remote-store>
                </distributed-cache>
            <distributed-cache name="authenticationSessions" owners="1" remote-timeout="30000">
                <remote-store cache="authenticationSessions" remote-servers="remote-cache" socket-timeout="60000" fetch-state="false" passivation="false" preload="false" purge="false" shared="true">
                <property name="rawValues">
                true
                </property>
                <property name="marshaller">
org.keycloak.cluster.infinispan.KeycloakHotRodMarshallerFactory
                </property>
                </remote-store>
                </distributed-cache>
            <distributed-cache name="offlineSessions" owners="1" remote-timeout="30000">
                <remote-store cache="offlineSessions" remote-servers="remote-cache" socket-timeout="60000" fetch-state="false" passivation="false" preload="false" purge="false" shared="true">
                <property name="rawValues">
true
                </property>
                <property name="marshaller">
org.keycloak.cluster.infinispan.KeycloakHotRodMarshallerFactory
                </property>
                </remote-store>
                </distributed-cache>
            <distributed-cache name="clientSessions" owners="1" remote-timeout="30000">
                <remote-store cache="clientSessions" remote-servers="remote-cache" socket-timeout="60000" fetch-state="false" passivation="false" preload="false" purge="false" shared="true">
                <property name="rawValues">
true
                </property>
                <property name="marshaller">
org.keycloak.cluster.infinispan.KeycloakHotRodMarshallerFactory
                </property>
                </remote-store>
                </distributed-cache>
            <distributed-cache name="offlineClientSessions" owners="1" remote-timeout="30000">
                <remote-store cache="offlineClientSessions" remote-servers="remote-cache" socket-timeout="60000" fetch-state="false" passivation="false" preload="false" purge="false" shared="true">
                <property name="rawValues">
                true
                </property>
                <property name="marshaller">
org.keycloak.cluster.infinispan.KeycloakHotRodMarshallerFactory
                </property>
                </remote-store>
                </distributed-cache>
            <distributed-cache name="loginFailures" owners="1" remote-timeout="30000">
                <remote-store cache="loginFailures" remote-servers="remote-cache" socket-timeout="60000" fetch-state="false" passivation="false" preload="false" purge="false" shared="true">
                <property name="rawValues">
                true
                </property>
                <property name="marshaller">
org.keycloak.cluster.infinispan.KeycloakHotRodMarshallerFactory
                </property>
                </remote-store>
                </distributed-cache>
            <replicated-cache name="work"/>
            <local-cache name="authorization">
                <object-memory size="10000"/>
            </local-cache>
            <local-cache name="keys">
                <object-memory size="1000"/>
                <expiration max-idle="3600000"/>
            </local-cache>
            <distributed-cache name="actionTokens" owners="1" remote-timeout="30000">
                <remote-store cache="actionTokens" remote-servers="remote-cache" socket-timeout="60000" fetch-state="false" passivation="false" preload="false" purge="false" shared="true">
                <property name="rawValues">
                true
                </property>
                <property name="marshaller">
org.keycloak.cluster.infinispan.KeycloakHotRodMarshallerFactory
                </property>
                </remote-store>
                <object-memory size="-1"/>
                <expiration max-idle="-1" interval="300000"/>
            </distributed-cache>
         </cache-container>

Liaisons de socket Keycloak :

<socket-binding-group name="standard-sockets" default-interface="public" port-offset="${jboss.socket.binding.port-offset:0}">
    <socket-binding name="management-http" interface="management" port="${jboss.management.http.port:9990}"/>
    <socket-binding name="management-https" interface="management" port="${jboss.management.https.port:9993}"/>
    <socket-binding name="ajp" port="${jboss.ajp.port:8009}"/>
    <socket-binding name="http" port="${jboss.http.port:8080}"/>
    <socket-binding name="https" port="${jboss.https.port:8443}"/>
    <socket-binding name="jgroups-mping" interface="private" multicast-address="${jboss.default.multicast.address:230.0.0.4}" multicast-port="45700"/>
    <socket-binding name="jgroups-tcp" interface="private" port="7600"/>
    <socket-binding name="jgroups-udp" interface="private" port="55200" multicast-address="${jboss.default.multicast.address:230.0.0.4}" multicast-port="45688"/>
    <socket-binding name="modcluster" multicast-address="${jboss.modcluster.multicast.address:224.0.1.105}" multicast-port="23364"/>
    <socket-binding name="txn-recovery-environment" port="4712"/>
    <socket-binding name="txn-status-manager" port="4713"/>
<outbound-socket-binding name="remote-cache">
<remote-destination Host="my-server-domain.com" port="11222"/>  
</outbound-socket-binding>
    <outbound-socket-binding name="mail-smtp">
        <remote-destination Host="localhost" port="25"/>
    </outbound-socket-binding>
</socket-binding-group>

Configuration du cluster Infinispan :

<subsystem xmlns="urn:infinispan:server:core:9.4" default-cache-container="clustered">
    <cache-container name="clustered" default-cache="default" statistics="true">
        <transport lock-timeout="60000"/>
        <global-state/>
        <distributed-cache-configuration name="transactional">
            <transaction mode="NON_XA" locking="PESSIMISTIC"/>
        </distributed-cache-configuration>
        <distributed-cache-configuration name="async" mode="ASYNC"/>
        <replicated-cache-configuration name="replicated"/>
        <distributed-cache-configuration name="persistent-file-store">
            <persistence>
                <file-store shared="false" fetch-state="true"/>
            </persistence>
        </distributed-cache-configuration>
        <distributed-cache-configuration name="indexed">
            <indexing index="LOCAL" auto-config="true"/>
        </distributed-cache-configuration>
        <distributed-cache-configuration name="memory-bounded">
            <memory>
                <binary size="10000000" eviction="MEMORY"/>
            </memory>
        </distributed-cache-configuration>
        <distributed-cache-configuration name="persistent-file-store-passivation">
            <memory>
                <object size="10000"/>
            </memory>
            <persistence passivation="true">
                <file-store shared="false" fetch-state="true">
                    <write-behind modification-queue-size="1024" thread-pool-size="1"/>
                </file-store>
            </persistence>
        </distributed-cache-configuration>
        <distributed-cache-configuration name="persistent-file-store-write-behind">
            <persistence>
                <file-store shared="false" fetch-state="true">
                    <write-behind modification-queue-size="1024" thread-pool-size="1"/>
                </file-store>
            </persistence>
        </distributed-cache-configuration>
        <distributed-cache-configuration name="persistent-rocksdb-store">
            <persistence>
                <rocksdb-store shared="false" fetch-state="true"/>
            </persistence>
        </distributed-cache-configuration>
        <distributed-cache-configuration name="persistent-jdbc-string-keyed">
            <persistence>
                <string-keyed-jdbc-store datasource="Java:jboss/datasources/ExampleDS" fetch-state="true" preload="false" purge="false" shared="false">
                    <string-keyed-table prefix="ISPN">
                        <id-column name="id" type="VARCHAR"/>
                        <data-column name="datum" type="BINARY"/>
                        <timestamp-column name="version" type="BIGINT"/>
                    </string-keyed-table>
                    <write-behind modification-queue-size="1024" thread-pool-size="1"/>
                </string-keyed-jdbc-store>
            </persistence>
        </distributed-cache-configuration>
        <distributed-cache name="default"/>
        <replicated-cache name="repl" configuration="replicated"/>
        <replicated-cache name="work" configuration="replicated"/>
        <replicated-cache name="sessions" configuration="replicated"/>
        <replicated-cache name="authenticationSessions" configuration="replicated"/>
        <replicated-cache name="clientSessions" configuration="replicated"/>
        <replicated-cache name="offlineSessions" configuration="replicated"/>
        <replicated-cache name="offlineClientSessions" configuration="replicated"/>
        <replicated-cache name="actionTokens" configuration="replicated"/>
        <replicated-cache name="loginFailures" configuration="replicated"/>
    </cache-container>
</subsystem>

P.S. Modifiez l'attribut "propriétaires" de 1 à votre valeur préférée.

J'espère être utile.

8
Ariel Carrera

Bon échange ici les gars, incroyablement j'avais exactement les mêmes hypothèses que vous Michael, j'ai configuré mon cache local pour utiliser le magasin distant et je m'attendais à ce que les clés soient lues/écrites toujours dans le magasin distant, mais apparemment, ce n'est pas comme ça Ça marche.

Malheureusement, à partir de tous les échanges effectués ici, je n'ai pas trouvé pourquoi, pourquoi ne pouvons-nous pas configurer l'infinispan local pour ne servir que de proxy à un infinispan distant, permettant de garder ces instances sans état et d'avoir un processus plus facile à redéployer .

0
Guilherme Oliveira