I’ve decided to keep the default title the WordPress gives to the post it autocreates on new installations. I think it’s fitting; what better way to signify the conversion from BlogEngine.net to WordPress?
But first things first.
I’ve decided to keep the default title the WordPress gives to the post it autocreates on new installations. I think it’s fitting; what better way to signify the conversion from BlogEngine.net to WordPress?
But first things first.
Generally speaking, I don’t like wasting time hunting down framework bugs. It’s not that I don’t like a challenge, it’s just that they are usually hard and very time consuming to fix (if at all possible), especially in case you have to deal with fringe cases (in other words, “Google isn’t going to help”).
Since we have lots of clients that are not limited to english-speaking markets only, Unicode has been a way of life for us, supporting it since we got off Windows 9x and moved on to Windows 2000. It’s always frustrating to see technology that doesn’t play nice with Unicode, especially considering that this is 2011, where everything is social and interconnected and having multilingual thingies is beyond cool; it’s a necessity.
I’ve stated before that despite its flaws, WordPress is an amazing product with a strong community and a plethora of available content that allows you to meet customer demands quickly and effectively (gone are the days of overpriced custom CMS solutions, especially since the global banks’ crisis began). Till now, the only real WordPress related problem we faced had to do with unicode permalinks, which to put simply…. just wouldn’t work with IIS: If your permalink contained unicode characters, WordPress would complain that it couldn’t find your post. There was no plugin that could solve the issue and as such, we usually resorted to ugly hacks in order to tackle it.
Recently, I was forced to look into PHP caching, thanks to a series of events. Here’s what happened:
Once upon a fine day, the (windows) server demanded that I will install some windows updates it found and I proceeded in complying with my master’s wishes (dare say no, and it will kill your customers’ sites. It already send me their fingers once). After the restart though, I noticed that all of our PHP sites were timing out. It didn’t take long to find out that the one to blame was MySQL which due to the massive amount of files in the temporary folder, apparently needed a very long time to create its temp files. In the end, I found out the cause and boy, was it ugly or what?
It seemed PHP was creating session files on the Windows’ temporary folder but wouldn’t delete them after the session had expired. As a result, the amount of files in the folder reached the 1.000.000 (!), all of which were 0 or 32KB long, but nevertheless enough to make anything that tried to access the folder crawl like it never crawled before (such as MySQL).
[more]
This ugly event mustn’t have to happen again and I need to ensure that. So, I took a deep breath and began digging into php.ini. It seemed that the following piece of advice was giving me a hint:
| ; If you are using the subdirectory option for storing session files ; (see session.save_path above), then garbage collection does *not* ; happen automatically. You will need to do your own garbage ; collection through a shell script, cron entry, or some other method. |
Still, that wouldn’t explain why such an option was set, since I neved touched the session section of the php.ini, ever. I refuse to believe that by default php is designed to kill its hosting server (I may be wrong though, feel free to correct me). I took a quick look into the caching option I actually used, which was provided by the session.save_handler setting, which was set to files. Searching around for different options I could try, I found out about WinCache.
WinCache, or Windows Cache Extension for PHP is PHP accelerator in the form of a PHP extension which is designed to work in Windows, but strangely enough, not limited to IIS (although being developed by Microsoft). WinCache though is not just an opcode cache but also offers some other nifty features, such as file caching, user data storage (more on that later) and session storage. Also, tests conducted by other people seem to indicate that it does a pretty great job, even when compared to other solutions. Plus, it won’t mind if you’re having 1 or 16 PHP FastCGI processes, since the cache it creates is centralised, thus avoiding data duplication!
Now go to RuslanY’s (WinCache’s creator) blog and thank him for his great work!
I have to admit though that initially, I was sceptical about WinCache. I had tried WinCache as a beta and it had some serious bugs which made some of our PHP sites to unexpectedly crash and as such, I had removed it completely. Not so with version 1.2.614, a development release that gave me no problem. After verifying that all of our PHP sites would work without issue when this extension was enabled, I was curious to find out more about its session handling option. So, I changed PHP’s temporary folder to one that would be untainted by other processes, changed the session.save_handler option to wincache and went on an angry rampage using openload, which hammered my servers with requests, the best part of which was that it would create a plethora of new sesions. Let me tell you, I was relieved to see that WinCache only creates a single file for handling PHP’s sessions.
So, I had certainly solved that annoying problem, but now WinCache had proven to be interesting and had to find out more about it. After all, I was sold on this nice live stats page that showed the status of WinCache. The best part was already set and forget. Opcode caching and File caching were applied automatically to all of our PHP applications and required no tweaking from my part. The same goes for session caching (although in this picture the hit/miss ratio is low due to using openload which creates lots of new sessions). What peaked my interest was the User Cache session which initially was 0. I found out eventually that user cache is nothing more than an object storage provided by WinCache and which is accessible using the WinCache provided functions.
“Big deal” I thought. “We’re talking about PHP on Windows, who would bother to lock-in its application to Windows and WinCache?”. Although the question is valid, the answer was far simpler: “Caching plugins!” Indeed, applications that up until now used the disk to act as a cache, could benefit greatly from WinCache if they used it instead for that same purpose. First case in point? WordPress, a platform which is favoured by many of our clients.
Let’s take a specific example, extrahype.com. Extrahype is a heavily modified site based on WordPress for all things geek, be it movies, games, pop culture and more and we’re lucky enough to be hosting it. Using my crude benchmark tool, openload, like a an angry caveman wielding an obsidian knife, I went and performed a simple benchmark of its start page, without using WinCache or any form of caching within the site itself. The results on the 2xDual Opteron 2212 were a bit disappointing, even though this was PHP on IIS on a not that fast server processor. I only got about 14 requests/second, which is low. In contrast, our in-house developed site rekonit.com an online review aggregator for stuff that matter (such as cars, movies and games, you know, the geek stuff you see on extrahype.com) which uses ASP.net 4.0 & MSSQL server and self designed caching algorithms gets about 350 rps. Note, we are currently redeveloping rekonit.com in ASP.net MVC 3 & MSSQL, so get ready to be amazed within the summer (yes, it will also look cooler).
I then proceeded and enabled WinCache in the php.ini. The results were very positive. With WinCache enabled, the average requests/second extrahype.com could handle rose to 31 rps, a difference of more than 2 times! That was good, but still not good enough.
Here’s where WinCache’s user cache came into play in the form of WordPress plugin, WinCache object cache. After I installed this, I could see the user cache section in the WinCache statistics page populated with data. Did it make any difference? Well, a minimal one. The average rps climbed from 31 to 34 rps.
The differences were reasonable and it’s obvious here that the bottleneck appears to be the database server. Still, it provided my PHP websites with a nice performance boost that only costs a little RAM (thankfully, that’s in abudance).
I then proceeded on testing it with PHPBB 3. Using the same method of “before and after WinCache” I would end up with 18 and 30 rps respectively. PHPBB 3 uses a file caching mechanism as its default. I found an experimental WinCache implementation which, usurprisingly, uses WinCache’s user cache. The difference was still minimal, this time from 30 to 33 fps, but still a no brainer compared to other forms of caching. Note that the problem here were the serialized database accesses, since the PHP FastCGI processes were are at a cosy 10% of CPU usage while MySQL was struggling around 25-30% (a whole core in a quad core system, plus a little more).
As a comparison, a PHPBB 3 installation on my development machine (an Intel Q9550 quad core) achieves about 59 rps without WinCache and 82 rps with it enabled, with the same database bottleneck issues.
In the end, WinCache (as other PHP accelerators do) offers an almost free performance upgrade to your PHP applications. Its extra features such as file, user and session caching & handling are indispensible even if you don’t have that much RAM to spare. It’s highly recommended and if you run PHP on Windows you should definitely check it out!
Comments? Criticism? Testimonies? Feel free to comment below!
PS. Before closing this article, I’d like to present you with two additional plugins for WordPress that managed to blow my mind with their results:
I’ve also tested W3 total cache for WordPress, a highly sophisticated caching system which is designed to take advantage of any caching option you can think of, such as opcode and file caching, page minifying even CDNs and some additional features that didn’t have the change to use (yet). The improvement is simply spectacular, since with it enabled plus setting it to take advantage of winCache’s features (and WinCache obviously active) the requests/second I achieved for extrahype.com exceeded the 300 rps mark! This result is achieved mostly by creating static versions of components whenever it can.
If your site however does not need a complex caching mechanism nor is very complex in nature (extrahype.com for example is not as complex as it might seem) you can opt for another caching plugin, simply named Quick Cache. Quick Cache is essentially a very simple caching plugin that creates static versions of your site’s pages. It doesn’t have the sophistication level W3TC has and only few differentiation methods of the page are recognised, but if your site’s user base consists mostly of unregistered visitors or you want to deal with a sudden Reddit/Digg/SU/Slashdot attack, it will do a magnificent job. How magnificent? Well, with Quick Cache enabled in extrahype and WinCache enabled in the server, I managed to get 610 rps! This amazing number is due to the web server only serving static content, with minimal PHP processing.
Since most of our WordPress clients don’t really need (yet) the sophisticated features of W3TC and they mostly have unregistered users, we’ve decided to enable Quick Cache and migrate to W3TC when required. No matter what you select though, make sure the plugins have the required permissions on the cache folders they create, or you may end up with a bazillion of cache files!
I’ve started messing around with custom websites based on WordPress lately, since it offers a very flexible platform with lots of functionality while still allowing you to customize the final result to your heart’s content. Really, the only real issues with this approach is that 1) we are talking about PHP which happens to not be my platform of choice (but I can swallow my pride and develop on it anyway) and 2) WordPress’s performance issues that can be easily solved with a caching plugin.
So, I’ve created a nice custom layout from scratch. Tested it on all major browsers on which it worked perfectly (except from IE 6 and 7, but I can ignore these at this stage). Then I went on to implement specific functionality from WordPress on the layout. The drill is quite simple. You seperate the HTML into template files. In this case I had created 3 of them, header.php with the doctype, head tag and header declaration, footer.php with the site’s footer and all closing tags, and index.php with the main content of the page. You render the header by using WordPress’s get_header() method and get_footer() for the footer.
After a while, I’d noticed that viewing the page on Firefox there was some kind of a blank white space border in the uppermost side of the page, which had no reason to be there. I excluded the beta nature of the browser as a probable cause, since the standalone layout worked perfectly. Then, I attempted to view the result on IE and… there are no words to describe the colossal mess the browser rendered. Oh yes, the white border was there too.
As if that weren’t enough, double clicking on that white space on Firefox and then viewing the “selection source” would produce a quite different html source, specifically moving all declarations that belong to a <head> tag into the <body> tag. Chaos, chaos I tells ya!
Then, I moved the contents of header.php back to index.php and removed the call to the get_header() method. Whadayaknow, it worked perfectly again. Feeling adventurous, I added the call to the get_header() method again in the index.php file but with the header file empty. Oh boy, chaos once again.
I was stumped. There was no logical explanation for that (as far as I could see), since the source produced was the same in each case. But when I checked the file sizes and found them different, I suddenly knew… It was the 3 characters known as Byte Order Mark, and should be the first thing that should appear on a Unicode document, be it a text file, a code file or a Word document. It’s a sort of metadata, only that it’s contained within the document contents themselves. It’s quite useful actually since not only it informs you about the endianness of the document’s encoding but of the unicode encoding variant used. Most applications that are Unicode aware usually remove those characters when they present or process such data, but there are few that do not and… well… the least painful result is the literal appearance of these characters on the document itself. In other cases, such as in PHP this means misrendered documents due to them app.
The easiest solution is to save the files without a BOM, especially the one containing the DOCTYPE declaration! There’s also supposed to be a zend configuration option (enable-zend-multibyte) that checks for the existence of the BOM, but from what I can gather it’s quite buggy. Also, the folks at PHP expect such issues to go away with PHP 6.0 (and here’s another reason why I like developing on the .net platform so much: I don’t have to deal with such trivial issues).
In any case, that’s 2 hours of my life wasted on one of the most idiotic issues I’ve ever encountered…