We chose two different kinds of server hardware to benchmark running the server software. Here are descriptions of the two types of computers on which we ran the benchmarks:
Desktop: Dual Intel Xeon 64 2.8Ghz CPU, 4G RAM, SATA 160G HD 7200RPM This was a tower machine with two Intel 64-bit CPUs; each CPU was single core and hyperthreaded.
Laptop: AMD Turion64 ML-40 2.2Ghz CPU, 2G RAM, IDE 80G HD 5400RPM This was a laptop that has a single 64-bit AMD processor (single core).
Because one of the machines is a desktop machine and the other is a laptop, the results of this benchmark also show the difference in static file serving capability between a single processor laptop and a dual processor desktop. We are not attempting to match up the two different CPU models in terms of processing power similarity, but instead we benchmarked a typical dual CPU desktop machine versus a typical single processor laptop, both new (retail-wise) around the time of the benchmark. Also, both machines have simpleext3hard disk partitions on the hard disks, so no LVM or RAID configurations were used on either machine for these benchmarks.
Both of these machines are x86_64 architecture machines, but their CPUs were designed and manufactured by different companies. Also, both of these machines came equipped with gigabit Ethernet, and we benchmarked them from another fast machine that was also equipped with gigabit Ethernet, over a network switch that supported gigabit Ethernet.
We chose to use the ApacheBench (ab) benchmark client. We wanted to make sure that the client supported HTTP 1.1 keep-alive connections because that’s what we wanted to benchmark and that the client was fast enough to give us the most accurate results. Yes, we are aware of Scott Oaks’s blog article about ab (read it at http://weblogs.java.net/blog/sdo/archive/2007/03/ ab_considered_h.html). While we agree with Mr. Oaks on his analysis of how ab works, we carefully monitored the benchmark client’s CPU utilization and ensured that ab never saturated the CPU it was using during the benchmarks we ran. We also turned up ab’s concurrency so that more than one HTTP request could be active at a time. The fact that a single ab process can use exactly one CPU is okay because the operating system performs context switching on the CPU faster than the network can send and receive request and response packets. Per CPU, everything is actually a single stream of CPU instructions on the hardware anyway, as it turns out. With the hardware we used for our benchmarks, the web server machine did not have enough CPU cores to saturate ab’s CPU, so we really did benchmark the performance of the web server itself.
We’re testing Tomcat version 6.0.1 (this was the latest release available when we began benchmarking—we expect newer versions to be faster, but you never know until you benchmark it) running on Sun Java 1.6.0 GA release for x86_64, Apache version 2.2.3, mod_jkfrom Tomcat Connectors version 1.2.20, and the APR connector (libtcnative) version 1.1.6. At the time of the benchmark, these were the newest versions available—sorry we cannot benchmark newer versions for this book, but the great thing about well-detailed benchmarks is that they give you enough information to reproduce the test yourself. The operating system on both machines was Fedora Core 6 Linux x86_64 with updates applied via yum. The kernel version was 18.104.22.168.
Here is our Tomcat configuration for the tests: Stock conf/web.xml. Stockconf/server.xml, except that the access logger was not enabled (no logging per request), and these connector configs, which were enabled one at a time for the different tests:
The APR code was enabled by using the HTTP APR connector configuration shown, plus setting and exportingLD_LIBRARY_PATHto a directory containing libtcnative in the Tomcat JVM process’s environment, and then restarting Tomcat.