Globalization has made it impossible to ignore how your web application performs for an international audience. Tools like YSlow and PageSpeed will tell you why your pages are slow, but you don’t truly know the pain of your end user abroad until you’ve used the application first hand over a high latency low bandwidth network.
One easy way to try this sans the layovers and jet lag is to place a proxy server between your browser and web server that simulates stressed network conditions. DonsProxy is a great tool that does this and much more.
Download the GUI from the SourceForge page or checkout an example running from an ant build via my Reference Project Page at Google Code.
Here’s an excerpt from the ant build to start the proxy:
<target name="start-proxy" depends="build" description="Starts the proxy server that simulates a slow connection, then stop after 2 minutes"> <java fork="false" classname="com.moneybender.proxy.Proxy" failonerror="true" classpathref="master-classpath" maxmemory="1024m"> <jvmarg line="-Dlisten.port=9090" /> <jvmarg line="-Dtarget.host=localhost" /> <jvmarg line="-Dtarget.port=8080" /> <jvmarg line="-Dlatency.millis=300" /> <jvmarg line="-Dpacket.loss.rate=100" /> <jvmarg line="-Dbandwidth.throttle=40" /> </java> </target>
Setup is easy. Configure your web browser to direct traffic through the proxy like in the Firefox example below:
You can test against a locally running Tomcat instance for example by browsing to localhost:9090/yourapp. Using a tool like FireBug you can now investigate how parts of the page load under stressed network conditions and see how it actually feels.
Sites like Internet Traffic Report will give you a rough idea of settings to try for latency, packet loss, etc to simulate different conditions around the world. If you need something beyond localhost:8080, or want to try out public sites, follow the Apache setup instructions to route all browsed sites through the proxy.
To take this a step further, you can bring stressed network conditions into your test environment by placing the proxy between a client under test and the server. Here’s an example of starting and stopping the proxy programmatically in a unit test:
public class ProxyTest { private Proxy proxy; public ProxyTest() { System.setProperty(ByteReaderFactory.LATENCY_PROPERTY_NAME, "300"); System.setProperty(ByteReaderFactory.PACKET_LOSS_PROPERTY_NAME, "10"); System.setProperty(ByteReaderFactory.THROTTLE_PROPERTY_NAME, "40"); } @Before public void setUp() throws Exception { proxy = new Proxy(); ProxySettings proxySettings = new ProxySettings(); proxy.start(proxySettings); } @After public void tearDown() throws Exception { proxy.stop(); } @Test(timeout = 10000) public void testProxy() throws Exception { // TODO: setup a target server to proxy Socket s = new Socket(ProxySettings.DEFAULT_TARGET_HOST, ProxySettings.DEFAULT_LISTEN_PORT); Assert.assertTrue("couldn't connect", s.isConnected()); } }
Feel free to contact me for further questions about performance testing and optimizing your applications.