将在EC2上运行的Keycloak的JVM指标发送到CloudWatch

我们是株式会社GxP的@rasahina-gxp团队。
本文是我们参与的成长合作伙伴Advent Calendar中第21天的文章。

大家在使用Keycloak吗?
在我所属的部门中,实现单点登录(SSO)时,我们经常使用Keycloak作为提供者。
通常我们使用SpringBoot的KeycloakAdapter作为SSO客户端来开发,但这次我进行了获取Keycloak的JVM指标的工作,现在向大家介绍一下。

Keycloak 是什么?

这是一个基于Wildfly开发的开源身份管理软件。您可以参考官方网站获取更多详细信息。正如前面提到的,我们为SpringBoot提供了适配器,同样我们也为其他各种语言和框架提供了适配器。

研究如何获取Keycloak的JVM指标。

经过初步调查,以下可能获得以下指标(不包括SaaS)。

方法特徴Prometheusエクステンション公式でも紹介されているエクステンションを追加することで利用可能Wildfly設定ファイルで有効化設定ファイルを変更することで利用可能Jolokiaをエージェントとして利用Keycloakに手を入れる必要がなく、Keycloakの外側から利用可能

根据本次要求,我做出了以下决定。

使用Prometheus扩展

由于Keycloak官方网站上有记录这个扩展,所以感觉很可靠。此外,添加扩展后查看指标的工作量较少。但是,由于目前希望监视的Keycloak环境中没有Prometheus存在,而是通过Cloudwatch集中监视指标,所以本次不在监视范围内。

在Wildfly的配置文件中启用

只需在standalone.xml等文件中启用管理端点。
尽管在JConsole中可以轻松连接,但在获取JMX的客户端工具(命令行JMX客户端、Jmxterm等)中,无法直接获取,需要进行一些改进。
另外,由于客户正在构建要监视的Keycloak,并且我们尽量不想对Keycloak进行修改。
因此,由于这种方法在这种情况下会有缺点,我们将不考虑它。

利用Jolokia代理

Jolokia是一款工具,可以通过HTTP获取JMX指标。您可以使用cURL等工具访问并以JSON格式获取指标。
它的优点是可以在不改变Keycloak配置的情况下,使用JVM指标。

我想介绍一下如何使用Jolokia来满足要求的最佳方法。

设置步骤

只需要一个选项

Keycloak的版本是7.0.0。
请下载并在standalone模式下启动。1
参考:https://qiita.com/ryota_i/items/69ded3fd950c7f9b70f5
另外,服务器上需要安装AWS CLI。
参考:https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-chap-install.html

请下载Jolokia。

请从此页面下载JVM代理。

激活Jolokia。

要启动Jololia有两种方法。

选项1:通过指定目标进程ID将进程附加到进程中。

执行以下命令,将显示可附加的Java进程列表。

$ java -jar jolokia-jvm-1.6.2-agent.jar list
23997   jolokia-jvm-1.6.2-agent.jar list
23838   /opt/oss/keycloak-7.0.0/jboss-modules.jar -mp /opt/oss/keycloak-7.0.0/modules org.jboss.as.standalon

接下来,使用目标进程ID作为参数再次执行。

$ java -jar jolokia-jvm-1.6.2-agent.jar start 23838
Couldn't start agent for PID 23838
Possible reason could be that port '8778' is already occupied.
Please check the standard output of the target process for a detailed error message.

由于8778已经被占用,无法启动,输出了无法启动的错误消息,
但是在Keycloak日志中输出了以下内容,说明jolokia成功启动。

02:50:55,576 INFO  [stdout] (JolokiaStart) I> No access restrictor found, access to any MBean is allowed
02:50:56,803 INFO  [stdout] (JolokiaStart) Jolokia: Agent started with URL http://127.0.0.1:8778/jolokia/

让我们尝试使用cURL获取JVM指标。
有关访问方法的详细信息,请参考此处。

# ヒープ利用量の情報を取得
$ curl -s http://localhost:8778/jolokia/read/java.lang:type=Memory/HeapMemoryUsage | jq
{
  "request": {
    "mbean": "java.lang:type=Memory",
    "attribute": "HeapMemoryUsage",
    "type": "read"
  },
  "value": {
    "init": 268435456,
    "committed": 705691648,
    "max": 954728448,
    "used": 293532344
  },
  "timestamp": 1608432046,
  "status": 200
}

通过给路径添加属性,也可以缩小获取结果的范围。

# ヒープ利用量の最大値を取得
$ curl -s http://localhost:8778/jolokia/read/java.lang:type=Memory/HeapMemoryUsage/max | jq
{
  "request": {
    "path": "max",
    "mbean": "java.lang:type=Memory",
    "attribute": "HeapMemoryUsage",
    "type": "read"
  },
  "value": 954728448,
  "timestamp": 1608432086,
  "status": 200
}

选项2:使用JAVA_OPTS将其指定为-javaagent进行附加。

可以通过将-javaagent指定为环境变量JAVA_OPTS来在运行JVM指标获取目标应用程序时也将Jolokia附加到目标进程中。
需要通过安全组或防火墙来控制Jolokia端口不被外部访问到。

