Archive for the Category 'performance'

Grails and Netty

Monday, April 01st, 2013

With all of the buzz about the Play vs Grails Smackdown at Devoxx last week, and this framework benchmark comparison from TechEmpower, I thought it would be interesting to look again at Rossen Stoyanchev’s demo project that integrates Spring MVC with Netty. He had mentioned it on the SpringSource internal developer list and I bookmarked it for later since I was curious about Netty.

I spent the weekend converting Rossen’s code to work with Grails, and created a plugin, borrowing some code from the Spring mock Servlet API classes and also from Tomcat. It’s a weird plugin in that it runs concurrently with the regular web app on a different port. I’m currently taking advantage of the work that Grails does, e.g. creating the Spring ApplicationContext, compiling GSPs in production WARs, etc. But it should be easy enough to get it to run standalone. It’s similar to the Dropwizard plugin, which also adds an alternative and higher-performance request path within a Grails application.

Netty is a generic (but high-performance) network library, so it doesn’t have extensive support for the Servlet API. But it does support HTTP, and that’s what Rossen’s code and my version add – a bridging layer between the lower-level Netty approach and the Servlet API. Ideally this provides a performance and scalability boost from Netty’s non-blocking IO, with the familiarity of the request/response/session approach in the Servlet API.

Most everything works in the plugin, but there are some omissions. There’s no support for SSL, and file upload isn’t implemented. You can do all of the usual Grails stuff, i.e. use controllers, services, GORM, etc. There is support for HTTP Sessions, although they’re not serialized to disk at shutdown and there’s no support for distributed sessions. But other than these items, making requests on the Netty port should work pretty much the same as requests on the servlet container port.

You can install the plugin in the usual way, i.e. add this to BuildConfig.groovy

compile ':nettymvc:0.1'

It will start a server socket on port 8080 by default, but you can configure that in Config.groovy, e.g.

grails.plugin.nettymvc.port = 8090

The plugin page is here and the source is here. Please try it out and let me know if there are issues or if you have suggestions for improvements, ideally in the form of pull requests of course 🙂

Clustering Grails

Saturday, December 19th, 2009

I did a talk on Grails clustering at the Groovy & Grails eXchange 2009 in London last week and wanted to put up the slides and the sample application and clustering scripts. This was the third time I’ve given a version of this talk (first at a Boston Grails meetup and again at SpringOne 2GX) so I’m way overdue getting this up.
(more…)

Groovy & Grails eXchange 2009

Saturday, December 19th, 2009

I got back from the Groovy & Grails eXchange 2009 a few of days ago and wanted to get some thoughts down before the whole thing becomes a blur. It was quite a week – the conference was two days but I brought my wife and extended the trip into a small vacation. We did a bunch of tourist stuff including the Tower of London, the British Museum, Stonehenge, the cathedral in Salisbury, shopping at Oxford Street and Portobello Market, saw a play, etc. Wendy Devolder and her husband Nick graciously offered to meet us Saturday at Portobello Market since they live nearby. Portobello Market is huge but thanks to Wendy and Nick we saw a bunch of stuff we would have otherwise missed, including the amazing Mutate Britain: One Foot in the Grove street art and sculpture show.

There were even other attendees from Boston. My colleague Eugenia Harris (we work together at InnoCentive) was also there for the week so the three of us did a lot of the touristy stuff together, and four guys from Cantina Consulting were also there.

The talks were excellent, but the best thing about these conferences is the social interactions. I met a bunch of Groovy/Grails/Griffon folks in New Orleans at SpringOne 2GX and this was another opportunity to meet even more. I got to meet and talk to several Grails contributors and users including Peter Ledbrook, Marc Palmer, Tomas Lin, Robert Fletcher, Glenn Saqui, Luis Arias, Jakob Külzer, Stefan Armbruster, and Jeremy “The Human Grails Search Engine” Flowers.

