Spring JMX: Manage beans in runtime

19 06 2016

JMX (Java Management Extensions) allows to change the bean field values or invoke bean methods on the fly at runtime. It is in opposite to DI where you configure application when it starts, using profiles or classpath. With JMX you can tune, monitor or configure your application anytime when it is running.

At the heart of JMX are MBeans. MBean is a JavaBean that exposes certain methods that define the management interface. To make of those exposed methods you can use tool of your choice. My choice is Java Mission Control. Others are VisualVM or JConsole.

With Spring you can expose those methods with annotations. I will guide you how to do it.

Source Code

Source Code for this tutorial you can find on my GitHub at: https://github.com/yacekmm/looksok/tree/JmxDemo/Spring/SpringJMX

Demo app introduction

The simplest app to demonstrate JMX basic capabilities is app with one REST controller exposing one GET resource method:

@RequestMapping(value = "/api/my-jmx-value", method = GET)
public int getManagedAttributeValue(){
    return myJmxValue;
}

The return value of that method will be managed by JMX. You can run the app from my GitHub sources and access that resource at http://127.0.0.1:8080/api/my-jmx-value. The default hardcoded value of 25 will be returned and displayed in your browser.

Exposing Bean as a MBean
First of all you need to annotate your Bean with @ManagedResource so it can expose its methods. My annotated Controller is:

@RestController
@ManagedResource(objectName = "jmxDemo:name=MyController")
public class MyController { ... }

The name value indicates the name under which the MBean will be exported. jmxDemo is a domain and MyController is the name of the MBean.

Exposing Bean’s Attribute via JMX

You can expose a field via accessors methods annotated with @ManagedAttribute. Thanks to that you will be able to change the field value via JMX. Annotated attributes in my controller are:

private int myJmxValue = 25;

@ManagedAttribute
public void setMyJmxValue(int myJmxValue) {
    this.myJmxValue = myJmxValue;
}
    
@ManagedAttribute
public int getMyJmxValue(){
    return myJmxValue;
}

Exposing Bean’s Method via JMX

You can also expose your Bean method to be able to invoke it by JMX. This time the @ManagedOperation annotation should be used:

@ManagedOperation
public void logMyJmxValue(String requester){
    log.info("{} requested to log JmxManagedValue which is: {}",
            requester, myJmxValue);
}

Managing JMX Attributes in Java Mission Control

Java Mission Control (JMC) is a tool you can find in your jdk/bin folder under the jmc.exe name. With JMC you can monitor java process health and manage MBeans. See image below to get familiar with the tool and see how to find your MBean there:

JMC-MBeans

1. run the JMC and under the list of local java processes find your app and connect to its MBean Server
2. go to MBean Browser tab and find jmxDemo domain
3. under MyController you can set the MyJmxValue attribute to any nymber you want
4. go to http://127.0.0.1:8080/api/my-jmx-value and test that the returned value is exactly how you set it

Managing JMX Operations in Java Mission Control

Similarly you can invoke exposed operation via JMC. Go to Operations tab, provide the operation param and execute it. In your app logs you should find message indicating that it actually ran:

[4)-192.168.56.1] p.l.spring.controller.MyController       : Jacek requested to log JmxManagedValue which is: 99
Advertisements




Setting up Glassfish Monitoring – handling connection problems

3 01 2012

On a production environment I came across few (mainly connection related) issues while trying to monitor glassfish application remotely with either JConsole or VisualVM. Tools does not differ in a connection method – problems were exactly the same and not caused by tools, but by glassfish setup, application statuses and firewall configuration.

Standard Settings Required

There is not very much of it. Just turn on Glassfish Monitoring using GUI. For HTTP Service and Web Container at least. LOW level is enough. Set it in: Configuration -> Monitoring.

Default configuration in Configuration -> Admin Service -> System is enough. You can take a look also in Application Server -> Monitor, if You like :)

Problem 1

