Copyright © 2010 Release The Codes!. All Rights Reserved. Snowblind by Themes by bavotasan.com. Powered by WordPress.
PHP
The PHP programming Language
For this quick article I am only going to quickly cover the A and the M of the LAMP stack.
The Setup
Assumptions: You have root on the server in question or you at least have enough server access to effect the configuration of Apache and MySQL.
The test server setup:
- A Virtual Private server running on Rackspace cloud
- Ubuntu 9.04 (Jaunty Jackalope)
Few quick commands and viola, you have a LAMP server…
$ sudo apt-get update
$ sudo apt-get upgrade
$ sudo locale-gen en_US.UTF-8
$ sudo apt-get install apache2-mpm-prefork php5 php5-dev mysql-server-5.0 mysql-client-5.0 php5-mysql
$ sudo a2enmod rewrite
- Installed latest Wordpress and added some test posts
Baseline Performance:
Before you start changing anything be sure to record the baseline performance ot the server. Place the server under load. I used http_load but anything similar can be used
The Test URL’s that http_load will draw from
$ cat pdxphp-test
http://67.23.47.195/
http://67.23.47.195/2010/02/test-post-1/
http://67.23.47.195/2010/02/test-post-2/
http://67.23.47.195/2010/02/test-post-3/
http://67.23.47.195/2010/02/test-post-4/
http://67.23.47.195/2010/02/test-post-5/
Run the test
$ http_load -parallel 5 -seconds 20 pdxphp-test
83 fetches, 5 max parallel, 1.74373e+06 bytes, in 20.0009 seconds
21008.8 mean bytes/connection
4.14982 fetches/sec, 87182.7 bytes/sec
msecs/connect: 80.6013 mean, 99.26 max, 71.974 min
msecs/first-response: 795.394 mean, 5495.6 max, 225.29 min
HTTP response codes:
code 200 — 82
To see how much RAM MySQL actually wants, we restart it with Apache stopped
Apache
Reduce the number of modules loaded
You can start with this. It will typically not give you incredible results but you will save some resource and it is a good security policy.
You can list your loaded modules with
apache2ctl -t -D DUMP_MODULES
Loaded Modules:
core_module (static)
log_config_module (static)
logio_module (static)
mpm_prefork_module (static)
http_module (static)
so_module (static)
alias_module (shared)
auth_basic_module (shared)
authn_file_module (shared)
authz_default_module (shared)
authz_groupfile_module (shared)
authz_host_module (shared)
authz_user_module (shared)
autoindex_module (shared)
cgi_module (shared)
deflate_module (shared)
dir_module (shared)
env_module (shared)
mime_module (shared)
negotiation_module (shared)
php5_module (shared)
rewrite_module (shared)
setenvif_module (shared)
status_module (shared)
Choosing to unload any of these modules is completely dependent of how you are using the server. But for many PHP developers can safely unload cgi.
$ sudo a2dismod cgi
Module cgi disabled.
Run ‘/etc/init.d/apache2 restart’ to activate new configuration!
sam@pdx-test:/etc/apache2/mods-enabled$ sudo apache2ctl start
Turn off htaccess
Explanation from Apache. So all you need to do is take the contents of the .htaccess file in your site’s webroot and place that in the corresponding vhost. Then turn off htaccess files with AllowOverride None and rm the .htaccess file in the web root after restarting apache.
sudo vi /etc/apache/sites-enabled/wordpress
<Directory /var/www/wordpress>
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php
</IfModule>
AllowOverride None
</Directory>
rm /var/www/wordpress/.htaccess
Now, how to really affect apache
This is all well and good and Apache will be better off for it but if you had a server that was paging and dying under load, after making these changes, that will probably not change.
The bigger issue shown in the top output above is that, for the amount of physical RAM, there are just too many 20+MB processes
the apache conf file controls these settings (/etc/apache2/apache2.conf on Ubuntu)
The stock settings:
<IfModule mpm_prefork_module>
StartServers 5
MinSpareServers 5
MaxSpareServers 10
MaxClients 150
MaxRequestsPerChild 0
</IfModule>
Possible more appropriate settings for a little personal blog site. Overall you need to lower MaxClients to the amount you can run without paging. If this is too few, you probably need more RAM.
<IfModule mpm_prefork_module>
StartServers 1
MinSpareServers 1
MaxSpareServers 5
MaxClients 5
MaxRequestsPerChild 1000
</IfModule>
The Results thus far
MySQL
Now onto MySQL. We saw above that MySQL is staring up and grabbing ~21M of RAM. A low to medium volume LAMP server probably doesn’t need all that but, again every situation is different. Here though are some notes of how to tune the Low Hanging Fruit of MySQL
If you don’t use it, Turn it off
Same as with Apache modules, turn off what you do not need. Storage engines are a great place to start. Very few frameworks (including WP), utilize InnoDB by default. Most use good old MyISAM.
Stopping MySQl from loading the InnoDb engine (and its predecessor:bdb) is quite simple, the lines are in my.cnf, just uncomment them
skip-innodb
skip-bdb
Now there are many, many MySQL config options that affect the amount of resource it uses. I’ll just cover a couple here, the key buffer and the query cache
The stock settings for these are
# used for holding built indexes
key_buffer = 16M
# largest query that is cache-able
query_cache_limit = 1M
# used for caching queries
query_cache_size = 16M
For many types of sites, these can be a bit large, for small sites, some suggested settings might be:
# used for holding built indexes
key_buffer = 4M
# largest query that is cache-able
query_cache_limit = 500K
# used for caching queries
query_cache_size = 8M
To see what the runtime values are concerning the query cache and key buffer use (once server has been under load)
mysql> SHOW STATUS WHERE Variable_name LIKE ‘Key_blocks_%’ OR Variable_name LIKE ‘Qcache_%’;
+————————-+———-+
| Variable_name | Value |
+————————-+———-+
| Key_blocks_not_flushed | 0 |
| Key_blocks_unused | 13369 |
| Key_blocks_used | 27 |
| Qcache_free_blocks | 4 |
| Qcache_free_memory | 16326632 |
| Qcache_hits | 5969 |
| Qcache_inserts | 95 |
| Qcache_lowmem_prunes | 0 |
| Qcache_not_cached | 410 |
| Qcache_queries_in_cache | 46 |
| Qcache_total_blocks | 106 |
+————————-+———-+
11 rows in set (0.00 sec)
As you reduce key_buffer and query_cache_size, check the output of the SHOW STATUS command shown above while the server is under load to verify that you are not running low on Key_blocks_unused or Qcache_free_memory
The Final result of our tinkering
So now that we have trimmed Apache and MySQL lets see what the top output looks like with the server under load
Our CPU load has reduced (idle is up to ~65%). More importantly we are no longer paging and we still have a bit of RAM left over. MySQL is running with ~8M of RAM, down from ~21M.
Also as seen below, we’ve roughly doubled our performance. Up to 6.85 req/sec and first response in down to 276ms.
$ http_load-parallel 5 -seconds 20 pdxphp-test
137 fetches, 5 max parallel, 4.69493e+06 bytes, in 20 seconds
34269.6 mean bytes/connection
6.85 fetches/sec, 234747 bytes/sec
msecs/connect: 80.6284 mean, 96.353 max, 73.043 min
msecs/first-response: 276.766 mean, 447.707 max, 225.995 min
HTTP response codes:
code 200 — 137
Links:
I’m teaching a PHP/MySQL course at the local community college this fall. First order of business is to get everyone set up with a PHP development environment. I decided to go ahead and post the strategy for the course as a post here in case it may be helpful others just starting out in PHP development.
This post is meant to help the individual who is just setting out to learn PHP web development and has no previous programming experience. I’m listing a set of tools to help in that quest and giving some pointers as to how to initially configure them (though part of the reason these tools were chosen was that they require very little tweaking before you can start using them).
The OS used in this example is Windows, but all theses tools are cross platform (deliberately chosen for that reason), and the instructions will only change slightly for other OS’s.
Below are examples of installing a client (the web browser), a server stack (PHP and MySQL) and a code editor. They’ve been chosen based on:
- ease of install and use for someone new to all this technology
- cross platform
versions available for Windows and Linux flavors including OS X - extensibility
In particular, Firefox and Netbeans. As the user grows comfortable with these tools, they will discover that they contain many features to aid in web development. (firefox: firebug, web-dev toolbar netbeans: integrated source control, xdebug, etc)
PHP is a cross platform technology at heart so that enables a plethora of alternatives to the choices I’ve made above. So feel free to explore the other options and find the tools that work best for you.
Firefox
Install
Get the files from: http://www.mozilla.com/en-US/firefox/firefox.html
Install the firebug addon : http://getfirebug.com/
XAMPP
Install on Windows (windows 7 64bit edition shown)
Get the files from: http://sourceforge.net/projects/xampp/files
XAMPP should do this by default, but be sure to install at C:\
In service section check
- Install apache as service
- Install mysql as service
This causes those services to automatically start when Windows starts
Test install by opening a browser and going to http://localhost
Netbeans Editor
Netbeans PHP IDE
Download here
Configure after Install
Apply Updates
Test
Now create a new PHP application project called {YOUR NAME}-week1
Place the project in the XAMPP htdocs folder
Confirm the URL your project will be found at. (In our case, Netbeans should make the right guess here, so just confirm and click ‘Finish’
Editor Will Open and Netbeans will automatically create a starter index.php file for you
Clean up some unneeded windows
close these windows (you can always get them back later if you like)
- navigator
- files
- services
- palette
Now to make a few edits and create a new file so we can start to get familiar with the IDE.
Add some PHP
See the file in a browser by clicking the green Play (>) button on the toolbar. The Browser should open at the URL for the file.
create another file called new-file.php
- Menu: File > New File
- Choose category PHP, File Type PHP Web Page
- Next
- Change the filename to new-file.php
- Finnish
In new-file.php create a hyper link to index.php and in index.php create a link to new-file.php
The resulting filesystem
Note, the nbproject folder is used by Netbeans (it is full of projects metadata). You can simply ignore it (but don’t edit or delete it)
Continue Reading »
Inspired by Toby Segaran’s creation of a heat map of restaurant health inspection scores for San Francisco, I set out to do the same for Portland, Oregon. I was able to scrape establishment records from the existing Multnomah County Food Establishment Inspections Search. Then I got lat/longs for those addresses using Google’s geocode API. Using the gathered establishment records I was able to scrape the MCHD search site once more for the Inspection records of those businesses. Lastly, I displayed the data on a Google map graded green for good score down through to red for the not so good scores.
See the map here. (It’s plotting ~3000 markers so it can take a bit of time to load).
After looking at the map I realized, just as Toby did, other than displaying ‘concerning’ red areas, this map exposes restaurant ‘clusters’ that you may not have known about and can then choose to explore.
Below is some more detail on the techniques I used to build this particular map.
Get the data
I searched around the web and found the Multnomah County Food Establishment Inspections Search. I made an attempt to get an export of the back-end data for this by calling county health. They were helpful but when I received the export of the data it was just the business records, not the inspection records for the businesses. I think they may have just misunderstood me and I probably could have pressed more and gotten data I needed, but I thought it would be fun the polish the old web scraping skills instead. Also, a scraping strategy would allow me to refresh the data whenever needed and I wouldn’t have to keep bugging MCHD.
Selenium is a suite of web app testing tools. Selenium IDE is a firefox addon that records all the actions you take in the browser. Meant for building functional testing scripts but doubles as a great web scrape script building tool. What I find most useful about Selenium IDE is that after recording your script you can export it to the xUnit version of your choice, PHPUnit in my case. This gives you the starting point for your script and you can then add things like database persistence for the information you are scraping and utilize the phpUnit assertion methods to let you know if your script has broken. Then, you can use a tool called Selenium Remote Control to re-run the script (and drive the browser) anytime you need. This intro video does a great job of explaining some of Selenium’s features.
So I needed to accomplish 4 things.
(I included links to the scripts I used, these are by no means ‘production ready’ but some might find them useful as a starting point to their own projects. Also here is the DB sql used.)
Step I: Pull the establishment records from the MCHD site
I noticed that on the MCHD site, if you just clicked ’search’ without any criteria you were taken to a holistic, paginated set of the records (currently 130 pages for total of just over 3000 records). So my first script was started with selenium IDE and worked through these 130 pages, gathering establishment meta-data and storing it in a mysql database. The Script
Step II: Pull the inspection scores for the gathered establishments from the MCHD site.
This was done by again, using Selenium IDE to start a PHPUnit script that scraped the inspection record for each gathered establishment. It simply queries all the establishment ids from out database and builds URLs to scrape the inspection data for each business and store that information in an inspections table in the database. The Script
Step III: Geocode the Establishment Records using Google
In preparation for displaying the data on a map, I needed to get the lat/long for each establishment in the database. I did this using Google’s Geocode service but there are many options for services that can accomplish this. Just be sure you stay within their Terms Of Use. The Script
Step IV: Display the Establishments on something akin to a heat-map
This is the easy part once you’ve done the heavy lifting in steps I,II and III. It involves one query from the Db to pull the score, latitude, and longitude for each establishment we know about. Then using a fairly simple php web page we build the HTML and javascript to display this data on a Google map. The Script
This talk was centered around adding channels of communication such as SMS and XMPP to existing HTTP web services.A project called Extapi, is a small web app that manages this coordination between multiple channels and services.here are the slides for my presentation given on November 14th 2008 at PHP|Works
Continue Reading »In Atlanta for the php|works conference.Listening to the Keynote from Kevin Dangoor (founder of turbo gears). He’s discussing successfully fostering open source projects.Looking forward to meeting new folks with PHP and/or Python backgrounds
Continue Reading »Very excited that the talk I submitted to php|works was accepted. I’ll be speaking at the Atlanta conference on my continuing work with combining XMPP and SMS with existing web API’s
Continue Reading »
One of my side projects has turned into a full blown startup. Shizzow.com will be officially announced at today’s Lunch 2.0 at cube space. It’s been a pleasure working with the other fine folks on this project and I’m looking forward to the future.Thanks to Silicon Florist for all the press
Continue Reading »
I discovered the Portland Trimet API about a month ago and was very inspired by the amount of real-time information available and the ease of accessing it through their web service. One feature of the service is that for a given stop id you can get the arrival times for the buses/trains for that stop. These are not the scheduled times but rather the real-time estimated arrival time based on the known GPS coordinates of the actual vehicles on their routes.
You can get to this data through IVR system by dialing 503-238-RIDE or on the web.
In the mean time, I have also been working with extending existing APIs with additional access such as SMS and XMPP (jabber). So it was natural to take on this trimet service as my first proof of concept.
For SMS access, you simple text “pdxt {stop_id}” to the short code DOTORG (368674)
so for example, for the stop 8334 (Pioneer Square South MAX Station Eastbound), you would text…
“pdxt 8334″ to DOTORG (368674)
The result is shown below (with the same request through the web for comparison)
There is slight differences in the times since it is difficult to coordinate the SMS and web request precisely.
In my trials, response times for SMS were in the 5-10 second range which for me is acceptable.
I’ll next be working on an XMPP (Jabber) wrapper around the service so you will then be able to access the service with an IM client (which many phones now have). XMPP will give the same mobility benefits of SMS but removes the 155 char limit for the returned text allowing for more information to be included in the returned message.
Once I have completed SMS and XMPP around this service, I plan to refactor the technique so it can be easily applied to other services. I will also document the steps I took to integrate with SMS and XMPP. Look for that on google code soon.
Authors: Dagfinn Reiersol, Marcus Baker, Chris Shiflett2007 Manning Publications525 pages This book is geared toward the intermediate PHP developer who wants to bring in aspects of OOP, Testing and Refactoring to help improve the quality of the code they write. It is split into four parts; Basic Tools and Concepts, Testing and Refactoring, Building the Web Interface, and Databases and Infrastructure. In addition to PHP, I have decent amount of experience with Java and Java web frameworks such as Struts. So as I worked through this book much of the content was familiar to me but from a Java perspective. It was enlightening to see the authors express these same concepts from a PHP perspective. The fact that many times (not always), the implementation in PHP is more concise and elegant that the Java alternative really shows of the power of a dynamically typed language such as PHP. Also the fact that PHP was bred from the beginning to be a web development language gives it a definate advantage in the web arena.The authors are honest though, they haven’t simply painted implementing OO, TDD, and Refactoring as completelty painless. For instance in the testing portion they’ve devoted quite a bit of time to showing the difficulties of testing (especially in a Web environment). Such as the need for mock objects and the difficulty in keeping mocks “real enough” so they fail and pass as the real object would. This full disclosure is key for readers to estimate if the extra effort of a concept is worth the benefits for their particual situation. Overall this is great book for the intended audience. It is not “black and white” about the solutions it proposes. Reasonable alternatives are given and the pros and cons of each are expressed. For those with extensive OO experience, some portions of the book may seem trivial but overall it is still worth a “quick scan” to see the specifics of PHP implementations of general OO concepts.
Continue Reading »I’m starting to work with mozilla and XUL again. I’ll be posting that work soon, But in the meantime I found this presentation I did back in 2005. I remember that is when I first stumbled across this strange but useful XmlHTTPRequest object and wondered if it’s use would find its way to the mainstream. Took a traditional HTML admin interface for a PHP web application and transformed it into a Mozilla XUL interface. Goal is to demonstrate the benefits of using XUL to create Rich Client Application interfaces into your web apps when you have the ability to mandate the browser used (such as an admin interface). Links and resources:
- Working Demo (mozilla browsers only)
- Documentation and Source Code (didn’t go too crazy on the docs, but you can see all the source code by viewing the files section of the tree on the left).

Recent Comments