The sweetest fruit salad recipe for energy saving services

Chapter 5. Profiling

Pau García
DEXMA Engineering Blog
2 min readFeb 26, 2021

--

(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.jar
ENV 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

--

--

Pau García
DEXMA Engineering Blog

Software Engineer who loves to find the simplest and most robust solution for each use case by applying architectural, design and clean-code principles