Keycloak 集群部署

本文档包含监控 Keycloak 部署性能的指标的详细信息。

本文档中描述的部署适用于单站点部署。在此架构中,Keycloak 节点利用 Infinispan 嵌入式集群缓存来形成集群。

如果使用外部 Infinispan,请查看带有外部 Infinispan 部署的 Keycloak指南。

启用 Keycloak 指标

Keycloak 在管理接口端点 /metrics 上公开指标。要启用,请使用构建时选项 --metrics-enabled=true

在 Kubernetes 集群中,使用 Keycloak 运算符,可以通过在 Keycloak CR addionalOptions 中启用指标,如下所示

apiVersion: k8s.keycloak.org/v2alpha1
kind: Keycloak
metadata:
  labels:
    app: keycloak
  name: keycloak
spec:
  additionalOptions:
    - name: metrics-enabled
      value: 'true'

可以在这里找到更多信息:这里

Keycloak HTTP 指标

本节介绍用于监控 Keycloak HTTP 请求处理的指标。

处理时间

这些指标公开了处理时间,以监控 Keycloak 性能以及处理请求需要多长时间。

在健康的集群中,平均处理时间将保持稳定。处理时间的峰值或增加可能是某些节点负载过重的早期信号。

标签

  • outcome:更通用的结果标签。

  • status:HTTP 状态码。

  • uri:请求的 URI。

指标 描述

http_server_requests_seconds_count

处理的请求总数。

http_server_requests_seconds_sum

处理的所有请求的总持续时间。

启用直方图后,可以使用百分位桶。这些对创建热图很有用,但收集和公开百分位桶可能会对部署性能产生负面影响。

活动请求

当前活动请求数量也可用。

指标 描述

http_server_active_requests

当前活动请求数量

带宽

以下指标有助于监控 Keycloak 使用的带宽和消耗的流量,以及请求和响应接收或发送时消耗的流量。

指标 描述

http_server_bytes_written_count

发送的响应总数。

http_server_bytes_written_sum

发送的字节总数。

http_server_bytes_read_count

接收的请求总数。

http_server_bytes_read_sum

接收的字节总数。

启用直方图后,可以使用百分位桶。这些对创建热图很有用,但收集和公开百分位桶可能会对部署性能产生负面影响。

集群和网络

部署多个 Keycloak 节点允许在它们之间分配负载,但这需要节点之间的通信。本节介绍用于监控 Keycloak 之间通信的指标,以便识别可能的故障。

全局标签

  • cluster=<name>:集群名称。如果正在收集来自多个集群的指标,此标签有助于识别它们属于哪个集群。

  • node=<node>:报告指标的节点的名称。

响应时间

以下指标公开了远程请求的响应时间。响应时间是在两个节点之间测量的,包括处理时间。所有请求都通过这些指标进行测量,响应时间应在整个集群生命周期中保持稳定。

在健康的集群中,响应时间将保持稳定。响应时间的增加可能表明集群降级或节点负载过重。

标签

  • node=<node>:它标识发送节点。

  • target_node=<node>:它标识接收节点。

指标 描述

vendor_jgroups_stats_sync_requests_seconds_count

对接收节点的同步请求数。

vendor_jgroups_stats_sync_requests_seconds_sum

对接收节点的同步请求的总持续时间

启用直方图后,可以使用百分位桶。这些对创建热图很有用,但收集和公开百分位桶可能会对部署性能产生负面影响。

带宽

Keycloak 接收和发送的所有字节都通过这些指标进行收集。此外,所有内部消息(如心跳)也都进行计数。它们允许计算每个节点当前使用的带宽。

指标名称取决于正在使用的 JGroups 传输协议。
指标 协议 描述

vendor_jgroups_tcp_get_num_bytes_received

TCP

节点接收的字节总数。

vendor_jgroups_udp_get_num_bytes_received

UDP

vendor_jgroups_tunnel_get_num_bytes_received

TUNNEL

vendor_jgroups_tcp_get_num_bytes_sent

TCP

节点发送的字节总数。

vendor_jgroups_tunnel_get_num_bytes_sent

UDP

vendor_jgroups_tunnel_get_num_bytes_sent

TUNNEL

线程池

监控线程池大小是节点负载过重的良好指标。接收的所有请求都添加到线程池中以进行处理,当线程池已满时,请求将被丢弃。重传机制确保可靠的通信,但会增加资源使用率。

在健康的集群中,线程池永远不应该接近其最大大小(默认情况下为 200 个线程)。
使用虚拟线程时,线程池指标不可用。
指标名称取决于正在使用的 JGroups 传输协议。
指标 协议 描述

