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




How to run jMeter tests on Jenkins

24 04 2016

If you monitor your system performance with Apache jMeter test suite, you can easily make it a part of your Continuous Integration and monitor the performance on a regular basis. You need to do three things:

  1. Put your Apache jMeter binary files on Jenkins machine
  2. Run jMeter tests in headless mode from Jenkins job, generating the xml test report
  3. Analyze reports with Jenkins Performance Plugin

Let’s get into details!

1. Put your jMeter binaries on Jenkins

Apache jMeter does not require installation so you can just copy the files that you currently use to the Jenkins server. Thanks to it you will have all the plugins ready to use. Then make sure that user that runs jenkins has access rights to execute jMeter.

2. Run jMeter tests from Jenkins job

Create Jenkins job and, as a Build Step, Execute Shell commands:

#remove previous reports
rm jMeter/reports/*.jtl -f

#run tests
$JMETER_PATH/jmeter -n 
     -t jMeter/suites/sampleSuite.jmx 
     -l jMeter/reports/sampleSuiteReport.jtl 
     -p jMeter/properties/user.properties

where:

  • $JMETER_PATH is a path where you put jMeter binaries (for example /opt/apache-jmeter-2.13/bin/)
  • -n param means that jMeter will be run in headless mode
  • – t jMeter/suites/sampleSuite.jmx is a test suite that you are going to run
  • -l jMeter/reports/sampleSuiteReport.jtl is a result report file that will be generated. This file will be interpreted by Jenkins Performance Plugin
  • -p jMeter/properties/user.properties is a properties file where you configure the report file format to XML (interpreted by default in Jenkins Performance Plugin)

By default the .jtl report file is in the csv format. Jenkins Performance Plugin can read the csv, however the default format for it is xml. By the same token I use user.properties file with one line indicating that the jtl output should be xml:

jmeter.save.saveservice.output_format=xml

3. Analyze reports with Jenkins Performance Plugin

Install the Performance Plugin on your Jenkins instance. To use it, add the Post Build Action to your job, providing the path to .jtl report files:

shot_3

Jtl files will be interpreted each time the job is executed. Moreover in the job page on Jenkins you have new option in menu: Performance Trend, where you can find (on graphs) how your performance was changing over time at each build:

shot_1








%d bloggers like this: