How to Enable JMX For Java Application Running in the Kubernetes Cluster?
Last Updated :
30 Mar, 2023
Many times we want to monitor our application’s CPU utilization, background thread behavior, and most importantly memory consumptions for tasks that deal with loads for data (500MB – 1GB) or much more data. Such monitoring helps to find which operation is causing heavy CPU or Memory utilization and helps to find the reason behind Memory leak issues or Out of Memory errors. In order to make our java application ready for analysis, one way is to enable the JMX port for the application and monitor its performance using java tools like JvisualVM, JConsole which are packages with JDK and can be used easily from external machines having jdk installed. Below is the guide to enable JMX manually and the steps to configure jvisualvm and jconsole. Connecting to these monitoring tools and seeing CPU, memory, thread consumption is the first step to start solving any performance-related issue in the system. For further analysis, we may need to analyze heap dumps of memory using memory analyzing tools like Eclipse Memory Analyzer or online free tools. One issue is identified that which class objects are taking too much space, you can go deeper into your system code to fix the issue. It could be a bug in the database model or java code which depends on the kind of issue and application.
Below are the steps to enable jmx manually by setting the environment variable
Step 1: Edit the my-app-deployment.yaml by running the below command.
kubectl edit deployment my-app-deployment
In the container’s environments section, add the following parameter (change the NODE_NAME accordingly and use any unused port: 9991)
– name: JAVA_TOOL_OPTIONS
value: -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9991 -Dcom.sun.management.jmxremote.rmi.port=9991 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.local.only=false -Djava.rmi.server.hostname=<NODE_NAME>
If you want to generate Heap Dump to analyze memory-related issues like “Out of Memory error”, give the value of JAVA_TOOL_OPTIONS as below:
value: -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9991 -Dcom.sun.management.jmxremote.rmi.port=9991 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.local.only=false -Djava.rmi.server.hostname=<host-name> -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/dumps/heapdumpJ.hprof
And mount the /dumps like below block:
(If you don’t want to mount, use an existing folder of container like /tmp folder instead of /dumps)
volumeMounts:
– name: heap-dumps
mountPath: /dumps
volumes:
– name: heap-dumps
After saving the changes to the deployment, Kubernetes will automatically redeploy all the pods with the new changes.
Step 2: Edit my-app-svc.yaml by running the below command
kubectl edit service my-app-svc
Add type: NodePort and expose nodePort, refer below sample my-app-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: my-app-svc
namespace: <namespace>
spec:
type: NodePort
ports:
– name: main-port
port: 9992
protocol: TCP
– port: 9991
nodePort: 9991
protocol: TCP
name: jconsole-port
selector:
app: my-app
After saving the changes to the deployment, Kubernetes will automatically restart the service with new changes.
Step 3: Run the below command and check 9991 port is available.
kubectl get service -n <namespace> | grep my-app-svc
Once JMX is enabled for your application, connect to any Performance Analysis Tool to monitor CPU, Memory, Thread Usage of Application.
Running JConsole
- Run jconsole.exe
- JConsole window should appear.
- Click Remote Process and enter the following value, replace the hostname below with your hostname.
- Click Connect. Select the insecure connection. Then jconsole loads up the CPU, Memory, Thread utilization all performance-related metrics:-
Running JVisualVM
- Run jvisualvm.exe
- Right-click Remote and select Add Remote Host.
- Enter your hostname.
- The host should now appear under the Remote section.
- Right-click the newly added host and select Add JMX.
- Enter the <hostname>:<port> for connection, replacing the hostname and port with your actual server.
- Select Do not require an SSL connection.
- Click OK.
- After doing this, a new entry should appear under the host, selecting it will give a remote profile overview.
You are all set to do a performance analysis of your Java Application deployed in the Kubernetes cluster.