it took a while since A symfony success story – Part I for me to write this second part.
Mainly because I had too much to do in the meantime (finishing the SCD and working on SCBCD) but also Carsten and me finished fixing up the main issues with the star of this second success story: Tempus vivit!
We jumped on the symfony train over a year back and I can say that I never regret this. We both worked during the last year sometimes more, sometimes less on relaunching the site, but I would estimate that in total 3 months of working time went into it. We got a little help from two designers, but they were so overworked, that also main design concepts came from us. So please forgive the somehow old fashioned look and feel. If you look into the web archive, on how the page has been looking before (which I do not dare to hotlink) you will see that it much improved, because the layout before was 10 years old.
One of the major challenges we had during design, testing, and after launch patching, was the large amount of users who have not a clue about PCs and Browsers, resulting in some users complaining in that the page doesn’t look good anymore on Netscape 4.7 in Win 98. But also the variety of IE 6 Browsers out there is interesting, there were users which had problems with IE6 that others didn’t. Interestingly we could convince some to upgrade to IE 7 or FF.
So thats on the Javascript side… keeping in mind that we only did a slight amount of javascript, which always degrades safely. Also with 800×600 screen resolutions the page now works… compatible…
The page is one of the early adopters to communities. I do not know if you would have called them that 10 years ago when the site was launched. So we kept the old concepts and removed more limitations, allowing users to publish more own content, then to send them for approval first. Which interestingly already worked in the first month and some areas of the site started living again.
Helped by adding some web 2.0 community features like a 5-star-rating widget, which we got basically for free through the sfPropelActAsRatableBehaviorPlugin, and introducing a iGoogle/netvibes like portal which users can customize, and offering RSS feeds for most areas, the site became a more interactive place to explore.
On the technical side, we started using Propel 1.2 coming from symfony 1.0 but we switched to Propel 1.3 during development, which helped with performance a lot. We do not have a separated backend for our moderators there, but they use the same UI as normal users, which resulted in a more specialized user management. We found sfGuard for this slightly to complicated to use and rolled our own, which was not that complicated.
At time of writing we have 33 modules working on 37 database tables containing approx. 1 GB of user data. Search functionality is implemented by Lucene (as readers of my blog should know
), not using the sfLucenePlugin, due to the fact that we started earlier with that. Carl is not going very much into our direction, so I never switched to the plugin, but I try to help him to stabilize it.
With regard to performance, we had huge problems initially. But we got rid of them by doing few things
- Switch to a new server. The old one had a slow disk (the main bottleneck). The new one has two, one hosting the DB the other hosting the webserver.
- Installing APC. Just by enabling APC we got 10 times faster responses
- Tuning Apache2. Key was to enable a MPM. We use prefork there and also enabled gzipping. See some guides like this or this.
- Tune MySql / InnoDB. There are mostly cosmetical changes, but setting some caches helps the DB to speed up and seperating log and data to two disks gives an extra boost. Most information is taken from MySQL Performance Blog.
- Watch the slow queries log file. We found a lot statements which we thought are good but when we used the EXPLAIn feature of Mysql we found out how to optimize them.
- Use symfony caching. Find the static partials and extract them, then cache them. Find rarely changing partials and extract them. For some it is not very complicated to write the remove from cache methods when the data changes.
- Use Yahoo YSlow. We found some issues with correctly caching our javascripts and images and could resolve them.
- If you haven’t done yet. Use Propel 1.3 instead of Propel 1.2
After all we are quite happy with the performance, and strive to improve it still a bit more (some browsers are refusing to cache the javascript.. don’t know why,perhaps the user switched to not cache? I recall that was 10 years ago a recommendation for problems).
We are still working on the site to resolve last issuesand implement new features. If you find something, feel free to mail or comment.
The nice thing with symfony is that the code is still clean and slim, refactoring is easy, and addition of a 5 minute wish is just a 5 minute work. The documentation is really good and never leaves you alone. It also helps you with tuning. The routing feature is just awesome and works very neat, making our old URLs backwards compatible was very easy. The debug toolbar is one of symfony’s greatest assets. It helps you so much in the development, and luckily just recently there is a way to include Propel 1.3 into it again.
Even if you find something that you do not like in symfony, or propel, it is very easy to replace the functionality, overwrite it or just disable the behaviour. Many frameworks claim that they are absolutly configuration free. And then the config comes back programtically, or using annotations or whatever. Symfony uses these nice YAML files, which are using sensible defaults, so most of the time you must use the routing file and no others. I never found it overly complicated to configure the application. Instead i prefer to set the html title attribute once in a config file and overwrite it in a second config file rather than to put that to the action controller. But of course thats a matter of preference.
Thank you symfony team for enabling us to be productive and do a smooth relaunch of Tempus vivit!