Extending the Grizzly HTTP Runtime VII: Cluster/load balance GrizzlyAdapter using Apache
With the release of Grizzly 1.9.11, it is now possible to cluster/load balance your GrizzlyAdapter using Apache!
As I described in the previous entry on the topic(I,II,II,IV, V, VI), it is quite simple to embed Grizzly using its’ extension point: GrizzlyAdapter:
GrizzlyWebServer ws = new GrizzlyWebServer("/var/www");
try{
ws.addGrizzlyAdapter(new GrizzlyAdapter(){
public void service(GrizzlyRequest request, GrizzlyResponse response){
try {
response.getWriter().println("Grizzly is so cool!!!");
} catch (IOException ex) {
}
}
});
ws.start();
} catch (IOException ex){
// Something when wrong.
}
Now let’s assume you want to add clustering/load balancing support to your GrizzlyAdapter. To add such support, let’s use Apache 2 and mod_jk. To install mod_jk and Apache, just install mod_jk module (see here for an example):
LoadModule jk_module /usr/apache2/httpd/modules/mod_jk.so JkWorkersFile /etc/apache2/conf/worker.properties # Where to put jk logs JkLogFile /var/log/apache2/mod_jk.log # Set the jk log level [debug/error/info] JkLogLevel debug # Select the log format JkLogStampFormat "[%a %b %d %H:%M:%S %Y] " # JkOptions indicate to send SSL KEY SIZE, JkOptions +ForwardKeySize +ForwardURICompat -ForwardDirectories # JkRequestLogFormat set the request format JkRequestLogFormat "%w %V %T" # Send all grizzly/ requests to Grizzly JkMount /grizzly/* worker1The add in your /etc/apache2/worker.properties# Define 1 real worker using ajp13 worker.list=worker1 # Set properties for worker1 (ajp13) worker.worker1.type=ajp13 worker.worker1.host=localhost.localdomain worker.worker1.port=8009 worker.worker1.lbfactor=50 worker.worker1.cachesize=10 worker.worker1.cache_timeout=600 worker.worker1.socket_keepalive=1 worker.worker1.socket_timeout=300
With the above, we are telling Apache to forward (via mod_jk) all requests starting with /grizzly to …. GrizzlyWebServer! How? Let’s take the previous example and add support for mod_jk:
GrizzlyWebServer ws = new GrizzlyWebServer("/var/www");
try{
ws.addGrizzlyAdapter(new GrizzlyAdapter(){
public void service(GrizzlyRequest request, GrizzlyResponse response){
try {
response.getWriter().println("Grizzly is so cool!!!");
} catch (IOException ex) {
}
}
});
ws.enableProtocol(PROTOCOL.AJP);
ws.start();
} catch (IOException ex){
// Something when wrong.
}
Just compile, java -jar …That’s it! Now any blog talking about mod_jk clustering/load balancing configuration can be used with your GrizzlyAdapter. As an example, take a look at this one
For any questions, post them to users@grizzly.dev.java.net or tweet us here.
_uacct = “UA-3111670-1″;
urchinTracker();
technorati: grizzly web server embedded

I have tried using GrizzlyWebServer with AJP and it works fine except for one issue. If I set the protocol to AJP then ws.start() method blocks. Calling stop() doesn’t seem to shut it down properly. In HTTP mode, start() doesn’t block and stop() works fine. My code is pretty much identical to what you have above. I can confirm using netstat that even several minutes after calling stop() port 8009 is still in use.
Salut,
I’m no longer working on Grizzly (resigned from Sun 6 months ago) …. looks like a bug, but better to send the question to users@grizzly.dev.java.net
A+
– Jeanfrancois