rails app fast on server, but slow when accessed from another machine - ruby-on-rails

I have a Rails app hosted on a server machine (running Webrick). When I log onto this machine and access the app (via localhost:3000), the app runs smoothly. But when I try to access the app from another machine (via hostname:3000), the app runs super slowly.
I'm not sure how to go about debugging the problem; is there any reason why this would be the case? I also have things like a SQL server database hosted on the same server machine, and accessing the database from other machines works fine.
Updating to add: the server machine, and the other machines I try to access it from, are all on a corporate intranet.

The following answer worked for me. Note that if you are running rvm the answer is at the bottom.
Webrick is very slow to respond. How to speed it up?
Look for the file /usr/lib/ruby/1.9.1/webrick/config.rb and edit it.
Replace the line
:DoNotReverseLookup => nil,
with
:DoNotReverseLookup => true,
rvm file is ~/.rvm/rubies/ruby-your-version/lib/ruby/your-version/webrick/config.rb

The most obvious answer would be that the problem is not with rails, but with your Domain Hosting(i.e. your DNS is super slow).
Try and load a different app(maybe a Sinatra "hello world") and see if it exhibits the same symptoms.
If yes - your domain provider is to blame.
If the problem persists, increase the verbosity of the logs and check if any SQL queries are an obvious bottleneck.
Also, the problem may be with Webrick. It just wasn't meant for production and may be slow if several people use the app at once. Try it with a different server. Apache is a reasonable choice: http://www.modrails.com/

I'm late to the party but you can use Thin instead of Webrick.
just add to Gemfile
gem 'thin'

Webrick isn't the fastest in the world, I'm fairly positive it's not meant for production but rather local testing. When you're connecting to the other machine is it on a local network or over the internet?

Take a look at the response times listed in your rails log file. If they are the same for local and remote access, then you know your problem is somewhere else in the stack (DNS, routing, software firewall, etc.)
It's highly likely that the problem is not rails itself.

Related

Ruby/RoR development: locally or server

Our company has started development of own systems "in-house". We already got couple of developers, who will be responsible for writing code in Ruby/RoR.
We are currently discussing about infrastructure and I would like to ask: should we develop everything on local machines, then put it to test server and later to production, or develop everything on development/test server, then publish it for testing and later to production?
Just an update to the description above: under "local machines" I meant developers' desktops and this test/development server is a machine in our office.
It's a valid question, and as such there's a trade-off to consider.
Generally; work locally. Web app development has a natural flow that leads developers to be saving and refreshing browsers many times an hour. All the time you save on network latency will actually add up, and be less frustrating for the developers.
There are downsides to working locally however, you'll need to make sure that your set-up is EXACTLY as it will be on the testing/production servers. That means everything down to your kernel version, apache version, ruby/rails version. DNS is easy, but again must mimic the live situation perfectly in order for AJAX calls etc to work seamlessly.
Even if you ensure all of the above, you will likely have to make a few minor changes when you move the app to a live server, there just always seems to be something in my experience.
Also, running on a live server isn't SO painful for a developer. Saving a source file from a text editor/IDE via FTP should take less than a second even over the internet, and refreshing a remote browser session will give your UI designers a better feel for the real user experience and flow. If you use SVN rather than FTP much the same applies.
Security isn't much of a concern, lock down FTP and SSH to the office IP, but have a backdoor available if a developer needs to edit a source from somewhere else, so they can temporarily open the firewall to their own IP.
I have developed PHP and Rails apps on a remote test server, on an in-office server and on a local machine. After many years doing each, I can say that as a developer, I don't mind any so much.
As a developer, my suggestion is that you need to 1st do all developing work on your local server. After testing, you need to send to client to make it live.
I'm working as a web developer on Ruby on Rails # andolasoft.com, we are following the same procedure. Hope you got the idea.
Thanks

Deploying rails: What to choose?

