目前正在以standalone-ha模式设置keycloak集群,以便能够在docker swarm上运行。在 keycloak 中,用户会话缓存在嵌入式 infinispan 存储中,并且 infinispan 可以配置为跨集群的分布式缓存。
我也将所有者设置为2,但问题是..在缩小规模期间,如果包含缓存的两个所有者在缩小期间都被杀死,则用户会话可能会丢失。
我还阅读了有关 Infinispan Redis 缓存存储的信息,但我不确定如何配置它。
问题1: 是否可以配置 Keycloak Infinispan 以使用 Redis 存储?
问题2: 如果这是不可能的,有没有办法可以克服这个问题?
任何建议都会有帮助。
由于此 PR https://github.com/keycloak/keycloak/commit/056ba75a72b1595ca9fa471f5693201fd5b2c7ae 默认情况下(Keycloak 最新版本 6.0.1),使用
Infinispan Connection SPI
的 InfinispanChangelogBasedTransaction.java
对 CacheDecorator.java
具有非常特殊的用途
这将skipCacheStore
。这意味着无论您是否配置具有持久性的存储,该存储都将被忽略。
为了实现你想要的,除了配置商店之外,你还必须在这里自定义大部分SPI https://github.com/keycloak/keycloak/tree/master/model/infinispan/src/main/resources /META-INF/services 以确保 Keycloak 将使用缓存存储。
这也不容易,因为这个过程涉及很多额外的好处,例如,由于 Keycloak 使用 Jboss 的 Marshaller,如果您自定义此 SPI,则必须携带大部分
org.keycloak.models.sessions.infinispan
包并注册您的模块,以确保 Wildfly 能够看到要编组的实体。
还有一点就是,使用Redis,你应该配置大部分缓存指向同一个数据库,除了
authenticationSessions
,不能与sessions
在同一个数据库,否则会出现像RootAuthenticationSesssionEntity
那样的冲突被发现但预计会 SessionEntityWrapper
。
要恢复,过程会很痛苦,但如果你想敢做,我就是这样实现的:
private Configuration getRedisConfiguration(int database) {
ConfigurationBuilder cb = new ConfigurationBuilder();
cb.persistence()
.passivation(false)
.addStore(RedisCacheStoreConfigurationBuilder.class)
.ignoreModifications(false)
.fetchPersistentState(false)
.purgeOnStartup(false)
.preload(false)
.shared(true)
.addProperty("host", System.getenv("REDIS_HOST"))
.addProperty("port", System.getenv("REDIS_PORT"))
.addProperty("database", String.valueOf(database));
return cb.build();
}
您看到的
RedisCacheStoreConfigurationBuilder
基本上是原始商店的精简版本,但我不需要哨兵或服务器模式,我只想连接到主机、端口和数据库。
然后我基本上复制了
org.keycloak.models.sessions.infinispan
删除与删除缓存相关的所有内容,而不是正常使用没有装饰器的缓存来跳过CacheStore。
如果我可以提供帮助,请告诉我,我最会准备一篇文章,指导更详细的操作方法,还涉及一个包含我正在讨论的代码的存储库。如果有人仍在尝试此操作,请告诉我更多信息。
当期望动态扩展大型系统时,期望避免这种在配置中注册可用节点列表的约束。所以 Redis 节点发现在这里是一个好处。
Infinispan 本身支持 Redis Store 作为扩展,实现 SPI 并添加 XML 实体以简化配置:
但是 WildFly infinispan 子系统尚不支持此扩展 - 因为 Keycloak 依赖于 WildFly。
因此,我希望通过以下任务使 Infinispan Redis Store 可用于 WildFly,以及 Keycloak:
为 infinispam redis 存储 jar 创建 jboss 模块 - 请参阅
modules/system/layers/base/org/infinispan/
创建一个“自定义缓存存储”工厂,能够从 WildFly 配置键/值属性实例化 Redis 存储对象(存储、服务器和连接池)。这也必须作为 jboss 模块添加到 WildFly
使用WildFly infinispan子系统“local-cache”“custom”来配置此工厂的属性
class
和properties
:https://wildscribe.github.io/WildFly/11.0/subsystem/infinispan/cache-container /local-cache/store/custom/index.html工作正在进行中,可能会发布代码和配置。