最近、専用のInfinispanクラスターをremote-store
として使用して、Keycloakのさまざまなキャッシュの永続性をさらに強化するために、Keycloakのデプロイメントを強化しました。変更自体はかなりうまくいきましたが、この変更を行った後、expired_code
エラーメッセージが原因で多くのログインエラーが発生し始めました。
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
このエラーメッセージは通常、同じIPアドレスから短時間に数十回繰り返されます。これの原因は、ブラウザ自体がループを停止するまで、エンドユーザーのブラウザがログイン時に無限にリダイレクトすることにあるようです。
GitHubのさまざまな問題( https://github.com/helm/charts/issues/8355 )も見たことがありますが、この動作も文書化されており、コンセンサスはKeycloakクラスターが原因であるようですJGroupsを介してそのメンバーを正しく検出できません。
この説明は、一部のKeycloakキャッシュが、standalone-ha.xml
内のデフォルト構成のKeycloakノード全体に分散されていると考えると意味があります。ただし、これらのキャッシュを、remote-store
が新しいInfinispanクラスターを指すローカルキャッシュになるように変更しました。これがどのように機能するかについて誤った仮定をしたため、このエラーが発生し始めたと思います。
これが私のKeycloakキャッシュの構成方法です。
<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>
デフォルトのstandalone-ha.xml
構成ファイルと比較すると、このキャッシュ構成のほとんどは変更されていないことに注意してください。ここで行った変更により、次のキャッシュがlocal
に変更され、リモートのInfinispanクラスターを指すようになります。
sessions
authenticationSessions
offlineSessions
clientSessions
offlineClientSessions
loginFailures
actionTokens
work
これがremote-cache
サーバーの設定です。
<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>
これが、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>
私は、リモートストアのローカルキャッシュがどのように機能するかについて、いくつかの誤った仮定を行ったと思います。誰かが私のためにこれをクリアできることを願っていました。私の意図は、InfinispanクラスターをKeycloakのすべてのキャッシュの真の情報源にすることでした。すべてのキャッシュをローカルにすることで、データがInfinispanクラスターを介して各Keycloakノードに複製され、keycloak-0
のローカルauthenticationSessions
キャッシュへの書き込みがInfinispanクラスターを介してkeycloak-1
に同期して永続化されると想定しました。
Keycloakのローカルキャッシュへの書き込みは、リモートのInfinispanクラスターへのその値の永続化に関して同期していないというのが私の考えです。つまり、authenticationSessions
キャッシュへの書き込みが実行されても、この値がInfinispanクラスターに書き込まれるのを待機している間はブロックされないため、別のKeycloakノードでこのデータをすぐに読み取ると、ローカルおよびInfinispanクラスター内のキャッシュミス。
私の現在の構成がこの問題を引き起こしている理由を特定するための助けを探しています、remote-store
の動作に関するいくつかの明確化-remote-store
によってバックアップされたローカルキャッシュへのキャッシュ書き込みを同期させる方法はありますか?そうでない場合、私がここで達成しようとしていることを行うためのより良い方法はありますか?
その他の関連する可能性のある詳細:
KUBE_PING
を使用しています。work
キャッシュがすべてのKeycloakノードに伝達されていると確信できます。前もって感謝します!
クラスターでKeycloakを構成する際に留意すべきいくつかの点を明確にしようと思います。
"無限リダイレクト"の件名について話していると、私は何年も前に開発環境で同様の問題を経験しました。キークロークチームは、無限ループに関連するいくつかのバグを修正しました(例 KEYCLOAK-5856 、 KEYCLOAK-5022 、 KEYCLOAK-4717 、 KEYCLOAK-4552 、 KEYCLOAK-3878 )構成の問題が原因で発生する場合があります。
サイトがHTTPSであるかどうかを確認する1つのことは、HTTPSによってKeycloakサーバーにもアクセスすることです。
KeycloakがHTTPSリバースプロキシの背後に配置され、必要なヘッダーがKeycloak(ヘッダーX-FOWARDED ...)に伝達されなかった場合、無限ループと同様の問題が発生したことを覚えています。うまく環境を整えて解決しました。クラスター内のノードの検出が正しく機能しない場合(JGroups)に、同様の問題が発生する可能性があります。
エラーメッセージ"expired_code"について、この種の期限切れトークン/コードエラーが発生する可能性があるため、各ノードのクロックが同期していることを確認します。
構成をよりよく理解したところで、infinispanクラスターを指すリモートストアで「ローカルキャッシュ」モードを使用することは不適切ではないようです。
ただし、通常、共有ストア(リモートキャッシュなど)は通常、無効化キャッシュと共に使用され、クラスターによって完全なデータを複製することは避けられます(ここで適用できるコメントを参照 https:/ /developer.jboss.org/message/986847#986847 )、分散または無効化キャッシュとの大きな違いはないかもしれません。
リモートストアを備えた分散キャッシュはより適切に適用されます(または所有者に重いデータが複製されないようにするための無効化キャッシュ)。ただし、リモートストレージ(共有)で「ローカルキャッシュ」がどのように機能するかを確認できませんでした。私はこの種の構成を試したことがないので。私は最初に、分散キャッシュまたは無効化キャッシュをテストすることを選択しました。通常、ローカルキャッシュは、クラスター内の他のリモートノードと同期しません。この種の実装がローカルマップをメモリに保持している場合、リモートストレージのデータが変更されても、これらの変更が一部の状況に反映されない可能性があります。両方の構成で独自のテストを実行できるように、使用できるJmeterテストファイルを提供できます。
構成のトピックに戻ると、レプリケートされたキャッシュには特定の制限があり、通常、定義された所有者にのみデータをレプリケートする分散キャッシュよりも少し遅いことを考慮する必要があります(レプリケートされたものはすべてに書き込みます)ノード)。パフォーマンスが向上するスキャッタリングキャッシュと呼ばれるバリアントもありますが、たとえばトランザクションのサポートが不足しています(ここで比較チャートを見ることができます https://infinispan.org/docs/stable/user_guide/user_guide.html#which_cache_mode_should_i_use )。送信する必要のあるレプリケーションメッセージの数が原因で、レプリケーションは通常、小さなクラスター(8台または10台未満のサーバー)でのみ適切に機能します。分散キャッシュを使用すると、エントリごとに多数のレプリカを定義することで、Infinispanを直線的に拡張できます。
Keycloakによって提案されたもの(standalone-ha.xml)に似たタイプではなく、実行しようとしているタイプの構成を作成する主な理由は、アプリケーションのinfinispanクラスターを個別にスケーリングするか、永続ストアとしてのinfinispan。
Keycloakがキャッシュを管理する方法、およびKeycloakが基本的に2つまたは3つのグループにそれを分割する方法を説明し、必要な構成をよりよく理解できるようにします。
通常、クラスターでKeycloakを構成するには、Wildflyの従来のインスタンスを使用する場合と同じように、Keycloakを上げてHAモードで構成するだけです。キークロークのインストールに含まれているstandalone.xmlとstandalone-ha.xmlの違いを観察すると、基本的にサポートが「Jgroups」、「modcluster」に追加され、キャッシュが分散されていることがわかります(以前はローカルでした) )Wildfly/Keycloak(HA)のノード間。
詳細:
「セッション」、「authenticationSessions」、「offlineSessions」、「clientSessions」、「offlineClientSessions」、「loginFailures」、および「actionTokens」(「ローカル」ではなく)のようなキャッシュの「分散キャッシュ」としてキャッシュ構成を定義する必要があると思います")。ただし、リモート共有ストアを使用するため、前に言ったように動作するかどうかを確認するためにテストする必要があります。
また、「work」という名前のキャッシュは「replicated-cache」で、その他(「keys」、「authorization」、「realms」、「users」)は「local-cache」として定義する必要があります。
Infinispanクラスターでは、「分散キャッシュ」(または「複製キャッシュ」)として定義できます。
覚えておいてください:
複製されたキャッシュでは、クラスター内のすべてのノードがすべてのキーを保持します。つまり、キーが1つのノードに存在する場合、他のすべてのノードにも存在します。分散キャッシュでは、冗長性とフォールトトレランスを提供するためにいくつかのコピーが維持されますが、これは通常、クラスター内のノードの数よりはるかに少ないです。分散キャッシュは、複製キャッシュよりはるかに優れたスケーラビリティを提供します。分散キャッシュは、クラスター全体でキーを透過的に検索することもでき、リモートに格納されている状態のローカルの高速読み取りアクセス用にL1キャッシュを提供します。詳細については、関連するユーザーガイドの章を参照してください。
Infinispanドキュメント。 ref: キャッシュモード
Keycloak(6.0)のドキュメントには次のように書かれています:
Keycloakには2種類のキャッシュがあります。 1つのタイプのキャッシュはデータベースの前に置かれ、DBの負荷を減らし、データをメモリに保持することで全体的な応答時間を短縮します。レルム、クライアント、ロール、およびユーザーのメタデータは、このタイプのキャッシュに保持されます。このキャッシュはローカルキャッシュです。より多くのKeycloakサーバーを含むクラスターにいる場合でも、ローカルキャッシュはレプリケーションを使用しません。代わりに、ローカルでのみコピーを保持し、エントリが更新されると、無効化メッセージが残りのクラスタに送信され、エントリは削除されます。個別の複製キャッシュ作業があり、どのタスクがローカルキャッシュから削除する必要があるかについて無効化メッセージをクラスター全体に送信します。これにより、ネットワークトラフィックが大幅に削減され、効率が向上し、機密性の高いメタデータがネットワーク経由で送信されなくなります。
2番目のタイプのキャッシュは、サーバーがパスワードフィッシングやその他の攻撃を検出できるように、ユーザーセッション、オフライントークンの管理、ログイン失敗の追跡を処理します。これらのキャッシュに保持されるデータは一時的なものであり、メモリ内にのみ存在しますが、クラスター全体で複製される可能性があります。
Doc。参照: キャッシュ構成
別の優れたドキュメントを読みたい場合は、「cross-dc」セクション( cross-dc mode )、特にセクション「3.4.6 Infinispan cache」( infinispan cache )
Keycloak 6.0.1とInfinispan 9.4.11.Finalを試してみましたが、これが私のテスト構成です(standalone-ha.xmlファイルに基づく)。
Keycloak infinispanサブシステム:
<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>
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>
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>
追伸属性「所有者」を1から好みの値に変更します。
お役に立てれば幸いです。
ここの人たちの素晴らしい交換、信じられないほど私はあなたのマイケルとまったく同じ仮定を持っていました、リモートストアを使用するようにローカルキャッシュを設定し、キーが常にリモートストアから読み取り/書き込みされることを期待しましたが、どうやらそうではありませんできます。
悲しいことに、ここで行われたすべての交換から、なぜこれが原因であるのか、ローカルinfinispanをリモートinfinispanのプロキシとしてのみ機能するように構成して、このインスタンスをステートレスに保ち、より簡単に再デプロイできるようにすることができないのです。 。