Archive

Archive for July 8, 2008

Extending the Grizzly HTTP Runtime part III: Gathering Monster’s Statistics

So far we were able to build a WebServer based on Grizzly and add JMX Support to it. Now it is time to gather statistics of what’s happening inside the monster’ stomach.

mathieu 009.jpg

Part I was about building synchronous and asynchronous Web Server using Grizzly Http Engine, part II demonstrated how to add JMX support and track what’s happening. Let’s re-use the example we used in part II:

 47         GrizzlyWebServer ws = new GrizzlyWebServer(path);
 48         ServletAdapter sa = new ServletAdapter();
 49         sa.setRootFolder("/Path/To/Exploded/War/File");
 50         sa.setServlet(new MyServlet());
 51         sa.setContextPath("/myServlet");
 52         ws.addGrizzlyAdapter(sa);
 53 
 54         ServletAdapter sa2 = new ServletAdapter();
 55         sa2.setRootFolder("/Path/To/Exploded/War2/File");
 56         sa2.setServlet(new MySecondServlet());
 57         sa2.setContextPath("/mySecondServlet");
 58         ws.addGrizzlyAdapter(sa2);
 59 
 60         ws.enableJMX(new Management() {
 61 
 62             public void registerComponent(Object bean, ObjectName oname, String type)
 63                     throws Exception {
 64                 Registry.getRegistry().registerComponent(bean, oname, type);
 65             }
 66 
 67             public void unregisterComponent(ObjectName oname) throws Exception {
 68                 Registry.getRegistry().
 69                         unregisterComponent(oname);
 70             }
 71         });
 72         ws.start();

There are two way to add statistics. First, you can just enable it using JMX and click on enableMonitoring button:

enableMonitoring.jpg

Then start doing request, and you can use jconsole to see the statistics:

Updates.jpg

Programmatically, you can enable statistics by just doing:

     56         GrizzlyWebServer ws = new GrizzlyWebServer(path);
     57         ws.enableJMX(new Management() {
     58 
     59             public void registerComponent(Object bean, ObjectName oname, String type)
     60                     throws Exception{
     61                 Registry.getRegistry().registerComponent(bean,oname,type);
     62             }
     63 
     64             public void unregisterComponent(ObjectName oname) throws Exception{
     65                 Registry.getRegistry().
     66                         unregisterComponent(oname);
     67             }
     68         });
     69 
     70         final Statistics stats = ws.getStatistics();
     71         stats.startGatheringStatistics();

The key method is GrizzlWebServer.getStatistics(). From the Statistics instance, you can start and stop gathering statistics. Below is an example that use a simple scheduler to output data on the console:

     45     // Simple scheduler that will outpot stats every 5 seconds.
     46     private static ScheduledThreadPoolExecutor ste =
     47             new ScheduledThreadPoolExecutor(1);
     48 
     49     public static void main( String args[] ) throws Exception {
     50         String path = args[0];
     51         if (args[0] == null || path == null){
     52             System.out.println("Invalid static resource path");
     53             System.exit(-1);
     54         }
     55 
     56         GrizzlyWebServer ws = new GrizzlyWebServer(path);
     57         ws.enableJMX(new Management() {
     58 
     59             public void registerComponent(Object bean, ObjectName oname, String type)
     60                     throws Exception{
     61                 Registry.getRegistry().registerComponent(bean,oname,type);
     62             }
     63 
     64             public void unregisterComponent(ObjectName oname) throws Exception{
     65                 Registry.getRegistry().
     66                         unregisterComponent(oname);
     67             }
     68         });
     69 
     70         final Statistics stats = ws.getStatistics();
     71         stats.startGatheringStatistics();
     72 
     73         ste.scheduleAtFixedRate(new Runnable() {
     74             public void run() {
     75                 System.out.println("Current connected users: " +
     76                         stats.getKeepAliveStatistics().getCountConnections());
     77                 System.out.println("How many requests since startup:" +
     78                         stats.getRequestStatistics().getRequestCount());
     79                 System.out.println("How many connection we queued because of all" +
     80                         "thread were busy: " +
     81                         stats.getThreadPoolStatistics().getCountQueued());
     82                 return;
     83             }
     84         }, 0, 10,TimeUnit.SECONDS);
     85         System.out.println("Grizzly WebServer listening on port 8080");
     86         ws.start();
     87     }