vendor_jgroups_tcp_get_thread_pool_size

TCP

线程池中的当前线程数。

vendor_jgroups_udp_get_thread_pool_size

UDP

vendor_jgroups_tunnel_get_thread_pool_size

TUNNEL

vendor_jgroups_tcp_get_largest_size

TCP

曾经同时在池中的线程的最大数量。

vendor_jgroups_udp_get_largest_size

UDP

vendor_jgroups_tunnel_get_largest_size

TUNNEL

流量控制

流量控制负责随着时间的推移调整消息发送者的速率以适应最慢接收者的速率。这是通过基于信用的系统实现的,其中每个发送者在发送时都会减少其信用额度。当信用额度降至 0 以下时,发送者会阻塞,并且只有在从接收者收到补充消息时才能恢复发送消息。

以下指标显示了阻塞消息的数量和平均阻塞时间。当值不为零时,它可能表明接收者过载,并且可能会降低集群性能。

每个节点都有两个独立的流量控制协议,UFC 用于单播消息,MFC 用于多播消息。

健康的集群显示所有指标的值为零。
指标 描述

vendor_jgroups_ufc_get_number_of_blockings

流量控制阻塞发送单播消息的发送者的次数。

vendor_jgroups_ufc_get_average_time_blocked

尝试发送单播消息时,流量控制中阻塞的平均时间(以毫秒为单位)。

vendor_jgroups_mfc_get_number_of_blockings

流量控制阻塞发送多播消息的发送者的次数。

vendor_jgroups_mfc_get_average_time_blocked

尝试发送多播消息时,流量控制中阻塞的平均时间(以毫秒为单位)。

重传

JGroups 提供可靠的消息传递。当消息在网络上丢失或接收者无法处理消息时,需要重传。重传会增加资源使用率,通常是系统过载的信号。

随机早期丢弃 (RED) 监控发送者队列。当队列几乎满时,消息会被丢弃,并且必须进行重传。它可以防止线程被满的发送者队列阻塞。

健康的集群显示所有指标的值为零。
指标 描述

vendor_jgroups_unicast3_get_num_xmits

重传的消息数。

vendor_jgroups_red_get_dropped_messages

发送者丢弃的消息总数。

vendor_jgroups_red_get_drop_rate

发送者丢弃的所有消息的百分比。

网络分区

集群大小

集群大小指标报告集群中存在的节点数量。如果它不同,它可能表明节点正在加入、关闭,或者在最坏的情况下,网络分区正在发生。

健康的集群在所有节点中显示相同的值。
指标 描述

vendor_cluster_size

集群中的节点数。

网络分区事件

集群中的网络分区可能由于各种原因而发生。此指标不能帮助预测网络拆分,但可以表明它已发生,并且集群已合并。

健康的集群显示此指标的值为零。
指标 描述

vendor_jgroups_merge3_get_num_merge_events

检测到网络拆分并修复的时间量。

Infinispan 缓存

Keycloak 将数据缓存在嵌入式 Infinispan 缓存中。本节中的指标有助于监控缓存运行状况和集群复制。

全局标签

  • cache=<name>:缓存名称。

大小

使用这两个指标监控缓存中的条目数量。如果缓存是集群化的,每个条目都有一个拥有者节点和零个或多个不同节点的备份副本。

将唯一条目大小指标相加,以获得集群的总条目数量。
指标 描述

vendor_statistics_approximate_entries

节点存储的条目数量(包括备份副本)的近似值。

vendor_statistics_approximate_entries_unique

节点存储的条目数(不包括备份副本)的近似值。

数据访问

以下指标监控缓存访问,例如读、写及其持续时间。

存储

存储操作是写入操作,它写入或更新存储在缓存中的值。

指标 描述

vendor_statistics_store_times_seconds_count

存储请求的总数。

vendor_statistics_store_times_seconds_sum

所有存储请求的总持续时间。

启用直方图后,可以使用百分位桶。这些对创建热图很有用,但收集和公开百分位桶可能会对部署性能产生负面影响。

读取

读取操作从缓存中读取值。它分为两组,如果找到值,则为命中,如果没有找到,则为未命中。

指标 描述

vendor_statistics_hit_times_seconds_count

读取命中请求的总数。

vendor_statistics_hit_times_seconds_sum

所有读取命中请求的总持续时间。

vendor_statistics_miss_times_seconds_count

读取未命中请求的总数。

vendor_statistics_miss_times_seconds_sum

所有读取未命中请求的总持续时间。

启用直方图后,可以使用百分位桶。这些对创建热图很有用,但收集和公开百分位桶可能会对部署性能产生负面影响。

移除