The conference was very well run by Russ Miles and Wendy Devolder’s crew at Skills Matter. The space was a little overbooked and would have been better with closer to 100 attendees but they were aware of that and are still getting used to the new location that they recently moved to. Other than that everything was smooth sailing, and they created a conducive environment for a bunch of Grails and Groovy geeks.

One particularly cool aspect was the speaker’s dinner on Tuesday at the Slaughtered Lamb. It was fun talking to (and drinking with) Wendy, Nick, Peter, Tomas, and the rest of the folks there. Not having met people there in person, it was great to make some early introductions before the conference started.

The talks that I found most interesting involved stuff that I rarely use. I don’t do much complex configuration management but I have in the past, so Russel Winder’s Gant talk and Hans Dockter’s Gradle talk were great to get a sense for the current state of the art in build tools. I also don’t do much UI work, but I thought Tomas Lin’s Flex talk and Sébastien Blanc’s iWebkit talk were both pretty cool. They definitely make creating slick UIs look easy.

The highlight of the conference for me though wasn’t actually part of the conference – Graeme Rocher and Peter Ledbrook’s GGUG on Wednesday night on Grails internals. It was a rare opportunity to see a presentation from the two people who have contributed most significantly to Grails. We had a half hour break after a full day at the conference and they spoke and took questions for an hour and a half. It made for a long day, but the audience clearly would have stayed for hours more.

So all in all it was a blast. London was a lot of fun, and Skills Matter put on a great conference. We could use a Skills Matter here in Boston 🙂


You can download the PDF slides and watch the video here. I wrote up a post here showing how to use the sample apps from the talk.

Boston Grails Meetup GORM Presentation

Thursday, August 13th, 2009

I gave a talk last week at the Boston Grails meetup and wanted to share the slides. There were two code demonstrations in the Grails console so I’ll describe those here.

The general gist of the presentation was that mapped collections in Hibernate (and therefore Grails, since GORM wraps Hibernate) are a potentially risky choice for representing One-to-Many and Many-to-Many relationships.

To see what’s going on I added

loggingSql = true

to DataSource.groovy so we’d see the generated SQL in the console when comparing the standard and modified versions of the code.

First we create a Library and associate 20 (a completely arbitrary number) Visits:

def library = new Library(name: 'the library')
20.times {
   library.addToVisits(new Visit(personName: "person$it"))
   library.save(flush: true)
}

Clear the output window and add one more Visit:

def library = Library.list()[0]
library.addToVisits(new Visit(personName: "new person"))
library.save(flush: true)

and you’ll see SQL similar to

select this_.id as id3_0_, this_.version as version3_0_, this_.name as name3_0_ 
from library this_;

select visits0_.library_id as library3_1_, visits0_.id as id1_, visits0_.id as id2_0_,
   visits0_.version as version2_0_, visits0_.library_id as library3_2_0_,
   visits0_.person_name as person4_2_0_, visits0_.visit_date as visit5_2_0_ 
from visit visits0_  where visits0_.library_id=?;

insert  into visit (id, version, library_id, person_name, visit_date) 
values (null, ?, ?, ?, ?);

call identity();

update library
set version=?, name=?
where id=? and version=?;

which means that it’s first loading the Library, then loading all of its previous Visits (!), then creating the new Visit, and finally bumping the version of the Library since it’s “changed”. Not good – not only do we incur a potentially huge performance hit to add one new instance (once there are a large number already), we also run a high risk of a false optimistic locking failure.

Doing the equivalent work with the updated versions:

def library = new Library(name: 'the library').save()
20.times {
    new Visit(personName: "person$it", library: library).save(flush: true)
}

and

def library = Library.list()[0]
new Visit(personName: "new person", library: library).save(flush: true)

we get SQL that makes a lot more sense:

select this_.id as id2_0_, this_.version as version2_0_, this_.name as name2_0_ 
from library this_;

insert into visit (id, version, library_id, person_name, visit_date) 
values (null, ?, ?, ?, ?);

call identity();