Another easy things with the monster! You can download the above example from here (bundled as an OSGi bundle if you like OSGi). Next time I will explore ways to write AsyncFilter, which was partially covered in part 1.

_uacct = “UA-3111670-1″;
urchinTracker();

technorati:

Categories: Uncategorized

Extending the Grizzly HTTP Runtime part II: Managing the monster using JMX

Now that we are all able to create Grizzly Web Server in less than 10 lines, let’s complicate our day and add JMX management to the monster

IMG_0159.JPG

In part I, I’ve described how easy it is to create synchronous and asynchronous http based Web Server. One of the most complicated example was:

GrizzlyWebServer ws = new GrizzlyWebServer("/var/www");
        try{
            ServletAdapter sa = new ServletAdapter();
            sa.setRootFolder("/Path/To/Exploded/War/File");
            sa.setServlet(new MyServlet());
            sa.setContextPath("/myServlet");
            ws.addGrizzlyAdapter(sa);
  
            ServletAdapter sa2 = new ServletAdapter();
            sa2.setRootFolder("/Path/To/Exploded/War2/File");
            sa2.setServlet(new MySecondServlet());
            sa2.setContextPath("/mySecondServlet");
            ws.addGrizzlyAdapter(sa2);
  
            ws.start();
        } catch (IOException ex){
            // Something when wrong.
        }

That wasn’t too difficult, was it? Now let’s add JMX support:

 47         GrizzlyWebServer ws = new GrizzlyWebServer(path);
 48         ServletAdapter sa = new ServletAdapter();
 49         sa.setRootFolder("/Path/To/Exploded/War/File");
 50         sa.setServlet(new MyServlet());
 51         sa.setContextPath("/myServlet");
 52         ws.addGrizzlyAdapter(sa);
 53 
 54         ServletAdapter sa2 = new ServletAdapter();
 55         sa2.setRootFolder("/Path/To/Exploded/War2/File");
 56         sa2.setServlet(new MySecondServlet());
 57         sa2.setContextPath("/mySecondServlet");
 58         ws.addGrizzlyAdapter(sa2);
 59 
 60         ws.enableJMX(new Management() {
 61 
 62             public void registerComponent(Object bean, ObjectName oname, String type)
 63                     throws Exception {
 64                 Registry.getRegistry().registerComponent(bean, oname, type);
 65             }
 66 
 67             public void unregisterComponent(ObjectName oname) throws Exception {
 68                 Registry.getRegistry().
 69                         unregisterComponent(oname);
 70             }
 71         });
 72         ws.start();

To enable JMX, you just need to implement the Management interface, and set it using the enableJMX method of the GrizzlyWebServer class. As you can see, you can plug your own JMX implementation easily using the Management interface. In the example above, I’ve just used the Apache Commons Modeler, which does all the JMX “bla bla bla” for me via its org.apache.commons.modeler.Registry static class.

To see it live, I just do:

%  java -Dcom.sun.management.jmxremote.port=1199 -Dcom.sun.management.jmxremote.authenticate=false \
-Dcom.sun.management.jmxremote.ssl=false -jar grizzly-embed-samples.jar

// Start jconsole
% jconsole

Hey hey I can see:

jconsole.jpg

Miaaaaaam! Next time I will explain how to grab statistics from your embedded GrizzlyWebServer, like number of requests, time spend, thread pool stats, etc. You can download the example above here. The binary can be used as it is and include all the Grizzly required classes to run.

_uacct = “UA-3111670-1″;
urchinTracker();

technorati:

Categories: Uncategorized
Follow

Get every new post delivered to your Inbox.

Join 51 other followers