I have just finished a Rails-application that I now want to upload to the web. It is a re-write of an existing application and I expect some 4 000 visitors a day with peaks to 10 000 a day at times.
I know Windows fairly well (have not used Windows server though).
I hardly know anything about Ubuntu or Linux
I want things nice and easy and don't want to spend too much of my time "hacking the server". I want to spend my time developing, not maintaining.
My budget is ~50$ a month at most for this project.
The database for the project is quite static (hardly any user generated data)
I am currently using WAMP & Mysql with Rails 3.0.3 on my local installation and it works fine most of the time but crashes quite often as well.
I am considering three ways of doing that:
Using Heroku
Seems quite easy (even though I haven't gotten it to work yet)
Also seems expensive, if I need more nodes. How many nodes should I expect to need?
Using a VPS Windows server
I know Windows and it would be fairly easy to install and get it set up
My friend (who is more of a Rails expert) says that Windows and Rails is not a good match.
My crashes on my local environment makes me nervous about this option
Using a VPS Ubuntu server
Seems to be the cheapest option (in terms of paying up-front)
Seems to be the most stable option
I don't know Ubuntu and I am not too eager to learn a whole new OS to get this set up.
Could you help me with directions? Is Windows server really bad for Rails?
Quite honestly, I think Windows would be the worst choice for you. The problem with Windows and Rails is that most of the gems are never designed to work with Windows, or the versions that do work with Windows are far outdated.
Using an Ubuntu VPS is a very viable option, would be your cheapest and most stable option. We use Amazon S3 services to run most of our web servers in the cloud. Like you said, it does require you to know and understand a *nix operating system to maintain.
Maybe for you, Heroku may be the best option. Heroku is super simple to setup your project on and then deploy. There are also pages of documentation to help you along the way. In a few basic commands from the terminal, your application is running. I often use Heroku as a 'staging' server to test application updates among beta users before pushing to production on S3. You also are not required to learn a new operating system to use it.
If you are running into problems with deploying to Heroku, please post the issues and we will gladly help you.
I would advise against a windows server. From my experience, the major ruby implementations are not optimized for windows - and run slowly. For the sake of your end-users, a rails stack on Linux may provide significant performance gains (or equally decrease your server budget).
With bundler and rails 3, the amount of maintenance work on the server should be minimal. Log in, deploy, log out. (look into tools like capistrano to make this even more straightforward).
By far the easiest production I've found so far is an Ubuntu server.
On Windows Rails tends to be slower and it's far simpler to setup something like passenger on *nix. If help is needed, there are more tutorials available.
My fastest setups have been Ubuntu Server and nginx.
PS. Rails 3.0 has gone beyond 3.0.3 so think about testing the latest version 8)
Heroku is delightfully easy to deploy to. If your database load is light, you can just use their shared 20GB PostgreSQL database ($15/mo). 2 dynos will cost you ($35/mo) so there's your $50 there. 2 should be fine to handle that traffic, and you can always scale during your high traffic times. Definitely would recommend adding the memcached add-on and utilize that as well. Install the New Relic add-on and you can analyze your traffic/load and scale accordingly.
I'd heavily advise against using Windows for a rails app deployment. Some gems compile slower on Windows, and some don't work at all.
I've worked with Heroku, but there are some complications with writing files to the Heroku instance as Heroku does not allow for local file writing. When working with Heroku, people usually offload write operations like file-upload to an Amazon S3 instance or Fog. In general, Heroku is really easy to deploy to, but when configuration comes along...it may be a bit more complicated than a VPS.
The best solution for me would be to go via VPS using Ubuntu. There's been a lot of documentation done on this, and you have more options with your configurations. In actuality, it's not so much different from setting up Ruby on Rails on a local Ubuntu development machine. If you need tips on how to deploy on Ubuntu, I've just recently written a guide on how to do so.
http://www.francisbautista.com/deploying-ruby-on-rails-apps-on-a-vps-nginx-passenger-capistrano/

ROR very slow in development while production works fine

I have one rubyonrails app that turned really slow in development mode. Everything is fine in production, but even a simple "hello world" takes seconds in dev. I checked the session store and every possible reason i found on the net, but I didn't find the problem. Am I missing something that is common knowledge? "Completed in 1657ms (View: 226, DB: 39)"
Development is definitely slower, because it reloads all components. Production mode only loads the components when the server is started.
If you find your app is still too slow in Production mode then you can start hunting down bottlenecks. You can start by optimizing DB queries, with :include and indicies. You can also try removing your gems and plugins systematically to find the parts that are slowing down your code.
This is usually the case if you are running webrick, its so slow it makes eyes bleed.
Try installing mongrel in dev
gem install mongrel
Create a new app, see if that's slow too - that'll point to your server stack (apache, mongrel, passenger, etc.) rather than your application. If it's just your application then google rails profiling - and pick one of the many options for profiling an application.
WEBrick is doing a reverse DNS lookup on connecting IPs by default. In other words, it's trying to see if your IP address is associated with a domain name. This is unnecessary and takes too long, so you can disable it.
Open the file "l/ruby/lib/ruby/1.9.1/webrick/config.rb" and locate the line with ":DoNotReverseLookup => nil".
Change nil to true.
Enjoy!