First the Library is loaded, and then the Visit is created. No other Visit instances need to be loaded since we know the new instance is unique, and there’s no need to version the Library.

For the Many-to-Many example, we create a Role and grant it to 20 Users:

Role role = new Role(name: 'ROLE_USER').save()
20.times {
   def user = new User(username: "user$it").save()
   user.addToRoles(role)
   user.save(flush: true)
}

and clear the console and grant the Role to one more User:

def role = Role.list()[0]
def user = new User(username: "new person").save()
user.addToRoles(role)
user.save(flush: true)

and you’ll see SQL similar to

select this_.id as id0_0_, this_.version as version0_0_, this_.name as name0_0_
from role this_;

insert into user (id, version, username) 
values (null, ?, ?);

call identity();

select users0_.role_id as role1_0_, users0_.user_id as user2_0_ 
from user_roles users0_
where users0_.role_id=?;

update role
set version=?, name=?
where id=?  and version=?;

update user 
set version=?, username=? 
where id=? and version=?;

insert into user_roles (user_id, role_id) 
values (?, ?);

So we can see that it first loads the Role, then creates the User, then loads all of the previous Users that have that Role (proxies in this case, but still a lot of instances for no good reason), then it bumps the version for both the Role and the User, and finally adds a row to the join table.

Doing the same work with the updated versions:

Role role = new Role(name: 'ROLE_USER').save()
20.times {
	def user = new User(username: "user$it").save()
	UserRole.create(user, role, true)
}

and

def role = Role.list()[0]
def user = new User(username: "new user").save()
UserRole.create(user, role, true)

we get more reasonable SQL:

select this_.id as id4_0_, this_.version as version4_0_, this_.name as name4_0_ 
from role this_;

insert into user(id, version, username)
values (null, ?, ?);

call identity();

select userrole_.user_id, userrole_.role_id
from user_role userrole_
where userrole_.user_id=? and userrole_.role_id=?;

insert into user_role(user_id, role_id) 
values (?, ?);

where we can see that it loads the Role, creates the User, does a lightweight unique check in the join table, and then inserts the join table row.


Download the presentation here and the sample projects at here and here.


A Grails UI Performance Plugin

Tuesday, August 26th, 2008

I wrote up some notes in my previous post about some recent work I’ve done implementing the Yahoo Performance Team’s 14 rules for UI Performance. We’d talked at work about making it a plugin, but I wasn’t sure if it was sufficiently different from the excellent Jawr plugin to justify it. So I took a look and I think that my approach has some benefits that do justify a second plugin.


One significant feature that I’m providing is versioning and far-future Expires headers and caching for images in addition to JavaScript and CSS. Of course images aren’t very compressible, so gzipping them doesn’t make much sense, but the image payload of most sites is going to be a lot larger than that of the .js and .css files, so it makes sense to try to get clients to cache those also.

Another is a taglib that helps keep javascript at the end of the page. Sitemesh gets in the way here – there can be a lot of code in your layout GSPs after the layoutBody call, so DependantJavascriptTagLib allows you to define one or more hidden JavaScript declarations in your GSPs and render them all from the layout at the end of the body (Sitemesh has “content” tags that support this but there’s a bug where script tags lose their opening bracket so I’m using a technique borrowed from here).

Finally there’s simplicity – this was designed as a Grails plugin, so it has a more focused feature set and has fewer moving parts, preferring convention over configuration.

Having said that, there are advantages and disadvantages of both approaches:

Reasons to use Jawr versus using this plugin:

  • a lot more features, e.g. I18n, DWR, and JSF support, choice of minification approach, etc.
  • more configurable, e.g. exclusion lists – I gzip/minify/version everything
  • it’s not Grails-specific, so the time you spend learning its features will be useful when you want to use it in non-Grails apps

