about summary refs log tree commit homepage
path: root/site/src/faq.page
diff options
context:
space:
mode:
Diffstat (limited to 'site/src/faq.page')
-rw-r--r--site/src/faq.page415
1 files changed, 415 insertions, 0 deletions
diff --git a/site/src/faq.page b/site/src/faq.page
new file mode 100644
index 0000000..b98d2e0
--- /dev/null
+++ b/site/src/faq.page
@@ -0,0 +1,415 @@
+---
+title: FAQ
+inMenu: true
+directoryName: FAQ
+ordering: 5
+---
+
+h1. FAQ
+
+h2. Design
+
+h3. Q: How is Mongrel designed?
+
+The design of Mongrel most closely matches "Simple":http://simpleweb.sourceforge.net/
+which is a very nicely designed web server framework for Java.  Despite being written
+in Java, Simple is very clean and simple, thus the name (clever eh?).  The main difference
+between Mongrel and Simple is that Simple monitors returned output from handlers so that
+it can modify the results.  Mongrel instead uses Ruby's blocks to get the same effect.
+
+As for the internals of Mongrel there are a few key technologies being used:
+
+* A custom HTTP 1.1 parser written based on the "RFC":http://www.w3.org/Protocols/rfc2616/rfc2616.html
+  standard and using "an ABNF dump":http://www.cs.columbia.edu/sip/syntax/rfc2068.html thankfully
+  put online by someone.  The parser is written using "Ragel":http://www.elude.ca/ragel/ and
+  is written C as a Ruby extension.
+* A URIClassifier that uses a "Ternary Search Trie":http://www.octavian.org/cs/software.html
+  written by Peter A. Friend and modified to quickly look up handlers for a URI based on
+  a prefix.  This makes finding any handler from any URI quick and painless and is much
+  faster than the alternative of parsing the path and using nested Hash structures.
+* A simple server that uses the parser and URIClassifier to process requests, find the
+  right handlers, and then pass the results on to the handler for processing.
+* Handlers are responsible for using HttpRequest and HttpResponse objects to do their
+  thing and then return results.
+
+Other than this there's not much more to it.
+
+h3. Q: Is it multi-threaded or can it handle concurrent requests?
+
+Mongrel uses one thread per request, but it will start closing connections
+when it gets "overloaded".  While Mongrel is processing HTTP requests and
+sending responses it uses Ruby's threading system (which is more like
+Java's original green threads and uses select).
+
+Camping and Og+Nitro are supposed to be thread safe and work with Mongrel directly.
+This hasn't been heavily tested so people should let me know if they get weird
+explosions under heavy load.
+
+Ruby on Rails is not thread safe so there is a synchronized block around the calls
+to Dispatcher.dispatch.  This means that everything is threaded right before and
+right after Rails runs.  While Rails is running there is only one controller
+in operation at a time.  This is why people typically have to run a small
+set of Mongrel processes (a "Pack of Mongrels") to get good concurrency.
+
+If you have long running actions then you'll most likely have performance
+problems.  You should look at "BackgrounDRB":http://backgroundrb.rubyforge.org/
+as a very nice way to offload work to another process so that your Rails
+app can keep working.
+
+h3. Q: But no, I mean how is it *exactly* locked? Because it's really really important that I know everything.
+
+First off, you should drink less coffee.  Knowing exactly how Rails is locked
+will not help you plan your deployment for the best performance, only testing
+your deployment's speed will help.  You should read "Tuning":/docs/how_many_mongrels.html
+to get a good quick idea on how to figure out what your optimal Mongrel number
+is, and then you should check out "BackgrounDRb":http://backgroundrb.rubyforge.org/
+for a good way to move long running tasks outside of Rails for better response.
+
+h3. Q: But, but, but, I really really need to know!  It's killing me I *have* to know!
+
+Fine! It goes like this:
+
+# A request hits mongrel.
+# Mongrel makes a thread and parses the HTTP request headers.
+# If the body is small, then it puts the body into a StringIO.
+# If the body is large then it streams the body to a temp file.
+# When the request is "cooked" it call the RailsHandler.
+# The RailsHandler sees if the file is possibly page cached, if so then it sends the cached page.
+# Now you're *finally* ready to process the Rails request.  *LOCK!*
+# Still *locked*, Mongrel calls the Rails Dispatcher to handle the request, passing in the headers, and StringIO or Tempfile for body.
+# When Rails is done, *UNLOCK!*.  Rails has (hopefully) put all of its output into a StringIO.
+# Mongrel then takes this StringIO output, any output headers, and streams them back to the client super fast.
+
+There's also a bit of processing with chains of Handlers, but that's a minor point.
+For the most part, your goal as a Rails programmer is to make all of your Rails
+actions as fast as possible, and to not do anything that takes a long time.
+
+
+h3. Q: Can I run mongrel without rails?
+
+Yes, Mongrel is designed to host any framework, and already hosts Camping or Nitro
+as well.  If you're feeling adventurous, check out the "RDoc":/rdoc/index.html
+for the latest API documentation.
+
+h2. Security
+
+h3. Q: Is Mongrel secure?
+
+Anyone who claims their server is "SECURE" is full of crap.  You can't be
+absolutely certain that any system is secure, but what you can do is put
+policies and practices in place to try and make them more secure.
+
+As you can read in the "Iron Mongrel":/security.html documentation, I
+have a policy of:
+
+* Extensive testing with multiple techniques, and even wrote my own HTTP fuzzing tool "RFuzz":http://rfuzz.rubyforge.org/
+* Full disclosure on any security issues found.
+* Security auditing of all code before it's released.
+* Design decisions such as using a parser generator and fixed limits on all HTTP.
+* Simply trying to remove all defects and being proactive about it.
+
+Understand that I'm just one person with a few other people's help, so there's
+bound to be mistakes.  You use this technology (and *any* technology) at your
+own risk.
+
+Then again, if someone is telling you their system is secure, but can't tell
+you why it's secure, then maybe you should take a look at what I do to keep
+Mongrel's defects low and ask if they do any of this.  You might be surprised
+at their response.
+
+h3. Q: What's this about .svn directories?
+
+Yeah, Capistrano doesn't use svn export to create the deployment directory so
+there's a bunch of extra information in the .svn files.  Without special config
+changes to your web server you'll be letting people access these.  Best solution
+is to use svn export rather than checkout to get your code.  If you're already
+screwed then just do:
+
+ find . -name ".svn" -exec rm -rf {} \;
+
+And that'll delete them all in a very final way.
+
+You should also read "the official page on that":http://subversion.tigris.org/faq.html#website-auto-update
+to make sure there's nothing more you need to do.
+
+Finally, you can configure capistrano to do export instead of checkout
+following "their instructions":http://manuals.rubyonrails.com/read/chapter/102
+instead of the ruthless delete I have above.
+
+h3. Q: Does Mongrel have SSL?
+
+No, having a Ruby web server do complex SSL cryptography is stupid when you can
+get any of the major web servers to do it faster.
+
+h3. Q: Why are Apache & SSL - Redirects going to http:// not https://?
+
+Basically, you need to pass in a header so Rails knows what to do.  Read
+the bottom of the "Apache Documentation":/docs/apache.html for instructions
+on how to do this.
+
+
+h2. Installation
+
+h3. Q: I can't get Mongrel installed on Debian.
+
+You should read the "Debian":/docs/debian-sarge.html documentation.
+
+h3. Q: I can't get Mongrel installed on Fedora.
+
+Not sure when Fedora decided to start chopping up its packages like Debian,
+but you should basically just install Ruby from source, then install Mongrel.
+
+
+h2. Deployment
+
+h3. Q: What can cause Mongrel to lock up on a regular basis?
+
+There are several reasons Mongrel can stop functioning properly, but
+most of them are related to using resources that aren't shared properly
+between multiple processes.  The following is just a short list of the
+possible things you could be doing to cause Mongrel processes to lock:
+
+# Configuring Logger to rotate log files.  Logger doesn't do this reliably
+between processes, so use an external log rotation like logrotate.
+# Using PStore to store your sessions.  This isn't faster than the database
+and has frequent locking and coordination issues.
+# Sharing a file or similar service without proper locking.  SQLite and BerkleyDB are
+both culprits here.
+# Not setting the MySQL timeout properly (see later in the FAQ).
+# Using up too much CPU or memory on Linux will cause the oomkiller to
+kill your Mongrel process.
+
+If you have frequent stopping and stability issues, then install "monit":http://www.tildeslash.com/monit/
+and have it restart your Mongrels when the go down or don't respond promptly.
+
+h3. Q: How do I deploy Mongrel in production?
+
+Take a look at the "documentation pages":/docs/index.html for
+information on deploying and enhancing Mongrel.  Feel free to
+suggest documentation that you think is needed.
+
+h3. Q: Is there some kind of caching of session data in mongrel?
+
+Nope, Mongrel doesn't do anything with sessions and leaves that to the
+framework.
+
+h3. Q: What is the best way to get mongrel servers within a cluster to always keep their sessions synced?
+
+For Rails the best way is either memcached or database session storage.
+*Do not use PStore!*  It is broken, will crash or lock your Mongrel processes,
+and really isn't all that fast.
+
+h3. Q: What does num-procs do?
+
+There's two options that impact how your deployment performs
+and what kind of resources it eats.
+
+* num-procs -- Determines how many active requests are allowed
+before clients are denied and old requests are killed off.
+* timeout -- Determines a short sleep time between each client
+that is accepted.  This acts as a kind of throttle.
+
+With num-procs you should think of it as the option that protects
+your server from overload.  Let's say you set it to 100 and you
+get 100 requests coming in that are all being worked on.  If
+request 101 comes in then that request gets closed immediately,
+and Mongrel goes through the original 100 looking for requests to
+kill off.  Right now it uses the timeout to come up with a reasonable
+way to determine how long something is taking and will kill old
+processors with an exception.
+
+The timeout option is what you use if you want to make sure that
+a Mongrel server can't take on too much work (i.e. you need to
+throttle it).  What it does is sleep for N 100th/second after
+each accept.  This means that it will slow down the number of
+incoming clients.  Very handy if you have a shared hosting system
+and don't want people to eat your servers.
+
+
+h3. Q: Mongrel stops working if it's left alone for a long time.
+
+If you find that Mongrel stops working after a long idle time
+and you're using MySQL then you're hitting a bug in the MySQL
+driver that doesn't properly timeout connections.  What happens
+is the MySQL *server* side of the connection times out and closes,
+but the MySQL *client* doesn't detect this and just sits there.
+
+What you have to do is set:
+
+  ActiveRecord::Base.verification_timeout = 14400
+
+Or to any value that is lower than the MySQL server's *interactive_timeout*
+setting.  This will make sure that ActiveRecord checks the connection
+often enough to reset the connection.
+
+
+h3. Q: Why is the first request to Mongrel really slow?
+
+The first request to *any* system will be slower than
+the others, you are just noticing it with Mongrel because
+the difference is so much larger.
+
+The cause of this depends on many factors, but typically it
+is either Rails start-up, slow machine, no memory, or eager loading
+the world.  If you are on a slow box, or if you are trying to
+load a huge amount of data when Rails starts, then the
+first request will be nasty slow.
+
+This shouldn't really bug you though unless it happens periodically
+rather than from a cold start.  If it happens from a cold start or
+after a long idle period then point your service monitor at your
+application to keep it fresh.
+
+If you run a long performance test and you see periodic pauses
+then you may have a memory leak or not enough ram.  Re-run your
+test while you monitor your ram with something like *top*.  If
+you see the ram of Mongrel increase and then drop, or just increase,
+or you see the swap grow and shrink, then you've got a memory leak
+or just simply need more ram.
+
+Debugging a leak is possible with the mongrel_rails start -B option.
+It will log objects that get created to log/mongrel_debug and you can
+look in there to find out what object is causing the problems.
+
+
+h3. Why doesn't Mongrel write the .pid file like I tell it to?
+
+There was a change to the 0.3.13.4 release and on that makes it so Mongrel
+doesn't try to "fix" invalid paths.  You should change your configurations
+so that they give explicit full paths to both the log and pid files.
+
+
+h3. How do I put my Rails site at /someprefix?
+
+Most people use a virtual host configuration, but Mongrel now has an option
+that lets you put your site at an arbitrary URI.  Just start mongrel with:
+
+ mongrel_rails start -e production --prefix=/someprefix
+
+Then your site will be at the same host but everything will be relative to
+/someprefix.  The only thing is you have to *religiously* use Rails link_to
+and friends.  If you don't then the links in your pages won't be written right.
+
+
+h3. How many Mongrel processes should I run?
+
+First off, the type of machine you have doesn't matter, what matters is
+that you measure your *deployment's* speed and tune that for optimal
+performance.  Then you *must* re-test after every change to your deployment
+configuration to make sure that things didn't get worse or improve.
+
+There's a simple "document on tuning":/docs/how_many_mongrels.html that
+should get you started.
+
+h3. What does BAD CLIENT mean?
+
+It means that a request came in which Mongrel rejects because it doesn't follow
+the RFC grammar.  Mongrel is pretty relaxed about most requests, but in order to
+block the majority of security attacks for web servers it is strict about characters
+used, header formats, status line formats, etc.  This is also based on matching
+the RFC's grammar specification to a Ragel grammar specification, so it's easy
+to compare.
+
+If you need to know why the client is triggering this, then simply hit your
+Mongrel processes with USR1 signals and they'll log the full request data
+and parameters that were collected.  Then, if you think the request is valid
+send me this data and I'll look.  If it's not valid than fix the client.
+
+Mongrel takes the stance that all clients are written by software developers and
+that they should follow the standard.  By doing this it reduces the bugs and
+potential security holes found in many other web servers.  It also means that
+if you absolutely have to allow a bad client, then you'll need to not use Mongrel.
+
+
+h3. Why do I get MySQL "lost connection to database" errors?
+
+The most common cause is that you're using mysql.rb that comes with Rails
+rather than the MySQL compiled ruby driver from gems.  Do this:
+
+  sudo gem install mysql
+
+And pick the one for your system (don't type sudo if you're win32).
+
+
+h3. Why does Mongrel keep dying on me?
+
+There are three known causes to this, and all of them are your fault.
+First, there's a few symptoms to check to see if you fit in these
+categories.
+
+* CLOSE_WAIT: Run @lsof -i -P | grep CLOSE_WAIT@ and if you see a bunch of mongrels then you've got a problem.
+* 99% CPU: Check the mongrel processes and see if one or more are at 99%.
+* MEMORY LEAK:  We've supposedly fixed it, but you might be causing it yourself.
+
+In the case of CLOSE_WAIT and 99% CPU the problem is most likely you're using the
+PStore for your session storage.  Don't do this.  Use memcached or database for your
+session storage.  PStore is slow anyway, but with multiple processes it's deadly.
+
+Another cause of CLOSE_WAIT and 99% CPU is one of your Rails actions is doing something
+that "jams" Mongrel requests.  Temporarily turn on USR1 debugging:
+
+  killall -USR1 mongrel_rails
+
+And then watch what Mongrel says about the number of threads waiting for the various
+Rails actions you have.  You'll see right away which one is causing it.  Usually
+it's because you're using an external 3rd party library that isn't designed for
+multiple process action.
+
+For memory leaks the most common cause is using Mutex.  We found that on most systems
+Mutex caused memory leaks when the Mutex was managing many Threads.  Switch to using
+Sync and see if the memory leak goes away.
+
+Other things that can cause big pauses are:
+
+* Using a broken or slow DNS server to resolve hosts.  Ruby blocks the whole process while it resolves.
+* Loading tons and tons of data over and over again.  The GC will kill you if Linux doesn't.
+* Locking files wrong.  Multiple processes locking files is a delicate thing to do.
+* Doing stuff over the network that takes a long time.  Move that process to a DRb server run locally.
+
+If you have to do extensive DNS resolving then consider using dnsmasq run locally to cache the DNS
+queries and make them faster.
+
+h3. How can I run some code before Rails starts?
+
+Simplest way is to put it in your production.rb and configure it there, but if
+you need it done long before Rails starts, then you can throw it into a
+mongrel.conf and run that file with the -S option (see mongrel_rails --help).
+The mongrel.conf is a Ruby script that lets you configure Mongrel with special
+Ruby code, but you can also put other Ruby code in it.
+
+h3. Why do I see my headers when Mongrel is behind Apache?
+
+If you see something weird like this in your browser when you're behind Apache:
+
+  HTTP/1.1 0 Content-Length: 7636
+  Connection: close
+  Date: Sat, 02 Sep 2006 14:10:38 GMT
+  Set-Cookie: device_id=; path=/; expires=Sun, 02 Sep 2007 14:10:38 GMT
+  Set-Cookie: _session_id=85d7a3c296268e0222cb796127da9c43; path=/
+  *Status: status500*
+  Cache-Control: no-cache
+  Server: Mongrel 0.3.13.3
+  Content-Type: text/html
+
+Then what you've done is you've mangled the *status* code inside rails with something
+that is setting "status => 500".  Rails is then injecting this right in, as you can
+see in the above Status line.  Since this is an invalid status, Apache "helpfully"
+shows you the error so you can correct it.
+
+
+h2. Mongrel Web Site
+
+h3. Q: How did you make this site?
+
+The site was actually incredibly easy to create.  I simply went to "OSWD":http://openwebdesign.org/
+and found a design that fit what I wanted for the site.  I then went to "Flickr":http://flickr.com/
+and found pictures of various animals that were licensed under the
+"Creative Commons":http://creativecommons.org/ license.  Once I chopped the images up, worked them
+into the design structure, and wrote an initial set of content I was done.
+
+The tool I use to generate the site is called "webgen":http://webgen.rubyforge.org/ which
+is a static site generator written in Ruby.  I write all of the content using redcloth
+mark-up and leave the generation to webgen.  Finally I hooked into the Mongrel Rakefile
+so that it's auto-generated and deployed to the site for me.
+
+Refer to the "attributions":/attributions.html page for information on the resources used.