JMX Support Spring Integration provides Channel Adapters for receiving and publishing JMX Notifications. There is also an Inbound Channel Adapter for polling JMX MBean attribute values, and an Outbound Channel Adapter for invoking JMX MBean operations.
Notification Listening Channel Adapter The Notification-listening Channel Adapter requires a JMX ObjectName for the MBean that publishes notifications to which this listener should be registered. A very simple configuration might look like this: ]]> The notification-listening-channel-adapter registers with an MBeanServer at startup, and the default bean name is mbeanServer which happens to be the same bean name generated when using Spring's <context:mbean-server/> element. If you need to use a different name, be sure to include the mbean-server attribute. The adapter can also accept a reference to a NotificationFilter and a handback Object to provide some context that is passed back with each Notification. Both of those attributes are optional. Extending the above example to include those attributes as well as an explicit MBeanServer bean name would produce the following: ]]> The Notification-listening Channel Adapter is event-driven and registered with the MBeanServer directly. It does not require any poller configuration. For this component only, the object-name attribute can contain an ObjectName pattern (e.g. "org.foo:type=Bar,name=*") and the adapter will receive notifications from all MBeans with ObjectNames that match the pattern. In addition, the object-name attribute can contain a SpEL reference to a <util:list/> of ObjectName patterns: org.foo:type=Foo,name=* org.foo:type=Bar,name=* ]]> The names of the located MBean(s) will be logged when DEBUG level logging is enabled.
Notification Publishing Channel Adapter The Notification-publishing Channel Adapter is relatively simple. It only requires a JMX ObjectName in its configuration as shown below. ]]> It does also require that an MBeanExporter be present in the context. That is why the <context:mbean-export/> element is shown above as well. When Messages are sent to the channel for this adapter, the Notification is created from the Message content. If the payload is a String it will be passed as the message text for the Notification. Any other payload type will be passed as the userData of the Notification. JMX Notifications also have a type, and it should be a dot-delimited String. There are two ways to provide the type. Precedence will always be given to a Message header value associated with the JmxHeaders.NOTIFICATION_TYPE key. On the other hand, you can rely on a fallback default-notification-type attribute provided in the configuration. ]]>
Attribute Polling Channel Adapter The Attribute Polling Channel Adapter is useful when you have a requirement, to periodically check on some value that is available through an MBean as a managed attribute. The poller can be configured in the same way as any other polling adapter in Spring Integration (or it's possible to rely on the default poller). The object-name and attribute-name are required. An MBeanServer reference is also required, but it will automatically check for a bean named mbeanServer by default, just like the Notification-listening Channel Adapter described above. ]]>
Tree Polling Channel Adapter The Tree Polling Channel Adapter queries the JMX MBean tree and sends a message with a payload that is the graph of objects that matches the query. By default the MBeans are mapped to primitives and simple Objects like Map, List and arrays - permitting simple transformation, for example, to JSON. An MBeanServer reference is also required, but it will automatically check for a bean named mbeanServer by default, just like the Notification-listening Channel Adapter described above. A basic configuration would be: ]]> This will include all attributes on the MBeans selected. You can filter the attributes by providing an MBeanObjectConverter that has an appropriate filter configured. The converter can be provided as a reference to a bean definition using the converter attribute, or as an inner <bean/> definition. A DefaultMBeanObjectConverter is provided which can take a MBeanAttributeFilter in its constructor argument. Two standard filters are provided; the NamedFieldsMBeanAttributeFilter allows you to specify a list of attributes to include and the NotNamedFieldsMBeanAttributeFilter allows you to specify a list of attributes to exclude. You can also implement your own filter
Operation Invoking Channel Adapter The operation-invoking-channel-adapter enables Message-driven invocation of any managed operation exposed by an MBean. Each invocation requires the operation name to be invoked and the ObjectName of the target MBean. Both of these must be explicitly provided via adapter configuration: ]]> Then the adapter only needs to be able to discover the mbeanServer bean. If a different bean name is required, then provide the mbean-server attribute with a reference. The payload of the Message will be mapped to the parameters of the operation, if any. A Map-typed payload with String keys is treated as name/value pairs, whereas a List or array would be passed as a simple argument list (with no explicit parameter names). If the operation requires a single parameter value, then the payload can represent that single value, and if the operation requires no parameters, then the payload would be ignored. If you want to expose a channel for a single common operation to be invoked by Messages that need not contain headers, then that option works well.
Operation Invoking Outbound Gateway Similar to the operation-invoking-channel-adapter Spring Integration also provides a operation-invoking-outbound-gateway, which could be used when dealing with non-void operations and a return value is required. Such return value will be sent as message payload to the reply-channel specified by this Gateway. ]]> If the reply-channel attribute is not provided, the reply message will be sent to the channel that is identified by the MessageHeaders.REPLY_CHANNEL header. That header is typically auto-created by the entry point into a message flow, such as any Gateway component. However, if the message flow was started by manually creating a Spring Integration Message and sending it directly to a Channel, then you must specify the message header explicitly or use the provided reply-channel attribute.
MBean Exporter Spring Integration components themselves may be exposed as MBeans when the IntegrationMBeanExporter is configured. To create an instance of the IntegrationMBeanExporter, define a bean and provide a reference to an MBeanServer and a domain name (if desired). The domain can be left out, in which case the default domain is org.springframework.integration. ]]> Once the exporter is defined, start up your application with: -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=6969 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false Then start JConsole (free with the JDK), and connect to the local process on localhost:6969 to get a look at the management endpoints exposed. (The port and client are just examples to get you started quickly, there are other JMX clients available and some offer more sophisticated features than JConsole.) The MBean exporter is orthogonal to the one provided in Spring core - it registers message channels and message handlers, but not itself. You can expose the exporter itself, and certain other components in Spring Integration, using the standard <context:mbean-export/> tag. The exporter has a some metrics attached to it, for instance a count of the number of active handlers and the number of queued messages. It also has a useful operation, as discussed in .
MBean ObjectNames All the MessageChannel, MessageHandler and MessageSource instances in the application are wrapped by the MBean exporter to provide management and monitoring features. The generated JMX object names for each component type are listed in the table below: <tgroup cols="2"> <colspec colnum="1" colname="col1" colwidth="1*"/> <colspec colnum="2" colname="col2" colwidth="3*"/> <thead> <row> <entry align="center">Component Type</entry> <entry align="center">ObjectName</entry> </row> </thead> <tbody> <row> <entry>MessageChannel</entry> <entry>o.s.i:type=MessageChannel,name=<channelName></entry> </row> <row> <entry>MessageSource</entry> <entry>o.s.i:type=MessageSource,name=<channelName>,bean=<source></entry> </row> <row> <entry>MessageHandler</entry> <entry>o.s.i:type=MessageSource,name=<channelName>,bean=<source></entry> </row> </tbody> </tgroup> </table> <para> The <emphasis>bean</emphasis> attribute in the object names for sources and handlers takes one of the values in the table below: </para> <table> <title /> <tgroup cols="2"> <colspec colnum="1" colname="col1" colwidth="1*"/> <colspec colnum="2" colname="col2" colwidth="3*"/> <thead> <row> <entry align="center">Bean Value</entry> <entry align="center">Description</entry> </row> </thead> <tbody> <row> <entry>endpoint</entry> <entry>The bean name of the enclosing endpoint (e.g. <service-activator>) if there is one </entry> </row> <row> <entry>anonymous</entry> <entry>An indication that the enclosing endpoint didn't have a user-specified bean name, so the JMX name is the input channel name </entry> </row> <row> <entry>internal</entry> <entry>For well-known Spring Integration default components </entry> </row> <row> <entry>handler</entry> <entry>None of the above: fallback to the <literal>toString()</literal> of the object being monitored (handler or source) </entry> </row> </tbody> </tgroup> </table> </section> <section id="jmx-channel-features"> <title>MessageChannel MBean Features Message channels report metrics according to their concrete type. If you are looking at a DirectChannel, you will see statistics for the send operation. If it is a QueueChannel, you will also see statistics for the receive operation, as well as the count of messages that are currently buffered by this QueueChannel. In both cases there are some metrics that are simple counters (message count and error count), and some that are estimates of averages of interesting quantities. The algorithms used to calculate these estimates are described briefly in the table below:
<tgroup cols="3"> <colspec colnum="1" colname="col1" colwidth="1*"/> <colspec colnum="2" colname="col2" colwidth="1.5*"/> <colspec colnum="3" colname="col3" colwidth="3*"/> <thead> <row> <entry align="center">Metric Type</entry> <entry align="center">Example</entry> <entry align="center">Algorithm</entry> </row> </thead> <tbody> <row> <entry>Count</entry> <entry>Send Count</entry> <entry>Simple incrementer. Increase by one when an event occurs. </entry> </row> <row> <entry>Duration</entry> <entry>Send Duration (method execution time in milliseconds) </entry> <entry>Exponential Moving Average with decay factor 10. Average of the method execution time over roughly the last 10 measurements. </entry> </row> <row> <entry>Rate</entry> <entry>Send Rate (number of operations per second)</entry> <entry>Inverse of Exponential Moving Average of the interval between events with decay in time (lapsing over 60 seconds) and per measurement (last 10 events). </entry> </row> <row> <entry>Ratio</entry> <entry>Send Error Ratio (ratio of errors to total sends)</entry> <entry>Estimate the success ratio as the Exponential Moving Average of the series composed of values 1 for success and 0 for failure (decaying as per the rate measurement over time and events). Error ratio is 1 - success ratio. </entry> </row> </tbody> </tgroup> </table> <para> A feature of the time-based average estimates is that they decay with time if no new measurements arrive. To help interpret the behaviour over time, the time (in seconds) since the last measurement is also exposed as a metric. </para> <para> There are two basic exponential models: decay per measurement (appropriate for duration and anything where the number of measurements is part of the metric), and decay per time unit (more suitable for rate measurements where the time in between measurements is part of the metric). Both models depend on the fact that </para> <screen>S(n) = sum(i=0,i=n) w(i) x(i)</screen> <para> has a special form when <literal>w(i) = r^i</literal>, with <literal>r=constant</literal>: </para> <screen>S(n) = x(n) + r S(n-1)</screen> <para> (so you only have to store <literal>S(n-1)</literal>, not the whole series <literal>x(i)</literal>, to generate a new metric estimate from the last measurement). The algorithms used in the duration metrics use <literal>r=exp(-1/M)</literal> with <literal>M=10</literal>. The net effect is that the estimate <literal>S(n)</literal> is more heavily weighted to recent measurements and is composed roughly of the last <literal>M</literal> measurements. So <literal>M</literal> is the "window" or lapse rate of the estimate In the case of the vanilla moving average, <literal>i</literal> is a counter over the number of measurements. In the case of the rate we interpret <literal>i</literal> as the elapsed time, or a combination of elapsed time and a counter (so the metric estimate contains contributions roughly from the last <literal>M</literal> measurements and the last <literal>T</literal> seconds). </para> </section> <section id="jmx-mbean-shutdown"> <title>Orderly Shutdown Managed Operation The MBean exporter provides a JMX operation to shut down the application in an orderly manner, intended for use before terminating the JVM. Its use and operation are described in .