I just completed some load tests with Glassfish v2ur2 on Linux, Clustered, a 4 way, Intel based machine and JDK 1.5 (JDK 1.6 would be better, but was not available in this case). I used a simple CRUD application as load generator, without think-time, and almost empty database, just to stress the appserver as much as possible.
The two load-generators ran remotely (via IIOP, standard EJB 3 client), each with 50 virtual users. Glassfish passed all tests without any problems, the response times and transaction / seconds were very stable. We just increased the number of connnections in the JDBC-pool, and set the -Xmx to 512m: no further tuning was performed.
The performance was impressive: 250 - 500 Transactions / second (we weren't alone on the machine :-(). We performed the tests with another, commercial, application server as well. The results were similar.
I actually performed similar, but not comparable, test several years
ago (around 2003) with EJB 2. / CMP 2.0. We had more load generators (250 - 300 virtual users) available and were able to execute
800 transactions / seconds.
Conclusion: The performance of even remote (IIOP!) EJB 3 rocks :-), and Glassfish performs well, even without any further tuning.
In real world, however, most of the performance gets lost in contention / locks and synchronization issues... But you should not blame your server / framework / platform for it :-).
NEW: Online Workhop Effective WebApps without Frameworks is also coming to: MUC Airport.