在启动 Keycloak 后,请考虑使用以下扩展和调优指南,根据需要调整您的实例以适应负载。
最大程度地减少资源利用率
实现目标响应时间
最大程度地减少数据库池争用
解决内存不足错误或过高的垃圾回收开销
通过水平扩展提供更高的可用性
在监控 Keycloak 工作负载时,请检查 CPU 或内存是否利用不足或过度利用。请参考 CPU 和内存资源大小调整概念,更好地调整 Java 虚拟机 (JVM) 可用的资源。
在增加 JVM 可用的内存量之前,尤其是在遇到内存不足错误时,最好使用堆转储来确定导致占用空间增大的原因。过长的响应时间也可能表明 HTTP 工作队列过大,调整负载卸载会比简单地提供更多内存更好。请参阅下一节。
Keycloak 会根据您提供的核心数量自动调整使用的线程数量。手动更改线程数可以提高整体吞吐量。有关更多详细信息,请参阅 配置线程池的概念。但是,更改线程数必须与其他 JVM 资源(例如数据库连接)相结合才能进行,否则可能会将瓶颈转移到其他地方。有关更多详细信息,请参阅 数据库连接池的概念。
要限制排队工作的内存利用率并提供负载卸载功能,请参阅 配置线程池的概念。
如果您遇到获取数据库连接超时问题,则应考虑增加可用的连接数。有关更多详细信息,请参阅 数据库连接池的概念。
某些平台(例如 Kubernetes)提供了垂直自动扩展机制。如果 Keycloak 需要重新启动服务器实例,则不建议使用垂直自动扩展,目前 Java 在 Kubernetes 上就是这种情况。您可以考虑改为提供更高的 CPU 和/或内存限制,以允许您的 JVM 根据需要在这些限制范围内进行调整。
单个 Keycloak 实例容易出现可用性问题。如果实例出现故障,您将遇到完全中断,直到另一个实例启动。通过在不同的机器上运行两个或多个集群成员,您可以大幅提高 Keycloak 的可用性。
单个 JVM 对可以处理的并发请求数量有限制。其他服务器实例可以提供大致线性的吞吐量扩展,直到关联的资源(例如数据库或分布式缓存)限制该扩展。
通常,请考虑允许 Keycloak 运算符处理水平扩展问题。使用运算符时,根据需要设置 Keycloak 自定义资源的 spec.instances
,以进行水平扩展。有关更多详细信息,请参阅 使用 Keycloak 运算符部署 Keycloak 以实现高可用性。
如果您没有使用运算符,请查看以下内容
如果您的实例位于不同的机器上,则可以实现更高的可用性。在 Kubernetes 上,使用 Pod 反亲和性来强制执行此操作。
使用分布式缓存;对于多站点集群,请使用外部缓存以使集群成员共享相同的状态。有关相关配置的详细信息,请参阅 配置分布式缓存。嵌入式 Infinispan 缓存具有水平扩展注意事项,包括
您的实例需要一种相互发现的方法。有关更多信息,请参阅 配置分布式缓存 中的发现。
此缓存不适合跨多个可用区(也称为扩展集群)的集群。对于嵌入式 Infinispan 缓存,请努力将所有实例放在一个可用区内。目标是避免通信中的不必要的往返,这些往返会放大响应时间。在 Kubernetes 上,使用 Pod 亲和性来强制执行 Pod 的这种分组。
此缓存无法优雅地处理多个成员同时加入或离开。特别是,成员同时离开会导致数据丢失。在 Kubernetes 上,您可以使用带有默认串行处理的 StatefulSet 来确保 Pod 按顺序启动和停止。
要避免在整个站点不可用时丢失服务可用性,请参阅高可用性指南,了解更多有关多站点部署的信息。请参阅 多站点部署。
水平自动扩展允许根据需要添加或删除 Keycloak 实例。请记住,启动时间不会是瞬时的,应使用优化后的镜像以最大程度地减少启动时间。
使用嵌入式 Infinispan 缓存集群时,动态添加或删除集群成员需要 Infinispan 对 Infinispan 缓存进行重新平衡,如果这些缓存中存在许多条目,则这会变得很昂贵。为了最大程度地减少此时间,默认情况下,我们将与会话相关的缓存中的条目数量限制为 10000。请注意,此优化只有在您的配置中未显式禁用 persistent-user-sessions
功能时才有可能。
在 Kubernetes 上,Keycloak 自定义资源是可扩展的,这意味着它可以被 内置自动扩展器 作为目标。