

# 在 Amazon EKS 和 Kubernetes 上设置 Java/JMX 示例工作负载
<a name="ContainerInsights-Prometheus-Sample-Workloads-javajmx"></a>

JMX Exporter 是 Prometheus 的官方导出程序，可以将 JMX MBeans 作为 Prometheus 指标进行抓取和公开。有关详细信息，请参阅 [prometheus/jmx\$1exporter](https://github.com/prometheus/jmx_exporter)。

Container Insights 可以使用 JMX Exporter 从 Java 虚拟机 (JVM)、Java 和 Tomcat (Catalina) 收集预定义的 Prometheus 指标。

## 默认 Prometheus 抓取配置
<a name="ContainerInsights-Prometheus-Sample-Workloads-javajmx-default"></a>

默认情况下，支持 Prometheus 的 CloudWatch 代理从 Amazon EKS 或 Kubernetes 集群中的每个 pod 上的 `http://CLUSTER_IP:9404/metrics` 抓取 Java/JMX Prometheus 指标。这是通过 Prometheus `kubernetes_sd_config` 的 `role: pod` 发现来完成的。9404 是 Prometheus 为 JMX Exporter 分配的默认端口。有关 `role: pod` 发现的更多信息，请参阅 [pod](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#pod)。您可以将 JMX Exporter 配置为在不同端口或 metrics\$1path 上公开指标。如果您更改了端口或路径，请更新 CloudWatch 代理 config 映射中的默认 jmx scrape\$1config。运行以下命令以获取当前 CloudWatch 代理 Prometheus 配置：

```
kubectl describe cm prometheus-config -n amazon-cloudwatch
```

要更改的字段是 `/metrics` 和 `regex: '.*:9404$'` 字段，如以下示例中突出显示所示。

```
job_name: 'kubernetes-jmx-pod'
sample_limit: 10000
metrics_path: /metrics
kubernetes_sd_configs:
- role: pod
relabel_configs:
- source_labels: [__address__]
  action: keep
  regex: '.*:9404$'
- action: replace
  regex: (.+)
  source_labels:
```

## 其他 Prometheus 抓取配置
<a name="ContainerInsights-Prometheus-Sample-Workloads-javajmx-other"></a>

如果您通过 Kubernetes Service 使用 Java/JMX Prometheus 导出器公开在一组 pod 上运行的应用程序，您还可以切换到使用 Prometheus `kubernetes_sd_config` 的 `role: service` 发现或 `role: endpoint` 发现。有关这些发现方法的更多信息，请参阅[服务](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#service)、[端点](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#endpoints) 和 [<kubernetes\$1sd\$1config>](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#kubernetes_sd_config)。

这两种服务发现模式提供了更多元标签，这对构建 CloudWatch 指标维度大有裨益。例如，您可以将 `__meta_kubernetes_service_name` 其重新标记为 `Service` 并将其包含在指标维度中。有关自定义 CloudWatch 指标及其维度的更多信息，请参阅 [Prometheus 的 CloudWatch 代理配置](ContainerInsights-Prometheus-Setup-configure-ECS.md#ContainerInsights-Prometheus-Setup-cw-agent-config)。

## 带有 JMX Exporter 的 Docker 镜像
<a name="ContainerInsights-Prometheus-Sample-Workloads-javajmx-docker"></a>

接下来，构建 Docker 镜像。以下各节提供了两个示例 Dockerfiles。

构建镜像后，请将其加载到 Amazon EKS 或 Kubernetes 中，然后运行以下命令以验证 `JMX_EXPORTER` 是否在端口 9404 上公开 Prometheus 指标。使用正在运行的 pod 名称替换 *\$1JAR\$1SAMPLE\$1TRAFFIC\$1POD*，并使用您的应用程序命名空间替换 *\$1JAR\$1SAMPLE\$1TRAFFIC\$1NAMESPACE*。

如果您在具有 Fargate 启动类型的集群上运行 JMX Exporter，则在执行此过程中的步骤之前，您还需要设置 Fargate 配置文件。要设置配置文件，请输入以下命令。将 *MyCluster* 替换为您的集群的名称。

```
eksctl create fargateprofile --cluster MyCluster \
--namespace $JAR_SAMPLE_TRAFFIC_NAMESPACE\
 --name $JAR_SAMPLE_TRAFFIC_NAMESPACE
```

```
kubectl exec $JAR_SAMPLE_TRAFFIC_POD -n $JARCAT_SAMPLE_TRAFFIC_NAMESPACE -- curl http://localhost:9404
```

## 示例：具有 Prometheus 指标的 Apache Tomcat Docker 镜像
<a name="ContainerInsights-Prometheus-Sample-Workloads-javajmx-tomcat"></a>

默认情况下，Apache Tomcat 服务器公开 JMX MBeans。您可以将 JMX Exporter 与 Tomcat 集成，以便将 JMX MBeans 作为 Prometheus 指标公开。以下示例 Dockerfile 显示了构建测试镜像的步骤：

```
# From Tomcat 9.0 JDK8 OpenJDK 
FROM tomcat:9.0-jdk8-openjdk 

RUN mkdir -p /opt/jmx_exporter

COPY ./jmx_prometheus_javaagent-0.12.0.jar /opt/jmx_exporter
COPY ./config.yaml /opt/jmx_exporter
COPY ./setenv.sh /usr/local/tomcat/bin 
COPY your web application.war /usr/local/tomcat/webapps/

RUN chmod  o+x /usr/local/tomcat/bin/setenv.sh

ENTRYPOINT ["catalina.sh", "run"]
```

下面的列表解释了此 Dockerfile 中的四个 `COPY` 行。
+ 从 [https://github.com/prometheus/jmx\$1exporter](https://github.com/prometheus/jmx_exporter) 下载最新的 JMX Exporter jar 文件。
+ `config.yaml` 是 JMX Exporter 配置文件。有关更多信息，请参阅 [https://github.com/prometheus/jmx\$1exporter\$1Configuration](https://github.com/prometheus/jmx_exporter#Configuration )。

  以下是 Java 和 Tomcat 的示例配置文件：

  ```
  lowercaseOutputName: true
  lowercaseOutputLabelNames: true
  
  rules:
  - pattern: 'java.lang<type=OperatingSystem><>(FreePhysicalMemorySize|TotalPhysicalMemorySize|FreeSwapSpaceSize|TotalSwapSpaceSize|SystemCpuLoad|ProcessCpuLoad|OpenFileDescriptorCount|AvailableProcessors)'
    name: java_lang_OperatingSystem_$1
    type: GAUGE
  
  - pattern: 'java.lang<type=Threading><>(TotalStartedThreadCount|ThreadCount)'
    name: java_lang_threading_$1
    type: GAUGE
  
  - pattern: 'Catalina<type=GlobalRequestProcessor, name=\"(\w+-\w+)-(\d+)\"><>(\w+)'
    name: catalina_globalrequestprocessor_$3_total
    labels:
      port: "$2"
      protocol: "$1"
    help: Catalina global $3
    type: COUNTER
  
  - pattern: 'Catalina<j2eeType=Servlet, WebModule=//([-a-zA-Z0-9+&@#/%?=~_|!:.,;]*[-a-zA-Z0-9+&@#/%=~_|]), name=([-a-zA-Z0-9+/$%~_-|!.]*), J2EEApplication=none, J2EEServer=none><>(requestCount|maxTime|processingTime|errorCount)'
    name: catalina_servlet_$3_total
    labels:
      module: "$1"
      servlet: "$2"
    help: Catalina servlet $3 total
    type: COUNTER
  
  - pattern: 'Catalina<type=ThreadPool, name="(\w+-\w+)-(\d+)"><>(currentThreadCount|currentThreadsBusy|keepAliveCount|pollerThreadCount|connectionCount)'
    name: catalina_threadpool_$3
    labels:
      port: "$2"
      protocol: "$1"
    help: Catalina threadpool $3
    type: GAUGE
  
  - pattern: 'Catalina<type=Manager, host=([-a-zA-Z0-9+&@#/%?=~_|!:.,;]*[-a-zA-Z0-9+&@#/%=~_|]), context=([-a-zA-Z0-9+/$%~_-|!.]*)><>(processingTime|sessionCounter|rejectedSessions|expiredSessions)'
    name: catalina_session_$3_total
    labels:
      context: "$2"
      host: "$1"
    help: Catalina session $3 total
    type: COUNTER
  
  - pattern: ".*"
  ```
+ `setenv.sh` 是一个 Tomcat 启动脚本，用于启动 JMX Exporter 和 Tomcat，并在本地主机的端口 9404 上公开 Prometheus 指标。它还为 JMX Exporter 提供 `config.yaml` 文件路径。

  ```
  $ cat setenv.sh 
  export JAVA_OPTS="-javaagent:/opt/jmx_exporter/jmx_prometheus_javaagent-0.12.0.jar=9404:/opt/jmx_exporter/config.yaml $JAVA_OPTS"
  ```
+ 您的 Web 应用程序 .war 是由 Tomcat 加载的 Web 应用程序 `war` 文件。

使用此配置构建 Docker 镜像并将其上载到镜像存储库。

## 示例：具有 Prometheus 指标的 Java Jar 应用程序 Docker 镜像
<a name="ContainerInsights-Prometheus-Sample-Workloads-javajmx-jar"></a>

以下示例 Dockerfile 显示了构建测试镜像的步骤：

```
# Alpine Linux with OpenJDK JRE
FROM openjdk:8-jre-alpine

RUN mkdir -p /opt/jmx_exporter

COPY ./jmx_prometheus_javaagent-0.12.0.jar /opt/jmx_exporter
COPY ./SampleJavaApplication-1.0-SNAPSHOT.jar /opt/jmx_exporter
COPY ./start_exporter_example.sh /opt/jmx_exporter
COPY ./config.yaml /opt/jmx_exporter

RUN chmod -R o+x /opt/jmx_exporter
RUN apk add curl

ENTRYPOINT exec /opt/jmx_exporter/start_exporter_example.sh
```

下面的列表解释了此 Dockerfile 中的四个 `COPY` 行。
+ 从 [https://github.com/prometheus/jmx\$1exporter](https://github.com/prometheus/jmx_exporter) 下载最新的 JMX Exporter jar 文件。
+ `config.yaml` 是 JMX Exporter 配置文件。有关更多信息，请参阅 [https://github.com/prometheus/jmx\$1exporter\$1Configuration](https://github.com/prometheus/jmx_exporter#Configuration )。

  以下是 Java 和 Tomcat 的示例配置文件：

  ```
  lowercaseOutputName: true
  lowercaseOutputLabelNames: true
  
  rules:
  - pattern: 'java.lang<type=OperatingSystem><>(FreePhysicalMemorySize|TotalPhysicalMemorySize|FreeSwapSpaceSize|TotalSwapSpaceSize|SystemCpuLoad|ProcessCpuLoad|OpenFileDescriptorCount|AvailableProcessors)'
    name: java_lang_OperatingSystem_$1
    type: GAUGE
  
  - pattern: 'java.lang<type=Threading><>(TotalStartedThreadCount|ThreadCount)'
    name: java_lang_threading_$1
    type: GAUGE
  
  - pattern: 'Catalina<type=GlobalRequestProcessor, name=\"(\w+-\w+)-(\d+)\"><>(\w+)'
    name: catalina_globalrequestprocessor_$3_total
    labels:
      port: "$2"
      protocol: "$1"
    help: Catalina global $3
    type: COUNTER
  
  - pattern: 'Catalina<j2eeType=Servlet, WebModule=//([-a-zA-Z0-9+&@#/%?=~_|!:.,;]*[-a-zA-Z0-9+&@#/%=~_|]), name=([-a-zA-Z0-9+/$%~_-|!.]*), J2EEApplication=none, J2EEServer=none><>(requestCount|maxTime|processingTime|errorCount)'
    name: catalina_servlet_$3_total
    labels:
      module: "$1"
      servlet: "$2"
    help: Catalina servlet $3 total
    type: COUNTER
  
  - pattern: 'Catalina<type=ThreadPool, name="(\w+-\w+)-(\d+)"><>(currentThreadCount|currentThreadsBusy|keepAliveCount|pollerThreadCount|connectionCount)'
    name: catalina_threadpool_$3
    labels:
      port: "$2"
      protocol: "$1"
    help: Catalina threadpool $3
    type: GAUGE
  
  - pattern: 'Catalina<type=Manager, host=([-a-zA-Z0-9+&@#/%?=~_|!:.,;]*[-a-zA-Z0-9+&@#/%=~_|]), context=([-a-zA-Z0-9+/$%~_-|!.]*)><>(processingTime|sessionCounter|rejectedSessions|expiredSessions)'
    name: catalina_session_$3_total
    labels:
      context: "$2"
      host: "$1"
    help: Catalina session $3 total
    type: COUNTER
  
  - pattern: ".*"
  ```
+ `start_exporter_example.sh` 是用于启动导出了 Prometheus 指标的 JAR 应用程序的脚本。它还为 JMX Exporter 提供 `config.yaml` 文件路径。

  ```
  $ cat start_exporter_example.sh 
  java -javaagent:/opt/jmx_exporter/jmx_prometheus_javaagent-0.12.0.jar=9404:/opt/jmx_exporter/config.yaml -cp  /opt/jmx_exporter/SampleJavaApplication-1.0-SNAPSHOT.jar com.gubupt.sample.app.App
  ```
+ SampleJavaApplication-1.0-SNAPSHOT.jar 是示例 Java 应用程序 jar 文件。将其替换为要监控的 Java 应用程序。

使用此配置构建 Docker 镜像并将其上载到镜像存储库。