In this second part of a two part series, you'll learn how to use debuggers and optimize performance. It is excerpted from chapter 12 of the book Zend PHP Certification, written by George Schlossnagle et al (Sams; ISBN: 0672327090).
Performance is a "happy problem" until the day it falls in your lap. Nothing can ruin your day like a pointy-haired manager screaming in your ears because the website is not responding well to an increase in traffic.
Although it won't have an immediate impact on your ability to go live, measuring the performance of a website is an important step that will come in handy on the day in which you will need to troubleshoot it.
Naturally, the easiest way to help a system that is ailing because of too much traffic is to throw more hardware at it. You could increase your onboard RAM or the speed of your hard disks, or you could even add another server altogether.
Another good idea is to ensure that your data is all stored in the right place. By saving the logs on a separate disk or partition than where your main application files are stored, you can help the operating system optimize its caching mechanisms and provide higher performance.
Although a well-configured computer is a great starting point as far as ensuring that your application is performing to the best of its capabilities, eventually you are going to find that an alternative solution is required since you obviously can't simply add new servers to your farm indefinitely.
Web Server Issues
Proper web server configuration goes a long way toward improving performance. A good starting point is to turn off reverse DNS resolution since you don't need it at the time when your web server is simply logging information about site access. You can always perform that operation offline when you analyze your logs.
It's also a good idea to familiarize yourself with how the web server you're using works. For example, Apache 1.3.x is a forking web server—meaning that it creates copies of its own process as children. Each child process waits for a connection (for example from a web browser) and, if there are more connections than available idle children, the server creates new ones as needed.
In its default configuration, Apache pre-forks 5 children and has a maximum of 150. If you consider that each child requires between 2 and 5 megabytes of memory to run (assuming your scripts don't require even more), this could easily lead to a performance bottleneck if the traffic on your server goes up. At maximum load, 150 child processes could require between 300MB and 750MB of RAM. And, if you run out of physical memory, the operating system will switch to its virtual memory, which is significantly slower.
This problem can also become self-compounding. As more and more child processes are created and the system is forced to rely increasingly on virtual memory, the average response time will increase. This, in turn, will cause even more child processes to be created to handle new connections, eventually exhausting all your system resources and causing connection failures.
As a result, a careful read of your web server's documentation is probably one of the cheapest (and smartest) investments that you can make. Do take the time to tune the appropriate configuration options for minimum and maximum clients and only compile or activate those web server modules you really need in order to save memory consumption.
If you're dealing with a mixture of static and dynamic content, it's a good idea to keep things simple and let a lightweight web server handle the static data. Because you don't need any of the advanced features provided by PHP and Apache, using a different server that requires fewer system resources to run will increase your performance. You can even move the static data to a different server altogether and neatly divide the work across multiple machines.
Zip It Up
HTML is a very verbose language. As a result, web pages are often rather large—although maybe not as large as, say, a video or audio stream. Still, even a 20KB page will take its sweet time across a slow dial-up connection.
PHP makes it possible to compress the output of a script so that it can travel faster to the user. This can be done in a number of ways—for example, you can enable the GZIP buffer handler in your php.ini file or turn it on directly from within your scripts:
Naturally, the output of your scripts will only be compressed if the browser that is requesting the document supports the GZIP compression standard.