The sweetest fruit salad recipe for energy saving services
Chapter 5. Profiling
(This story begins in Chapter 0. Launching an energy-saving rocket to the stars)
Before releasing the service, we want to analyse the behaviour of the JVM with all these new technologies and ensure that the component will behave as expected on a high load scenario. From local machine we can easily profile the JVM with JConsole, jvisualvm, Java Mission Control, etc
But we want to go further, providing these profiling tools for the service when running on Kubernetes, and also offering metrics for Webflux reactor components.
In this stage we got the valuable assistance of our DevOps team mates. Most of the investigation and work was actually done by them. Should you want to donate a beer, it should be for them.
Publishing WebClient metrics
First we need to add corresponding dependencies to our maven’s pom:
To enable JMX metrics at the reactor WebClient, we need to add the following to the client:
HttpClient
.create(ConnectionProvider.fixed(“ProviderName”, maxConnections, acquireTimeout, maxIdleTime, maxLifeTime))
.metrics(true)
We can also specify where to place those metrics (just the container name of the JMX metrics). Modify the Application.yml (or equivalent) by adding:
management:
metrics:
export:
jmx:
enabled: true
domain: healthcheck
Docker configuration
Find below our docker configuration, which publishes the JMX metrics and also keeps the direct memory JVM space under control:
FROM amazoncorretto:11
LABEL maintainer=”Dexma <techteam@dexma.com>”
COPY target/*.jar /app.jarENV JAVA_TOOL_OPTIONS “-Dio.netty.noPreferDirect=true \
-XX:MaxDirectMemorySize=32m \
-XX:+UseG1GC \
-Xms256m \
-Xmx512m\
...
-Dcom.sun.management.jmxremote \
-Dcom.sun.management.jmxremote.local.only=false \
-Dcom.sun.management.jmxremote.ssl=false \
-Dcom.sun.management.jmxremote.authenticate=false \
-Dcom.sun.management.jmxremote.port=1099 \
-Dcom.sun.management.jmxremote.rmi.port=1099"ENTRYPOINT [“/usr/bin/java”,”-jar”,”/app.jar”]
Kubernetes
In order to access via JMX client to Kubernetes pods from a local environment, add to the above configuration (inside JAVA_TOOL_OPTIONS):
-Djava.rmi.server.hostname=127.0.0.1
Once Kubernetes cluster is up, we need to forward the ports in our local machine:
kubectl port-forward <POD> 1099:1099
And then open your favourite JVM profiler, to analyse how reactor clients behave, for instance:
jconsole 127.0.0.1:1099
And you can explore how that Kubernetes pod behaves when, for instance, you are running a load test.
Our trip continues in Chapter 6. Caching