移除操作从缓存中移除值。它分为两组,如果值存在,则为命中,如果值不存在,则为未命中。

指标 描述

vendor_statistics_remove_hit_times_seconds_count

移除命中请求的总数。

vendor_statistics_remove_hit_times_seconds_sum

所有移除命中请求的总持续时间。

vendor_statistics_remove_miss_times_seconds_count

移除未命中请求的总数。

vendor_statistics_remove_miss_times_seconds_sum

所有移除未命中请求的总持续时间。

启用直方图后,可以使用百分位桶。这些对创建热图很有用,但收集和公开百分位桶可能会对部署性能产生负面影响。

对于 usersrealms 缓存,数据库失效会转化为移除操作。这些指标是数据库实体修改频率以及因此从缓存中移除频率的良好指标。

读取和移除操作的命中率

可以使用表达式在诸如 Prometheus 之类的系统中计算缓存的命中率。例如,读取操作的命中率可以表示为

vendor_statistics_hit_times_seconds_count/(vendor_statistics_hit_times_seconds_count+vendor_statistics_miss_times_seconds_count)

读写比率

可以使用表达式使用上述指标计算缓存的读写比率

(vendor_statistics_hit_times_seconds_count+vendor_statistics_miss_times_seconds_count)/(vendor_statistics_hit_times_seconds_count+vendor_statistics_miss_times_seconds_count+vendor_statistics_remove_hit_times_seconds_count+vendor_statistics_remove_miss_times_seconds_count+vendor_statistics_store_times_seconds_count)

驱逐

驱逐是限制缓存大小的过程,当缓存已满时,会移除一个条目以腾出空间供新条目缓存。由于 Keycloak 在 usersrealmsauthorization 中缓存数据库实体,因此数据库访问总是伴随着驱逐事件。

指标 描述

vendor_statistics_evictions

驱逐事件的总数。

驱逐率

驱逐事件的快速增加以及非常高的数据库 CPU 使用率意味着 usersrealms 缓存对于 Keycloak 的平滑操作来说太小了,因为数据需要非常频繁地从数据库中重新加载,这会减慢响应速度。如果可用内存充足,请考虑使用 CLI 选项 cache-embedded-users-max-countcache-embedded-realms-max-count 增加最大缓存大小。

锁定

写入和移除操作会保持锁定,直到该值在本地集群和远程站点中复制。

在一个健康的集群中,锁定的数量应该保持不变,但是死锁可能会导致临时峰值。
指标 描述

vendor_lock_manager_number_of_locks_held

当前由该节点持有的锁的数量。

事务

事务性缓存使用单阶段提交和两阶段提交协议来完成事务。这些指标跟踪操作的持续时间。

PESSMISTIC 锁定模式使用单阶段提交,并且不会创建提交请求。
在一个健康的集群中,回滚的数量应该保持为零。死锁应该很少见,但它们会增加回滚的数量。
指标 描述

vendor_transactions_prepare_times_seconds_count

准备请求的总数。

vendor_transactions_prepare_times_seconds_sum

所有准备请求的总持续时间。

vendor_transactions_rollback_times_seconds_count

回滚请求的总数。

vendor_transactions_rollback_times_seconds_sum

所有回滚请求的总持续时间。

vendor_transactions_commit_times_seconds_count

提交请求的总数。

vendor_transactions_commit_times_seconds_sum

所有提交请求的总持续时间。

启用直方图后,可以使用百分位桶。这些对创建热图很有用,但收集和公开百分位桶可能会对部署性能产生负面影响。

状态转移

状态转移发生在节点加入或离开集群时。它需要平衡存储的数据并保证所需的副本数量。

此操作会增加资源使用量,并且会对整体性能产生负面影响。

指标 描述

vendor_state_transfer_manager_inflight_transactional_segment_count

本地节点从其他节点请求的正在进行的事务段的数量。

vendor_state_transfer_manager_inflight_segment_transfer_count

本地节点从其他节点请求的正在进行的段的数量。

集群数据复制

集群数据复制可能是故障的主要来源。这些指标不仅报告响应时间(即复制更新所需的时间),还报告故障。

在一个健康的集群中,平均复制时间将保持稳定或变化很小。故障的数量不应该增加。
指标 描述

vendor_rpc_manager_replication_count

成功复制的总数。

vendor_rpc_manager_replication_failures

复制失败的总数。

vendor_rpc_manager_average_replication_time

在集群中复制数据的平均时间(以毫秒为单位)。

成功率

可以使用表达式计算复制成功率

(vendor_rpc_manager_replication_count)/(vendor_rpc_manager_replication_count+vendor_rpc_manager_replication_failures)