Finalist

Finalist Developers Blog

Slimmere web applicaties door JMX

4 June 2007 10:00 · Bjorn Tyla · Java

Java Management Extensions (JMX) is een framework voor het beheren en monitoren van applicaties en services. Vanaf het J2SE platform 5.0 is JMX een standaard onderdeel van de distributie.

De toepassing van JMX in een applicatie biedt een software ontwikkelaar toegang tot waardevolle informatie gedurende de lifecycle van de applicatie. Tijdens het ontwikkelen is de debugger je beste vriend, echter eenmaal gedeployed zijn de debug mogelijkheden vaak beperkt. Het JMX framework biedt je de mogelijkheid om een draaiend systeem te analyseren en zelfs te corrigeren, zonder het systeem offline te brengen of te herstarten.

In deze blog wil ik een simpele en praktische toepassing van JMX in een web applicatie demonstreren aan de hand van een tweetal servlet filters. Een inleiding JMX en servlet filters valt buiten de scope van dit artikel.

De Basis

De vereiste JMX registratie details zijn in een herbruikbare base class “ManagedFilter” geïmplementeerd. Tevens implementeert deze class een JMX interface om het filter aan of uit te zetten.

jmxumlbase.png

Request Counter

De eerste toepassing is een simpel filter, dat het aantal gefilterde HTTP requests telt. Tevens biedt dit filter de mogelijkheid om de teller te herstarten.

jmxumlcounter.png

Dit filter is handig om bijvoorbeeld communicatie tussen twee processen te controleren.

public class RequestCounterFilter extends ManagedFilter 
implements RequestCounterFilterMBean {
    private final AtomicInteger requestCounter = new AtomicInteger();
 
    public void doFilter(
        final ServletRequest  req,
        final ServletResponse rsp,
        final FilterChain chain)
    throws IOException, ServletException {
        if (!isDisabled()) {
            requestCounter.incrementAndGet();
        }
        chain.doFilter(req, rsp);
    }
 
    public int getRequestCounter() {
        return requestCounter.get();
    }
 
    public void resetRequestCounter() {
        requestCounter.set(0);
    }
}

Zelfbeheersing

De JMX interface is niet alleen voor extern management, maar kan ook door het systeem zelf gebruikt worden. Het systeem kan de JMX interface gebruiken om zichzelf te monitoren en te behoeden voor overbelasting.

Een toepassing hiervan is bijvoorbeeld een servlet filter dat HTTP opdrachten weigert middels de HTTP fout code 503 (service unavailable) zolang er onvoldoende systeem resources zoals geheugen of disk ruimte beschikbaar zijn. Wanneer er weer voldoende capaciteit is zal het filter weer opdrachten doorlaten. Op deze manier beschermd het systeem zich tegen overbelasting, maar blijft het binnen gestelde grenzen functioneren.

Als tweede toepassing een servlet filter, dat een queue middels JMX in de gaten houdt. Zolang het aantal opdrachten in de queue te groot is, wordt de toevoer van nieuwe opdrachten geblokkeerd. De JMX GaugeMonitor die hiervoor wordt gebruikt, is zelf ook weer middels de JMX interface te beheren. Zo kunnen de waardes van de thresholds achteraf bijgesteld worden.

jmxumlmonitor.png

Het filter creëert een JMX GaugeMonitor tijdens filter initialisatie. Deze monitor controleert actief de “backlog” property van de “observable” queue en zal notificaties genereren als de thresholds overschreden worden.

public class BackPressureFilter extends ManagedFilter 
implements NotificationListener, BackPressureFilterMBean {
    private final AtomicBoolean serviceUnavailable = new AtomicBoolean();
 
    private ObjectName monitorName;
 
    public boolean isServiceUnavailable() {
        return serviceUnavailable.get();
    }
 
    public void init() throws ServletException {
        super.init();
 
        try {
            final MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
 
            // observable object name
            final ObjectName objName = new ObjectName(getDomain() + 
                    ":type=Servlet,name=ProcessorServlet");
 
            // construct monitor
            final GaugeMonitor monitor = new GaugeMonitor();
 
            monitor.addObservedObject(objName);
            monitor.setObservedAttribute("Backlog");
            monitor.setNotifyHigh(true);
            monitor.setNotifyLow (true);
            monitor.setThresholds(50, 25); // hi, low threshold
            monitor.setGranularityPeriod(5000L);
 
            monitorName = new ObjectName(getDomain() + 
                    ":type=" + getObjectTypeAttr() +
                    ",name=" + getObjectNameAttr() +
                    ",subType=Monitor" +
                    ",subName=" + objName.getKeyProperty("name"));
 
            mbs.registerMBean(monitor, monitorName);
 
            monitor.addNotificationListener(this, null, null);
 
            monitor.start();
        }
        catch (final Exception e) {
            // ...handle exception
        }
    }
 
    public void destroy() {
        // ...deregister monitor with the MBean server and call super.destroy()
    }
 
    public void doFilter(
            final ServletRequest  req, 
            final ServletResponse rsp,
            final FilterChain chain) 
    throws IOException, ServletException {
        if (!isDisabled()) {
            if (isServiceUnavailable()) {
                ((HttpServletResponse) rsp).sendError(
                    HttpServletResponse.SC_SERVICE_UNAVAILABLE);
                return;
            }
        }
        chain.doFilter(req, rsp);
    }
 
    public void handleNotification(final Notification notification, final Object handback) {
        if (notification instanceof MonitorNotification) {
            final String type = notification.getType();
 
            if (type.equals(MonitorNotification.THRESHOLD_HIGH_VALUE_EXCEEDED)) {
                serviceUnavailable.set(true);
                return;
            }
            if (type.equals(MonitorNotification.THRESHOLD_LOW_VALUE_EXCEEDED)) {
                serviceUnavailable.set(false);
                return;
            }
        }
    }
}

Het geheel is als een Eclipse WTP project te downloaden.

Referenties

—————————————————————————————
Meer weten over Java-specialist Finalist IT Group?

Share and Enjoy:
  • E-mail this story to a friend!
  • Print this article!
  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • Blogosphere News
  • Fleck
  • NuJIJ
  • Slashdot
  • StumbleUpon
  • LinkedIn
  • Twitter

Reageer

RSS feed for comments on this post · TrackBack URI