Reasons to use this plugin versus using Jawr:

  • the bulk of the work is done during the build, so no temp files, everything is in the war and problems are caught during the build instead of after deployment
  • it versions and sets Expire on images, and rewrites inner urls in css files to point to versioned images
  • supports Sprites via a taglib
  • helps move JavaScript to the end of the body via a taglib
  • doesn’t use a servlet – only a few taglibs and a Filter, letting the container continue to serve static resources
  • less processing at the server – it only needs to check if client supports gzip when rendering <javascript>, <css>, and <img> tags in GSPs
  • more Grails-friendly – in development mode it does nothing, and is only enabled in production mode, so there’s no need to check for modifications since Grails doesn’t support that in production mode

So as you’ll see from the code, there’s not much to it:

  • the plugin script wires up a simple Filter that adds caching headers in production mode
  • an Events.groovy script hooks into the war building process and gzips/versions/minifies static resources before the war file is packaged
  • and five taglibs handle the work of inserting the correct version and paths for resources, choosing to render the path to the gzipped files if the client supports it

Downloading:

You can download an early version of the plugin here, and a sample app demonstrating its use here. I’m waiting on some feedback before I put it up at plugins.grails.org since it’s still got some rough edges. Note that they’re configured as Eclipse projects but I’ve removed the Grails classpath jar entries and replaced them with a User Library called ‘grails’ to simplify the classpath. Either create a similar User Library (just include everything in GRAILS_HOME/dist and GRAILS_HOME/lib) or just re-add those jars explicitly like you’d have in a regular app.

Testing it out:

First run “grails run-app” from the performance-test project. It’s a basic app with one domain class, but the point is to show that in development mode it functions just like an app without the plugin – it serves the files from the file system unchanged and with no extra headers.

But if you run “grails war” and deploy the war in a servlet container (I’ve only tested Tomcat 6.0.16) then you should be able to view the source and see that the .js and .css files, plus all images have versions embedded in the urls and the .js and .css are gzipped and minified, and that the appropriate caching headers are set. The source files are unchanged – you still get to develop with readable files, but when deployed in prod mode, the app is a lot more efficient.

Note that there are very few image files since most are rendered using sprite1.gif via CSS. Also check out http://localhost:8080/performance-test/sprite/index (and views/sprite/index.gsp) for an example of an inline image from a sprite, plus an example of deferred JavaScript.

To install the plugin in one of your apps run

grails install-plugin http://burtbeckwith.com/blog/files/68/grails-ui-performance-0.1.zip

Let me know about issues you find or questions you have.

High Performance Grails

Saturday, August 23rd, 2008

I’ve been looking at performance issues for the site we’re building at work. The database is obviously going to be the biggest bottleneck, so we’ve configured 2nd-level caching for read-only tables and some read-mostly tables. We’ve also configured query caching for obvious candidates.

Currently the big hitter is the search page, and some profiling showed that we just needed a few extra indexes and some extra 2nd-level caching, but otherwise it performs pretty well. I still need to test it on production hardware with a large database – the stuff I’ve done so far is on my own high-end developer box with the database, server, and clients all running on the same box.

So I’m now working on applying the 14 rules from Steve Souders and the Yahoo performance team. YSlow has been very useful to measure improvement after each change, and of course Firebug is indispensable.

This is a Grails app, and Grails makes several parts of the process a lot easier, but of course all of these approaches apply to non-Grails apps too.


We’d already put the CSS at the top of the pages and the JavaScript at the bottom, so the next thing I looked at was GZipping content. I configured Tomcat to gzip HTML and text types by adding “compression=’on’ compressableMimeType=’text/html,text/xml,text/plain'” to the HTTP <Connector> element in conf/server.xml. This will change to Apache’s mod_deflate if we end up fronting the Tomcat instances with Apache.

I’m not having Tomcat compress CSS and JavaScript since these are static and I don’t want to keep re-compressing these files for each client, trading I/O cost for CPU cost. So instead I’m compressing once during the build.