One of the Glassfish applications in VisualVM is visible but its stats are not available (App #1), and the other application is not visible at all
It appears that this is some old app visible in Glassfish admin GUI, but not existing on the file system. Here is how it looks like in VisualVM:

VisualVM showing dead application

VisualVM Showing dead application

App cannot be analyzed and there is some info on the VisualVM troubleshooting page (at the bottom):

No Servlets Displayed In The Runtime Area Of GlassFish Web Application Tab
Description: There are no servlets displayed in the runtime are of GlassFish web application tab (see here)
Resolution: Only servlets with some statistics available are displayed. In order to generate statistics put some load on the web application.

It appeared that App #1 was an older version of an existing App #2 (that is was not visible because of it). Removing App #1 by Glassfish admin GUI helped to resolve this conflict, and App #2 (the current version showed up and was able to be monitored.

Problem 2

Problem connecting to the remote Glassfish instance
After setting up the Glassfish IP address and credentials the connection could not be established. I solved this issue by dedicated RMI configuration. It was necessary because of a NAT, I suppose. The result is that RMI receives packets from VisualVM, and then responses that it is listening on his local IP address (127.0.0.1). Then VisualVM is lost, because following requests are sent to given IP (127.0.0.1).
The solution is to set in a Glassfish his own external IP address, using GF admin GUI. There You have to set the JVM Parameter:

-Djava.rmi.server.hostname=Glassfish_Server_External_IP_Address

And it works! Helpful sources: source 1 and source 2.

(Theoretical) Problem 3

Maybe jstatd or firewall?
This source states that the jstatd (daemon responsible for RMI) has to be running in order to be able to connect to GF using RMI. I have two hosts with similar configuration, and to the one of them I was able to connect, the other one – not. both of them did not have jstatd running. As it turned out later this was not the problem (my problem was RMI IP described in Problem 2).

So info in this source may be outdated or maybe I’ve made some mistake in using it or it was simply not a case for me.

Firewall can surely be a cause of Your problem. If You know that traffic is blocked – nothing will help. Then I advice You to try setting up Monitoring tool locally on Glassfish Server and connect using Xming. This is also a good solution.

Do not hesitate to ask a question if You need more details!

Did I help you?
I manage this blog and share my knowledge for free sacrificing my time. If you appreciate it and find this information helpful, please consider making a donation in order to keep this page alive and improve quality

Donate Button with Credit Cards

Thank You!





Java VM Monitoring for glassfish applications

29 12 2011

It is good practice to monitor server resources of your webapp. You can really know Your app better with monitoring tools. Not only webapps can be monitored of course.

Recently I encountered some problems with glassfish webapp. I thought that it could be lack of server resources. Although problem was different – I’ve learnt to use some monitoring tools – very useful skill!

There are two free tools You should consider: JConsole, which is included in JDK, and VisualVM which appears to be better for glassfish apps thanks to the dedicated plugin. Tools monitors Memory and CPU usage, active threads and loaded classes for JVM and You can access your webapp remotely with them (provided that traffic is not blocked). Both are user-friendly. Here are some screenshots from GUI:

JConsole GUI

JConsole GUI

VisualVM GUI

VisualVM GUI

JConsole is provided with JDK, so using it does not require installation. It is then good entry point – You can just fire it on localhost and check memory, CPU usage, active threads and classes. Good solution for standalone apps, and starting point for advanced monitoring of webapps. If You’ll find such need You should install VisualVM.

VisualVM can do everything what JConsole can, plus some more: it has dedicated plugin to monitor glassfish web applications (along with a bunch of other plugins). It can show:

  • stats for each (glassfish) application
  • amount of active sessions to Your app
  • max sessions count reached since monitoring started
  • list each servlet in your app and measure the time spent by server on processing it, error count, and hit count.
  • profiler (according to my observations this module influences efficiency of Your webapp, so be careful using it while app is being loaded with big traffic)

It also allows to create snapshots of current monitoring graphs and statistics (it is not just screenshot, but fully usable graphs).

JRockit is another useful suite – full version is paid but, as Oracle representant said, totally helpful and worth trying. Equipped with VisualVM I did not find a need to try anything more. Reading JRockit specifications it seems that tool can be your last help when everything else fails.

Tools mentioned are very useful to find bottleneck of Your app, errors source etc. They do not require a lot of resources to run so You can just fire them and watch graphs. Very useful. Installing them is very easy. Some problems may appear while connecting with app remotely. I’ll describe solutions in the following post.

Did I help you?
I manage this blog and share my knowledge for free sacrificing my time. If you appreciate it and find this information helpful, please consider making a donation in order to keep this page alive and improve quality

Donate Button with Credit Cards

Thank You!








%d bloggers like this: