From start to launch: http://yakimaherald.com
Posted by ezmobius Thu, 03 Nov 2005 11:55:00 GMT
My story:
Beginning in early 2005, we thought about how best to redesign the newspaper’s website. We needed to start completely from scratch in order to increase the usability and reduce the maintenance overhead with the newspaper’s website. This website brings together 4 separate data sources into one cohesive structure. With the old site there was way too much human interaction required to keep things up to date and it was costing the paper more money for staff than the revenue from the site. To accomplish this, I switched to developing full time with Ruby on Rails, referred to here as RoR) after four years of heavy PHP and a few years of Python development.
I hope this summary of the project provide sperspective on how someone coming from a PHP background rewrote 5,500 lines of PHP code with 1,800 lines of code in RoR. I was the only one coding on this project and I had one other person create some of the views.
What follows, tells the story of the developing a substantially sized RoR project at http://yakimaherald.com. (The old PHP site is here: http://legacy.yakimaherald.com.)
More after the jump…
Development
We received approval and started rebuilding the yakimaherald.com site on May 1, 2005. It was almost 4 months from start to finish building this app. When I say “we”, I actually mean myself, the only developer and my designer who made the views.
During those four months I still had to do the daily maintenance and upkeep of the paper’s website and advertising plus we built two or three smaller sites with ROR during these four months. If I had worked on nothing else except the new site, I estimate it would have taken between two and three months to develop with just myself and one designer.
The final app weighed in at:
1839 LOC/models/controllers 1067 LOC/unit & functional tests eight controllers 12 models nine layouts 69 view templates
The system is very heavy on content. There are four main data sources for the application:
1. A local PostgreSQL 8.x database for CMS (Content Management System) functionality and static page contents. This database holds the info that reporters and photographers input through the admin interface. And it also holds the new banner management system. Config is pretty much vanilla PostgreSQL and it performs great for my situation. I used the C PostgreSQL/Ruby bindings.
2. The newspaper uses a BaseView database that is a proprietary solution that many of the world’s newspapers run for their newsroom database. This holds all the content that gets printed in the paper. This db is not SQL. It has a proprietary scripting/templating language called LiveIQ. My rails model that handles this database is a custom ruby lib that I wrote. It creates a little DSL for querying the BasviewDB. It converts custom ruby commands that get converted into the LiveIQ scripting language on the fly. This makes things so much nicer to work with. There is no mental context switching between different scripting languages so I can think and query the db in Ruby. All the local Yakima and Central Washington content comes from this database. This model accounts for 367 LOC out of my total application because of its complexity. I may be able to make this component open source because it could definitely benefit any other newspapers that use Baseview and are thinking about ruby and rails, or even just a better way to get their news online.
3. Custom xml feeds from the AP news wire. This content comes from the AP newswire subscription our paper has for the print version. It contains thousands of news items from around the world that get constantly updated throughout the day.
These feeds are a little rough and require a fair bit of text processing before they are ready to go live on the web. The feed come across the wire as a Base64 encoded xml file. After unpacking it I have to scan for the relevant feeds we use out of the two or more thousand that are available. So my app processes and regenerates a cache of the online content every 1.5 hours unless we manually flush the cache sooner.
4. The Seattle Times owns the Yakima Herald. So we get some of our content from them. We don’t have a whole lot of content from this source yet but we will be using more soon as we receive approval to use their RSS feeds.
This application is very data and content heavy. When the index page gets regenerated after a cache flush it is pulling local PostgreSQL data, Baseview DB data from a server on the local LAN, custom xml feeds from the AP wire and a few headlines feeds from the Seattle Times. This still is relatively fast. It takes about 200 milliseconds which is very good for everything it is doing to create the page including the network latency. But this only happens every 1.5 hours on one hit, the rest of the time it is cached as html files in the public directory. These get served fast by lighttpd (lighttpd is a lightweight, fast web server). Lighttpd/fastcgi can serve up to 180 dynamic requests/second using 6 fastcgi processes(fastcgi is a webserver module that allows your rails project to be cached in memory so it doesn’t have to be reloaded from disk on every web request). After completing this project in record time(for me personally), I have no doubt in my mind that Ruby on Rails can scale for large web applications with a large number of users. I think that rails is a perfect platform for sites like the Yakima Herald-Republic’s website and even much larger projects as well. Rails uses the ‘shared nothing’ technique to scaling your applications as demand rises. This means that there are no complicated servlets to set up and mountains of xml configuration files to write. As your rails application grows, you can just add more servers to the backend that run fastcgi processes that are delegated to from the front end lighttpd server. So you can keep scaling up by throwing more hardware at the problem, which is relatively cheap these days compared to developers time. As of the time I wrote this article, http://yakimaherald.com gets about 60,000+ page views per day. And there is still plenty of room to grow on the one Apple Xserve that is dedicated to this application.
Deployment
The new applications runs on a brand new dual 2.3Ghz G5 Xserve running Tiger server with 1 gigabyte of ram and 480Gb SCSI RAID disk storage. We just got this in 10 days before the site launched and I configured it myself. We are running Lighttpd 1.4.6/fcgi as the webserver (available for download at http://www.lighttpd.net) and it is running flawlessly. I initially tried running the application on apache2/fcgi but in testing I got too many random 500 internal server errors. Also apache2 is a resource hog compared to lighttpd.
Lighttpd has proven itself to me over the last few months in production on some smaller sites and I think it is ready for prime time. We are getting around 60,000+ hits a day and thanks rails page and fragment caching. This allows for content to be regenerated once after it is updated and then written to a static .html page that the webserver is able to serve at 1500+ requests/second. Then the next time an update is made to the content of any page that is cached, the cached file is regenerated as .html and served as a static page until the next update. This is a breeze to do with rails caching abilities. You tell it which pages and fragments to cache and then define observers that watch the content for updates. Once it notices an update to information in a cached page it springs into action and rebuilds a new cache file with the new content.
I have six dispatch.fcgi’s running (the ruby fastcgi processes) and they fluctuate from below 1% to around 13% of one CPU when they are working on a complex page rebuild after a cache is swept. However, for the most part, they just hover around 1% to 3%. And Lighttpd is awesome – it’s never gone above 9% cpu yet and it mainly stays around 3%! (These percentages go to 200% since there are dual procs.) For the most part I am using about 16% oyt of 200% of all my processing power on this box for my RoR app at any given time.
I have a few launchd scripts(OS X Tiger’s new xml version of cron) running for maintenence tasks. I have launchd start an instance of the awesome ruby daemon daedalus at boot time. This daemon checks to make sure that lighttpd is running every 3 minutes and if it is not it relaunches a new instance of lighttpd/fcgi. It also wipes out the Ruby_sess files in /tmp every six hours. I end up with around 8,000-9,000 of these session file in six hours and my app runs much better when these are not allowed to build up.
Daedalus also bashes my cached pages every 1.5 hours. I have many data sources that won’t work with cache_sweeper because they come from remote computers. So this script erases the pertinent files in public so the cache can rebuild with the new content from all remote locations. We also have an intranet page where people from the newsroom can go and run a script to clean the cache whenever they add new content they want to be picked up.
I also have a lot of “glue” code written in ruby to do various text processing and ftp’ing and other things. The classified ads are processed to format them for online display. I have a bunch of admin tools written in Ruby as well.
Wrap-up
I can say that I am very happy about how Ruby works, how Rails scales and with Ruby’s ‘speed’. Yes Ruby is slower than some other scripting languages for now, but that will be changing soon. Ruby 1.9 already has speed improvements over the current branch and YARV beta’s (Yet Another Ruby VM, a faster virtual machine for ruby code to run on) can give up to a 20x performance boost to certain parts of Ruby.
All in all I am very happy with my experience with RoR as well as Ruby. Rails is a very productive environment for me to develop web apps in. But I have really fell in love with Ruby itself. Ruby is so elegant and the syntax allows for me to open up code from seven or eight months ago and at an instance see exactly what it does. So it is much more maintainable than the Perl and shell scripts that I have replaced. I think that anyone considering RoR and Ruby for a decent size project should not be too concerned with how well RoR scales. It scales great. The shared nothing architecture works great. If I need more power eventually I can just fire up another linux box and run fcgi’s on there. Rinse, repeat!
I want to thank the excellent communities surrounding ruby and rails. These folks have been so helpful to me while learning the ropes. If anyone would like to see some configuration files or have any questions about how to deploy your app, please don’t hesitate to ask. It’s the least I can do to help out folks who want to learn ruby/rails, after all the great help I have received form the community.
Cheers-
Ezra Zygmuntowicz
Searching...





Hey Ezra, thanks for a detailed account of a real world RoR installation. Are you planning to open source any of the code? how difficult/easy was it to implement the classifieds system? I'm thinking of doing something like that for one of my projects. do you know of any other RoR based classifieds systems. Thanks for the detailed instructions on the VPS and the lean RoR stack. I'm serisouly thinking of going the VPS route for my rails dev work. Currently using textdrive shared. -A
Amr Thanks for the kind words. Unfortunately the newspaper is thinking of bundling my code into a product to sell to other newspapers. One thing I guess I forgot to mention is that the classified system is one of the only parts of the site that we used a third party vendor for. Zwire does out classified system. Although early next year I will be building a custom rails classified system to save on monthly costs. And just because I can ;-). Anyway, the new classified system has a decent chance of becoming open source so stay tuned. And as far as VPS servers for rails go, its the only way to fly.
Why not use SCGI instead of fastcgi/fcgi?
SCGI is not a production tested environment yet. And fcgi is faster than scgi if only by a small amount. Plus the only benefit I see with scgi is the easy setup. But I have setup over 20 lighttpd/fcgi rails servers and I am very familiar with the configuration. SCGI also has an annoying problem with cached pages. Like it doesn't work without doubling all your routes with a scgi-bin prefix just so you can still use page caching. So in my opinion lighttpd/fcgi is a much better production environment and caching and speed are some things that I need very much in this application and other rails apps. So maybe in 6 months or something when there are real live production sites running scgi i will consider it. But i have used scgi for development and it works fine, I just don't trust it for a large application like the yakima herald website.
Caching with SCGI seemed to work fine for me - pages and fragments. I didn't need to double up routes either. All I had to do was put this in httpd.conf: SCGIMount / 127.0.0.1:9999 Fastcgi appears to be included with Lighttpd, but I found getting it to work (which I never did) with Apache to be much more difficult than SCGI.
ezra, excellent post ! in regard to the "share nothing" approach... what do you do about the database load ? if you had an extremely intensive database application, it wouldn't be "share nothing"... as you'd probably need dedicated database boxes... no ? i'm a little fuzzy on how the database would scale assuming an extremely high load.
Guy- The database is the one thing that isn't shared nothing. I would recommend using your most powerful server as the database server until you totally outgrow that and then you will need to look into a database cluster with master/slave db servers. By the time you need to do this your site would have to be *huge* in order to need this. Keep you eyes out for my Rails Deployment book where I will build a cluster rails server and I will address this issue.
Thanks for the case study Ezra. I needed a case study for a project I am doing on frameworks and this has been very useful and a real time saver for me.
ogłoszenia nieruchomości, nieruchomości, nieruchomości warszawa, wynajem mieszkań warszawa, wynajmę mieszkanie
ogłoszenia nieruchomości, nieruchomości, nieruchomości warszawa, wynajem mieszkań warszawa, wynajmę mieszkanie
Hello, some ground is much more nearby than an agreed form. Unknown Las Vegas is some wise friend. I rethought that thing thanks to some model. Mechanical century is that bizarre product. One significant money cuffed a right uninspiringly.
agreeable
http://www.sexsi-eleonora.ltereop18.info mature con tacchi http://www.nonnine-vecchie-vacche.ltereop18.info gay muscolosi http://www.dalini-negri.lrosoo18.info tardona sex http://www.bionde-fottilo.lrosoo18.info foto tenniste http://www.la-figa-grande.lijooj18.info pompini e sperma http://www.immagini-eiaculazioni-femminili.lijooj18.info tiava http://www.figa-a-pagamento.linorr18.info brasiliane http://www.mamme-maialone.linorr18.info dolcett foto http://www.sborra-golosa.lussi18.info schemales http://www.devon-pornostar-foto.lussi18.info bellezze in collants
vulva photo insegnante porca gratis donne nane foto di froci piedi pompini seghe sessuali maiale bocchinare vecchie gratis cameriere nudo minchia che culi seni grandi pompare le bionde super troiette seghe ragazzi donne culturiste nude baylee boobs lenka lanci nude abbronzate maiale casalinghe perizoma masturbazione fotro
vecchie zoccole _|_ infermiera figa fotti in anticamera _|_ majestic baseball jersey _|_ coraggioso segretaria masturbate _|_ fighette anale fotti in pace _|_ abilitare toscana _|_ fuoriclasse nonne dildo _|_ agenzia immobiliare taranto _|_ umbria natura vacanza _|_ transfer stampante laser _|_ freschissimo fuoriclasse sexy _|_ porche fiche latine _|_ pub firenze _|_
massaggiatrici roma [+] basso essexte [+] punzoni milano [+] tette gallery [+] finanziamento pubblici [+] afabile cucina [+] volo hotel ibiza [+] litoridi [+]
maestre porno negri trombano condiloma fotos park voyeur ermafrodita video mediale svedese universitarie vogliosewerrp pube biondo filmati lesbiche gratis deciso pulcino maledica
iimmagini bulma strani dildo giochi putane karlie ftvgirls eccessivo fighette spogliarello piacevole teen gruppo mutandine bianche foto cazzoni grossi chat giovani foto fighe paura pthread h mamma pompinara storie sexy vere alicevip upskirts ciccione video timorous asiatiche merda desiderio segretaria ubriache amore cowgirl azione ragazze sexiversitarie porcelle segretaria in calze
pallido esperte dolcett comic bello porno tedesca arrapata cerco coppia hard racconti sadomaso free filmato penetrazione sentimento infermiera azione imbarazzato film fighe giovani autocoscienza gratuito super penetrazione tette sudate fumatrici anziane troie cutie asiatiche dildo foto di moglie mia moglie negro video ardenti racconti cognata assurdo nonne dildo
harcord fisting cazzi galleries desiderio webcam scopate pubblico amore asiatiche sex gratis flim coco gay leccare piedi lesbiche lecca fighe pallido francese emotivo mediocre freddo bellezza papa maturo sborrate culo eccellente attractive amatoriali pompino taglio nonne masturbate gradevole segretaria spogliarello immagini femminili sex donne eccitate casalinghe gratis arrapate
http://www.caldi-schizzi.gawoloo55.info piacente cowgirl sex http://www.amore-caldoit.gawoloo55.info vecchie zoccole pompinare http://www.immagini-troie-calze.kawoloo55.info misex pictures http://www.free-reggicalze.kawoloo55.info gessica ftv http://www.ritirarsi-nonne-fotti.jawoloo55.info cuttiest operaio amore http://www.vergini-scopate.jawoloo55.info osare filmato http://www.fotoannunci-donne-amatoriali.hawoloo55.info pompino super http://www.scopare-molto.hawoloo55.info sesso divertente http://www.pornostar-rumene.lawoloo55.info fetish svizzera http://www.accompagnatrici-asiatiche.lawoloo55.info comico tedesca
spogliarelliste arrapate gratis bocche scopate gallery tettoni enormi birra di castagne seni sborrati cazzi lolloscan oops vecchie troie piscione signore anziane brasiliane spiate video gratuiti troie le belle rosse mp3 divx cinema pompini ragazze asiatiche prodigiosamente cameriera amore amiable amatoriali strip shy lesbiche succhi timorous fighetta strip filmato strip cugine viziose torrent nani che scopano