将在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扩展
由于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
总结
我們介紹了如何使用Jolokia簡單地獲取Keycloak的JVM指標。在可以使用Prometheus的環境中,首先考慮使用Prometheus擴展,如果無法使用Prometheus,則建議使用上述方法來獲取指標。
请参考
通过脚本访问WildFly的JMX接口
从Logstash中获取Wildfly的JMX信息。链接:https://qiita.com/mkyz08/items/928ff9089ce971470ef0
我对Jolokia的速查表
https://cloudpack.media/10332