This step is currently a little clumsy. Eventually we’ll hook into the war building process using GANT events, but currently I’m unpacking the war after it’s built, compressing each file (leaving the original for the rare client that doesn’t support gzip) and re-packing the war. While I’m doing this, I also use the YUI Compressor to minify all CSS and JavaScript files. This has the benefit of allowing us to develop with readable files but send optimized files to the client.

We also want to configure caching by using far-future Expires header. The best approach for this is to add an Expires header for the year 2038, 10 years from now, etc. and embed a version number in the url but serve the current file. For example instead of:

<script src='/js/foo/bar.js'></script>

we want:

<script src='/js/foo/bar_v2364.js'></script>

The client will get the latest contents of bar.js and the Expires header will tell the browser to cache forever. The version helps us when we deploy a new build and want to ensure that clients re-request the file to get the new latest version. After deploying the new version we’d want to render the new version:

<script src='/js/foo/bar_v2789.js'></script>

We’ll still send them the contents of bar.js but it’ll be newer and since the name is different, the old version will be ignored (and removed from the client’s cache once it’s full) and they’ll use the latest code.

So how to get the version in the urls? Grails has a <g:javascript> taglib but in the past I’d written custom tags to reduce a lot of the boilerplate for <script> tags, CSS <link> tags, and <img> tags and I’ve ported these to this app. Since all JavaScript, CSS , and image files are in the /js/, /css/, and /images/ directories respectively, and we know the extension for JavaScript and CSS files, the custom tags allow us to specify the minimum information, e.g.

<ns:javascript src='bar'/>

generates

<script type='text/javascript' src='/context/js/bar.js></script>


<ns:css name='styles'/>

generates

<link rel='stylesheet' type='text/css' href='/context/css/styles.css' />

and

<ns:image src='spacer.png'/>

generates

<img src='/context/images/spacer.png' border='0' />

where ‘context’ is the context the app is deployed under (blank for the root context), and ‘ns’ is whatever namespace the tag is registered under. Each tag allows extra attributes and these are just passed through to the HTML (e.g. to specify the id, style, etc.)

Since we’re rendering the urls to most static resources using these three tags, we can do a lot of extra work. During the build, I look up the latest SVN version of the root directory and use that to version the resources. I gzip each JavaScript and CSS file and embed the version in the gzipped and non-gzipped file names, and also rename images.

I write out the version into a properties file for use by the custom tags at runtime so they can append the version into the rendered <script>, <link>, and <img> tag urls so they match up with the names in the war.

Embedded image urls in CSS files are a problem using this versioning scheme, but since I’m processing each file during the build, I take that opportunity to rewrite the urls inside all CSS files with the version embedded, so they also agree with the names in the war, e.g.

background-image: url(/images/cluetip/wait.gif);

becomes

background-image: url(/images/cluetip/wait_v2364.gif);


The final optimization I’m working on is reducing the number of files. We have many small JavaScript files being sent to each client and have partitioned our CSS files but typically send the same few files in most pages. So another step in the build process involves bundling JavaScript and CSS files into larger single files. These are minified and gzipped like the rest, and the net effect is fewer requests with a smaller total size.

And I’m also putting together sprites where practical (stretched single-pixel background images and animated images aren’t candidates) to reduce the number of image requests. csssprites.com makes bundling together individual images easy and generates a table showing the position offsets for each image.

Using these techniques I’m seeing YSlow scores of 93-99 on all of our pages when deployed in production mode in Tomcat. We’re planning on using a CDN eventually, but for now I’ve cheated and added ‘localhost’ and ‘maps.google.com’ to the YSlow ‘extensions.firebug.yslow.cdnHostnames’ property since the YSlow score is significantly affected when not using a CDN that it knows about.

Of course developing locally we don’t use war files, so all of this must be disabled unless we’re in production mode. Grails makes this easy (using application.isWarDeployed() and GrailsUtil.environment), so the custom tags skip the step of appending the version in urls, and we’re able to serve uncompressed, unminified files from the file system with no Expires headers.

Creative Commons License
This work is licensed under a Creative Commons Attribution 3.0 License.