$ JAVA_OPTS="$JAVA_OPTS -Djboss.modules.system.pkgs=$JBOSS_MODULES_SYSTEM_PKGS -javaagent:/home/centos/jolokia-jvm-1.6.2-agent.jar=port=8778,host=127.0.0.1" \
./standalone.sh
JAVA_OPTS already set in environment; overriding default settings with values:  -Djboss.modules.system.pkgs= -javaagent:/home/centos/jolokia-jvm-1.6.2-agent.jar=port=8778,host=127.0.0.1
=========================================================================

  JBoss Bootstrap Environment

  JBOSS_HOME: /opt/oss/keycloak-7.0.0

  JAVA: java

  JAVA_OPTS:  -server  -Djboss.modules.system.pkgs= -javaagent:/home/centos/jolokia-jvm-1.6.2-agent.jar=port=8778,host=127.0.0.1

=========================================================================

02:59:36,102 INFO  [org.jboss.modules] (main) JBoss Modules version 1.9.1.Final
I> No access restrictor found, access to any MBean is allowed
Jolokia: Agent started with URL http://127.0.0.1:8778/jolokia/
~~省略~~
02:59:48,945 INFO  [org.jboss.as] (Controller Boot Thread) WFLYSRV0025: Keycloak 7.0.0 (WildFly Core 9.0.2.Final) started in 13262ms - Started 589 of 884 services (601 services are lazy, passive or on-demand)

和方法1一样, Jolokia启动消息会显示出来呢。
关键是需要指定-Djboss.modules.system.pkgs=$JBOSS_MODULES_SYSTEM_PKGS。
如果没有指定这个参数而只指定-javaagent,会导致日志管理相关的问题,使得Keycloak无法启动。
我们可以尝试使用cURL进行获取,就像之前一样。

$ curl -s http://localhost:8778/jolokia/read/java.lang:type=Memory/HeapMemoryUsage | jq
{
  "request": {
    "mbean": "java.lang:type=Memory",
    "attribute": "HeapMemoryUsage",
    "type": "read"
  },
  "value": {
    "init": 62914560,
    "committed": 361758720,
    "max": 883949568,
    "used": 136322976
  },
  "timestamp": 1608433444,
  "status": 200
}

这个也可以用同样的方式取得。

可以获取的指标清单。

您可以通过访问/jolokia/list来获取可获取的度量指标的列表。

$ curl -s http://localhost:8778/jolokia/list | jq
# 取得結果はかなり多いので注意が必要

将度量指标发送到Cloudwatch

到了这一步,后面只需将其发送到Cloudwatch。
我会根据我们公司成员 @ttanaka-gxp 编写的2020年圣诞节日历 第17天的文章来参考脚本。

#!/bin/bash

function put_metics_data() {
    aws cloudwatch put-metric-data --dimensions $1 --timestamp $TIMESTAMP --namespace Jmx --metric-name JmxHeapMemoryUsageCommitted --value $HEAPUSAGE_COMMITED --unit Bytes
    aws cloudwatch put-metric-data --dimensions $1 --timestamp $TIMESTAMP --namespace Jmx --metric-name JmxHeapMemoryUsageUsed --value $HEAPUSAGE_USED --unit Bytes
    aws cloudwatch put-metric-data --dimensions $1 --timestamp $TIMESTAMP --namespace Jmx --metric-name JmxNonHeapMemoryUsageCommitted --value $NONHEAPUSAGE_COMMITED --unit Bytes
    aws cloudwatch put-metric-data --dimensions $1 --timestamp $TIMESTAMP --namespace Jmx --metric-name JmxNonHeapMemoryUsageUsed --value $NONHEAPUSAGE_USED --unit Bytes
}

# Set environment variables
INSTANCE_ID=`curl -s http://169.254.169.254/latest/meta-data/instance-id`
TIMESTAMP=$(date -u +%Y-%m-%dT%H:%M:%SZ)

# jolokiaからメトリクスを取得する
# Heap
HEAPUSAGE_COMMITED=`curl -s http://localhost:8778/jolokia/read/java.lang:type=Memory/HeapMemoryUsage/committed | jq '.value'`
HEAPUSAGE_USED=`curl -s http://localhost:8778/jolokia/read/java.lang:type=Memory/HeapMemoryUsage/used | jq '.value'`

# NonHeap
NONHEAPUSAGE_COMMITED=`curl -s http://localhost:8778/jolokia/read/java.lang:type=Memory/NonHeapMemoryUsage/committed | jq '.value'`
NONHEAPUSAGE_USED=`curl -s http://localhost:8778/jolokia/read/java.lang:type=Memory/NonHeapMemoryUsage/used | jq '.value'`

# メトリクスをCloudwatchに送信する
put_metics_data $INSTANCE_ID

image.png

总结

我們介紹了如何使用Jolokia簡單地獲取Keycloak的JVM指標。在可以使用Prometheus的環境中,首先考慮使用Prometheus擴展,如果無法使用Prometheus,則建議使用上述方法來獲取指標。

请参考

通过脚本访问WildFly的JMX接口

从Logstash中获取Wildfly的JMX信息。链接:https://qiita.com/mkyz08/items/928ff9089ce971470ef0

我对Jolokia的速查表
https://cloudpack.media/10332

通常情况下,不会在生产环境中使用standalone模式。
广告
将在 10 秒后关闭
bannerAds