Mongrel hangs after several hours

I'm running into a problem in a Rails application.
After some hours, the application seems to start hanging, and I wasn't able to find where the problem was. There was nothing relevant in the log files, but when I tried to get the url from a browser nothing happened (like mongrel accept the request but wasn't able to respond).
What do you think I can test to understand where the problem is?
I might get voted down for dodging the question, but I recently moved from nginx + mongrel to mod_rails and have been really impressed. Moving to a much simpler setup will undoubtedly save me headaches in the future.
It was a really easy transition, I'd highly recommend it.
Are you sure the problem is caused by Mongrel? Have you tried running your application under WEBrick?
There are a few things you can check, but since you say there's nothing in the logs to indicate error, it sounds like you might be running into a bug when using the log rotation feature of the Logger class. It causes mongrel to lock up. Instead of relying on Logger to rotate your logs, consider using logrotate or some other external log rotation service.
Does this happen at a set number of hours/days every time? How much RAM do you have?
I had this same problem. The couple options I had narrowed it down to were MySQL adapter related. I was running on Red Hat Enterprise Linux 4 (or 5) and the app would hang after a given amount of idle time.
One suggested solution was to compile native MySQL bindings, I had been using the pure Ruby one.
The other was to set the timeout on the MySQL adapter higher than what the connection would idle out on. (I don't have the specific configuration recorded, but as I recall it was in environment.rb and it was some class variable in the mysql adapter.)
I don't recall if either of those solutions fixed it, we moved to Ubuntu shortly after that and hadn't had a problem since.
Check the Mongrel FAQ:
http://mongrel.rubyforge.org/wiki/FAQ
From my experience, mongrel hangs when:
the log file got too big (hundreds of megabytes in size). you have to setup log rotation.
the MySQL driver times out
you have to change the timeout settings of your MySQL driver by adding this to your environment.rb:
ActiveRecord::Base.verification_timeout = 14400
(this is further explained in the deployment section of the FAQ)
Unfortunately, Rails (and thereby Mongrel) using up too much memory over time and crashing is a known problem (50K+ Google entries for "Ruby, rails, crashing, memory"). The current ruby interpreter has the property that it sometimes simply fails entirely to give memory back to the system - it may reuse the memory it has but it won't give it up.
There are numerous schemes for monitoring, killing and restarting Mongrel instances in a production environment - for example: (choosing at random) rails monitor . Until the problem is fixed more decisively, one of these may be your best bet.
We have experienced this same issue. First off, install the mongrel_proctitle gem
http://github.com/rtomayko/mongrel_proctitle/tree/master
This gem/plugin will allow you to view the mongrel processes via "ps" and you can see if a Mongrel is hung. An issue we have seen with Mongrel is that it will happily accept connections and enqueue them, then wedge itself. This plugin will help you see when a Mongrel has been wedged but then you must use another monitoring app to actually restart a a wedged Mongrel, something like Monit or God
You might also want to consider putting a more balanced reverse proxy in front of your Mongrels, something HAproxy, instead of nginx, Apache or Lighttpd. With a setting of "maxconn 1" in HAproxy you can assure that the queue is being maintained by HAproxy versus Mongrel. The other reverse proxies (nginx, Apache, Lighttpd) only do round-robin which means that they can load up your Mongrel queue, inadvertently.
My personal choice is God as it is much more flexible.
tl;dr Install this gem plugin and keep an eye on your Mongrels. Try Apache+Phusion Passenger.

How can I find out why my app is slow?

I have a simple Rails app deployed on a 500 MB Slicehost VPN. I'm the only one who uses the app. When I run it on my laptop, it's fast enough. But the deployed version is insanely slow. It take 6 to 10 seconds to load the login screen.
I would like to find out why it's so slow. Is it my code? (Don't think so because it's much faster locally, but maybe.) Is it Slicehost's server being overloaded? Is it the Internet?
Can someone suggest a technique or set of steps I can take to help narrow down the cause of this problem?
Update:
Sorry forgot to mention. I'm running it under CentOS 5 using Phusion Passenger (AKA mod_rails or mod_rack).
If it is just slow on the first time you load it is probably because of passenger killing the process due to inactivity. I don't remember all the details but I do recall reading people who used cron jobs to keep at least one process alive to avoid this lag that can occur with passenger needed to reload the environment.
Edit: more details here
Specifically - pool idle time defaults to 2 minutes which means after two minutes of idling passenger would have to reload the environment to serve the next request.
First, find out if there's a particularly slow response from the server. Use Firefox and the Firebug plugin to see how long each component (including JavaScript and graphics) takes to download. Assuming the main page itself is what is taking all the time, you can start profiling the application. You'll need to find a good profiler, and as I don't actually work in Ruby on Rails, I can't suggest any: google "profile ruby on rails" for some options.
As YenTheFirst points out, the server software and config you're using may contribute to a slowdown, but A) slicehost doesn't choose that, you do, as Slicehost just provides very raw server "slices" that you can treat as dedicated machines. B) you're unlikely to see a script that runs instantly suddenly take 6 seconds just because it's running as CGI. Something else must be going on. Check how much RAM you're using: have you gone into swap? Is the login slow only the first time it's hit indicating some startup issue, or is it always that slow? Is static content served slow? That'd tend to mean some network issue (either on the Slicehost side, or your local network) is slowing things down, assuming you're not in swap.
When you say "fast enough" you're being vague: does the laptop version take 1 second to the Slicehost 6? That wouldn't be entirely surprising, if the laptop is decent: after all, the reason slices are cheap is because they're a fraction of a full server. You're using probably 1/32 of an 8 core machine at Slicehost, as opposed to both cores of a modern laptop. The Slicehost cores are quick, but your laptop could be a screamer compared to 1/4 of core. :)
Try to pint point where the slowness lies
1/ application is slow, or infrastructure (network + web server)
put a static file on your web server, and access it through your browser
2/ If it is fast, it is probable a problem with application + server configuration.
database access is slow
try a page with a simpel loop: is it slow?
3/ If it slow, it is probably your infrastructure. You can check:
bad network connection: do a packet capture (with Wireshark for example) and look for retransmissions, duplicate packets, etc.
DNS resolution is slow?
server is misconfigured?
etc.
What is Slicehost using to serve it?
Fast options are things like: Mongrel, or apache's mod_rails (also called passenger phusion or
something like that)
These are dedicated servers (or plugins to servers) which run an instance of your rails app.
If your host isn't using that, then it's probably defaulting to CGI. Rails comes with a simple CGI script that will serve the page, but it reloads the app for every page.
(edit: I suspect that this is the most likely case, that your app is running off of the CGI in /webapp_directory/public/dispatch.cgi, which would explain the slowness. This tends to be a default deployment on many hosts, since it doesn't require extra configuration on their part, but it doesn't give good performance)
If your host supports "Fast CGI", rails supports that too. Fast CGI will open a CGI session, and keep it open for multiple pages, so you get much better performance, but it's not nearly as good as Mongrel or mod_rails.
Secondly, is it in 'production' or 'development' mode? The easy way to tell is to go to a page in your app that gives an error. If it shows you a stack trace, it's in development mode, which is slower than production mode. Mongrel and mod_rails have startup options to determine whether to run the app in production or development mode.
Finally, if your database is slow for whatever reason, that will be a big bottleneck as well. If you do have a good deployment (Mongrel/mod_rails/etc.) in production mode, try looking into that.
Do you have a lot of data in your DB? I would double check that you have indexed all the appropriate columns- because this can make a huge difference. On your local dev system, you probably have a lot more memory than on your 500 mb slice, which would result in the DB running a lot slower if you have big, un indexed tables. You can also run the slow queries logger in MySql to pinpoint columns without indexes.
Other than that, yes- passenger will need to spool up a process for you if you have not been using the site recently. If this is the case, you should see a significant speed increase on second, and especially third and later page loads.
You might want to run a local virtual machine with 500 MB. Are you doing a lot of client-server interaction? Delays over the WAN are significant
You might want to check out RPM (there's a free "lite" version too) and/or New Relic's Tune Up.
Your CPU time is guaranteed by Slicehost using the Xen virtualization system, so it's not that. Don't have the other answers for you, sorry! Might try 'top' on a console while you're trying to access the page.
If you are using FireFox and doing localhost testing (or maybe even on LAN) you may want to try editing the network.dns.disableIPv6 setting.
Type about:config in the address bar and filter for network.dns.disableIPv6 and double-click to set to true.
This bug has been reported mainly from Vista OS's, but some others as well.
You could try running 'top' when you SSH in to see which process is heavy. If you also have problems logging you, perhaps you may try getting Statistics in the Slicehost manager.
If you discover it is MySQL's fault, consider decreasing the number of servers it can spawn.
512 seems decent for Rails application, you might have to check if you misconfigured too.

Resources