mirror of
https://github.com/puma/puma.git
synced 2022-11-09 13:48:40 -05:00
Damn bug in how CGI encodes redirects so that they default to port 0 if SERVER_PORT not defined (happens with proxied servers on port 80).
git-svn-id: svn+ssh://rubyforge.org/var/svn/mongrel/trunk@72 19e92222-5c0b-0410-8929-a290d50e31e9
This commit is contained in:
parent
f826d89b81
commit
caabee7221
6 changed files with 201 additions and 72 deletions
|
@ -46,6 +46,18 @@
|
|||
<h4>NEWS</h4>
|
||||
|
||||
<dl>
|
||||
<dt>Mar-02-2006</dt>
|
||||
<dd>
|
||||
<h5><a href="{relocatable: news.html}">Mongrel 0.3.7 -- Solid Rails, Win32, SwitchTower, Docs</a></h5>
|
||||
|
||||
<p>A slightly longer time between releases but this is packed with lots of good
|
||||
things for people who want to run Mongrel. Highlights: SwitchTower,
|
||||
Best Practices, Page Caching Support, Win32 CPU Affinity, Solid Stability.
|
||||
</p>
|
||||
<a href="http://rubyforge.org/frs/?group_id=1306" title="Downloads">Download</a>
|
||||
<a href="{relocatable: news.html}"><img src="{relocatable: images/li4.gif}" alt="more" /><br /></a></p>
|
||||
</dd>
|
||||
|
||||
<dt>Feb-22-2006</dt>
|
||||
<dd>
|
||||
<h5><a href="{relocatable: news.html}">Mongrel 0.3.6 -- Win32 Service!</a></h5>
|
||||
|
@ -96,25 +108,6 @@
|
|||
<a href="{relocatable: news.html}"><img src="{relocatable:images/li4.gif}" alt="more" /><br /></a></p>
|
||||
</dd>
|
||||
|
||||
<dt>Feb-12-2006</dt>
|
||||
|
||||
<dd>
|
||||
<h5><a href="{relocatable: news.html}">Mongrel 0.3.1 Released</a></h5>
|
||||
|
||||
<p><a href="http://rubyforge.org/frs/?group_id=1306" title="Downloads">
|
||||
Download</a> the 0.3.1 release featuring better Rails support and a
|
||||
major bug fix.
|
||||
<a href="{relocatable: news.html}"><img src="{relocatable: images/li4.gif}" alt="more" /><br /></a></p>
|
||||
</dd>
|
||||
|
||||
<dt>Feb-12-2006</dt>
|
||||
|
||||
<dd>
|
||||
<h5><a href="{relocatable: news.html}">Site now up!</a></h5>
|
||||
|
||||
<p>The new website is up and now running.
|
||||
<a href="{relocatable: news.html}"><img src="{relocatable: images/li4.gif}" alt="more" /><br /></a></p>
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
<hr noshade="noshade" size="1" />
|
||||
|
|
|
@ -53,10 +53,11 @@ For lighttpd you need to have *mod_proxy* in your server.modules setting:
|
|||
Then you need to tell lighttpd where the other backends are located:
|
||||
|
||||
proxy.balance = "fair"
|
||||
proxy.server = ( "/" => ( ( "host" => "127.0.0.1", "port" => 8001 ),
|
||||
( "host" => "127.0.0.1", "port" => 8002 ),
|
||||
( "host" => "127.0.0.1", "port" => 8003 ),
|
||||
( "host" => "127.0.0.1", "port" => 8004 ) ) )
|
||||
proxy.server = ( "/" =>
|
||||
( ( "host" => "127.0.0.1", "port" => 8001 ),
|
||||
( "host" => "127.0.0.1", "port" => 8002 ),
|
||||
( "host" => "127.0.0.1", "port" => 8003 ),
|
||||
( "host" => "127.0.0.1", "port" => 8004 ) ) )
|
||||
|
||||
When I used lighttpd 1.4.9 and set proxy.balance="round-robin" I had an excessive number of
|
||||
500 errors for no real reason. The "fair" setting seems to be the best, but if you
|
||||
|
@ -71,10 +72,14 @@ Mongrel is pretty easy to setup with this configuration on either Win32 or Unix,
|
|||
since lighttpd doesn't compile so easily on Win32 I'll just show the Unix method
|
||||
for starting it:
|
||||
|
||||
$ mongrel_rails start -d -p 8001 -e production -P log/mongrel-1.pid
|
||||
$ mongrel_rails start -d -p 8002 -e production -P log/mongrel-2.pid
|
||||
$ mongrel_rails start -d -p 8003 -e production -P log/mongrel-3.pid
|
||||
$ mongrel_rails start -d -p 8004 -e production -P log/mongrel-4.pid
|
||||
$ mongrel_rails start -d -p 8001 \
|
||||
-e production -P log/mongrel-1.pid
|
||||
$ mongrel_rails start -d -p 8002 \
|
||||
-e production -P log/mongrel-2.pid
|
||||
$ mongrel_rails start -d -p 8003 \
|
||||
-e production -P log/mongrel-3.pid
|
||||
$ mongrel_rails start -d -p 8004 \
|
||||
-e production -P log/mongrel-4.pid
|
||||
|
||||
Now you should be able to hit your web server at port 80 and it'll run against
|
||||
one of your four Mongrels.
|
||||
|
@ -88,10 +93,14 @@ in lighttpd 1.4.9 but how did I figure this out? Here's how you can do it.
|
|||
You use "httperf":http://www.hpl.hp.com/research/linux/httperf/ to first hit each
|
||||
Mongrel backend with a large request set.
|
||||
|
||||
$ httperf --port 8001 --server 127.0.0.1 --num-conns 300 --uri /test
|
||||
$ httperf --port 8002 --server 127.0.0.1 --num-conns 300 --uri /test
|
||||
$ httperf --port 8003 --server 127.0.0.1 --num-conns 300 --uri /test
|
||||
$ httperf --port 8004 --server 127.0.0.1 --num-conns 300 --uri /test
|
||||
$ httperf --port 8001 --server 127.0.0.1 \
|
||||
--num-conns 300 --uri /test
|
||||
$ httperf --port 8002 --server 127.0.0.1 \
|
||||
--num-conns 300 --uri /test
|
||||
$ httperf --port 8003 --server 127.0.0.1 \
|
||||
--num-conns 300 --uri /test
|
||||
$ httperf --port 8004 --server 127.0.0.1 \
|
||||
--num-conns 300 --uri /test
|
||||
|
||||
After each of these you're looking for the *Connection rate*, *Request rate*,
|
||||
*Reply rate*, and *Reply status*. You first look at the *Reply status* to make
|
||||
|
@ -100,7 +109,8 @@ sure they are about the same.
|
|||
|
||||
Then you hit lighttpd with a similar request set to confirm that it handles the base case.
|
||||
|
||||
$ httperf --port 80 --server 127.0.0.1 --num-conns 300 --uri /test
|
||||
$ httperf --port 80 --server 127.0.0.1 \
|
||||
--num-conns 300 --uri /test
|
||||
|
||||
You should get no 5xx errors. In the case of round-robin there were about 60%
|
||||
5xx errors even though the Mongrels were functioning just fine. The "hash" method
|
||||
|
@ -109,7 +119,8 @@ seems the "fair" method is the best you can do right now.
|
|||
|
||||
Finally you hit lighttpd with a 4x rate to see if it could handle the theoretical limit.
|
||||
|
||||
$ httperf --port 80 --server 127.0.0.1 --num-conns 10000 --uri /test --rate 600
|
||||
$ httperf --port 80 --server 127.0.0.1 \
|
||||
--num-conns 10000 --uri /test --rate 600
|
||||
|
||||
It will most likely fail miserably and you'll probably see a few 5xx counts in the
|
||||
*Reply status* line but that's normal. What you're looking to do is keep moving
|
||||
|
@ -120,25 +131,107 @@ to your --rate setting causes the Request rate to tank. That's your setup's brea
|
|||
point and is the actual requests/second you can handle.
|
||||
|
||||
|
||||
h2. Other Configuration Tips
|
||||
h1. Insane Caching Power Magnet
|
||||
|
||||
The only other thing that's missing from this setup is the page caching with
|
||||
mod_rewrite so that lighttpd is serving the static files. Right now your
|
||||
Mongrels are the ones serving the static files through lighttpd. What you
|
||||
want is to have lighttpd serve the static files from page caching and if
|
||||
it doesn't find it talk to Rails.
|
||||
Mongrel (as of 0.3.7) by default supports Rails style page caching
|
||||
in the RailsHandler it uses to serve your applications. What this
|
||||
means is that if you do a page cached action (which writes a
|
||||
.html file as well as respond) then Mongrel will just serve up
|
||||
the cached page instead of bug Rails.
|
||||
|
||||
Well there's one problem with this configuration: I don't know how to
|
||||
do it with lighttpd. Normally you'd do this with SCGI or FastCGI:
|
||||
This does give you a large boost in performance, but still not nearly
|
||||
as much as if you had lighttpd doing the caching for you. The optimal
|
||||
configuration would be where lighttpd checks for cached pages and then
|
||||
served it directly as it already does with FastCGI.
|
||||
|
||||
server.error-handler-404 = "/dispatch.scgi"
|
||||
url.rewrite = ("^/$" => "index.html", "^([^.]+)$" => "$1.html")
|
||||
There are some technical problems with this and the lighttpd mod_proxy,
|
||||
but thankfully I don't have to go into them because lighttpd now supports
|
||||
the "power magnet" and Cache Meta Language (CML). CML is a small bit
|
||||
of the Lua programming language that lets you script lighttpd and tell
|
||||
it when to cache or not. The power magnet feature of CML lets you put
|
||||
all requests through one CML script so that you can determine whether
|
||||
to cache or not.
|
||||
|
||||
Problem with this is that setting the requests are being sent back
|
||||
directly to each Mongrel unlike with /dispatch.scgi which modifies
|
||||
the request to work with SCGI.
|
||||
h2. Configuration
|
||||
|
||||
In order to get everything to work right you'll need a few pieces
|
||||
of equipment and make sure they are enabled in your lighttpd build.
|
||||
The sample build was done on Debian so that everything would work
|
||||
including mod_rewrite, mod_memcache, mod_cml, and mod_redirect.
|
||||
|
||||
* lua50, liblua50-dev
|
||||
* libpcre3-dev
|
||||
* memcached
|
||||
* Finally make sure you configure with ./configure --with-lua --with-memcache
|
||||
|
||||
This is especially important on Debian since even though they
|
||||
have the latest lighttpd they don't compile it with these options.
|
||||
On Debian I had to also modify the src/Makefile to remove some
|
||||
invalid library settings for Lua. I'll let you figure those out.
|
||||
|
||||
|
||||
h3. lighttpd.conf
|
||||
|
||||
If it all builds right then you'll be able to use this nifty
|
||||
CML script that Bradley K. Taylor (from railsmachine.net) came
|
||||
up with. First you need to tweak your lighttpd.conf at the
|
||||
place where you have the mod_proxy setup from previous:
|
||||
|
||||
$HTTP["host"] == "www.myhost.come" {
|
||||
server.document-root = "/my/path/to/app/public"
|
||||
cml.power-magnet = "/my/path/to/app/config/power-magnet.cml"
|
||||
proxy.balance = "fair"
|
||||
proxy.server = ( "/" => ( ( "host" => "127.0.0.1", "port" => 8001 ),
|
||||
( "host" => "127.0.0.1", "port" => 8002 ) ) )
|
||||
}
|
||||
|
||||
This one just has two for simplicity. The big thing is the
|
||||
document root setting and the power-magnet.cml setting. I wouldn't
|
||||
put the power-magnet.cml in your public directory.
|
||||
|
||||
h3. power-magnet.cml
|
||||
|
||||
Now for the magic bit of Lua code that tells lighttpd what to do:
|
||||
|
||||
dr = request["DOCUMENT_ROOT"]
|
||||
|
||||
if file_isreg(dr .. "maintainance.html") then
|
||||
output_include = { dr .. "maintainance.html" }
|
||||
return CACHE_HIT
|
||||
end
|
||||
|
||||
f = request["REQUEST_URI"]
|
||||
|
||||
if f == "/" or f == "" then
|
||||
file = dr .. "index.html"
|
||||
elseif not string.find(f, "%.") then -- rewrite for cached pages
|
||||
file = dr .. f .. ".html"
|
||||
else
|
||||
file = dr .. f
|
||||
end
|
||||
|
||||
if file_isreg(file) then
|
||||
output_include = { file }
|
||||
return CACHE_HIT
|
||||
end
|
||||
|
||||
return 1 -- should be CACHE_MISS, but there's a bug in 1.4.10
|
||||
|
||||
Place this in the /my/path/to/app/config/power-magnet.cml like you
|
||||
configured above.
|
||||
|
||||
Now if you restart lighttpd and everything worked right you should
|
||||
be able to see the headers and tell if Mongrel or lighttpd is serving
|
||||
them.
|
||||
|
||||
|
||||
h2. Memcached
|
||||
|
||||
|
||||
|
||||
h2. CML Tricks
|
||||
|
||||
Since Lua is a full blown and fast little language
|
||||
you can get pretty creative with it.
|
||||
|
||||
A better tactic might be to delve into the CML (Cache Meta Language)
|
||||
that lighttpd supports to see if it offers better caching. A future
|
||||
version of these instructions will try to solve this problem.
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ pre-compiled gems available for people to use.
|
|||
|
||||
h2. Stopping The mongrel_rails Script
|
||||
|
||||
When you run the mongrel_rails script from the command line you'll have to use CTRL-Pause/Break
|
||||
When you run the mongrel_rails script from the command line you'll have to use *CTRL-Pause/Break*
|
||||
to get it to exit rather than CTRL-C.
|
||||
|
||||
|
||||
|
@ -30,29 +30,21 @@ and do:
|
|||
|
||||
Now hit the port and poof, works (or should).
|
||||
|
||||
*Stopping the service is a little problematic right now.* We're working on graceful
|
||||
shutdown, so be patient. The application will stop if you use:
|
||||
The application will stop if you use:
|
||||
|
||||
$ mongrel_rails_service stop -n myapp
|
||||
|
||||
But will complain about an error during shutdown. If you try to stop using the
|
||||
Services control panel then it will seem to hang. Just wait a little while then
|
||||
hit stop once the service actually stop.
|
||||
Now the really great thing is that you can just do all this from
|
||||
the Services control panel like your Rails application is a regular
|
||||
Windows service.
|
||||
|
||||
|
||||
h2. Development Work
|
||||
|
||||
I recommend that you keep the service runner for doing a production run setup,
|
||||
and then use a regular console with the plain Mongrel runner until we get
|
||||
service stop working right.
|
||||
|
||||
Also, if you run into an app that's not running right, my suggestion is to run it with
|
||||
the regular mongrel_rails runner:
|
||||
|
||||
$ cd c:\my\path\to\myapp
|
||||
$ mongrel_rails start -p 4500
|
||||
|
||||
Since that will spit out error messages and stuff to the console. *Use CTRL-Pause/Break to stop.*
|
||||
Even works in development mode, which is pretty nice. I use win32
|
||||
at work now and what I have setup is three services: myapp_dev,
|
||||
myapp_stage, myapp_prod. I point dev and stage at the same
|
||||
directory but run dev in *development* mode and stage in *production*
|
||||
mode. Then I have myapp_prod in a separate directory and when I'm
|
||||
about to claim I've got something to release I'll go simulate a
|
||||
subversion check-out and run my tests again.
|
||||
|
||||
|
||||
h2. Other Service Commands
|
||||
|
@ -91,3 +83,20 @@ Takes the name (-n) of the service to delete and then removes it from the list.
|
|||
*This would be how you'd remove a service so you can change it's start-up options.*
|
||||
|
||||
|
||||
h2. CPU Affinity
|
||||
|
||||
Mongrel's win32 support actually is able to set the CPU affinity of a running
|
||||
Mongrel service. This is pretty neat since it means if you're running a
|
||||
fancy SMP machine or a dual core that pretends to be SMP, then you can
|
||||
force Mongrel onto one of them and get a nice little boost.
|
||||
|
||||
It's pretty easy to use, just pass the *-c or --cpu* option to the *install*
|
||||
command and give a CPU of 1-X. That means if you have 4 CPUs and you want
|
||||
Mongrel on #4 then do:
|
||||
|
||||
$ mongrel_rails_service install -n myapp \
|
||||
-r c:\my\path\to\myapp -p 4000 -e production -c 4
|
||||
|
||||
Pretty much the same command, just one more option and you're done.
|
||||
|
||||
|
||||
|
|
|
@ -8,7 +8,8 @@ h1. What is Mongrel?
|
|||
Mongrel is a fast HTTP library and server for Ruby that is intended for
|
||||
hosting Ruby web applications of any kind using plain HTTP rather than
|
||||
FastCGI or SCGI. It is framework agnostic and already supports
|
||||
Ruby On Rails, Og+Nitro, and Camping frameworks.
|
||||
"Ruby On Rails":http://www.rubyonrails.org, "Og+Nitro":http://www.nitrohq.com/,
|
||||
and "Camping":http://camping.rubyforge.org/files/README.html frameworks.
|
||||
|
||||
|
||||
h2. Getting Started
|
||||
|
@ -42,7 +43,13 @@ and do:
|
|||
-r c:\my\path\to\myapp -p 4000 -e production
|
||||
$ mongrel_rails_service start -n myapp
|
||||
|
||||
Now hit the port and poof, works. *Stopping the service is a little problematic right now.*
|
||||
Now hit the port and poof, works. Stopping the app is just done with:
|
||||
|
||||
$ mongrel_rails_service stop -n myapp
|
||||
|
||||
And, you can *even* set the CPU processor affinity for the service when
|
||||
yourun the install command. Can't even do that on POSIX yet. Now
|
||||
that's hot.
|
||||
|
||||
If you run into an app that's not running right, my suggestion is to run it with
|
||||
the regular mongrel_rails runner:
|
||||
|
@ -67,6 +74,10 @@ more, but for serving basic content mongrel does pretty good.
|
|||
|
||||
There will be a more formal performance analysis when Mongrel is more stable.
|
||||
|
||||
*NOTE: On FreeBSD and Mac OSX I've found Mongrel performs really poorly.* Compared
|
||||
to Linux, Win32, or NetBSD these two OS seem to be doing something very "different".
|
||||
We'll be tuning these two platforms better, but it may just be a Ruby problem.
|
||||
|
||||
|
||||
h2. Documentation
|
||||
|
||||
|
|
|
@ -7,6 +7,29 @@ ordering: 2
|
|||
|
||||
h1. Latest News
|
||||
|
||||
h2. Mar-03: Mongrel 0.3.7 -- Solid Rails, Win32, SwitchTower, Docs
|
||||
|
||||
A slightly longer time between releases but this is packed with lots of good
|
||||
things for people who want to run Mongrel. We're talking Win32 CPU affinity,
|
||||
better service, POSIX signal control for SwitchTower, more tested platforms,
|
||||
little bug fixes, and documentation on deployment best practices.
|
||||
|
||||
This release has also been tested on tons of platforms: Linux, NetBSD, FreeBSD,
|
||||
Windows, and Mac OSX. Under FreeBSD Mongrel seems to ignore signals unless
|
||||
you do one more network connection, but the other platforms work great.
|
||||
|
||||
* Initial beginning of the plugin support that will let people write
|
||||
their own handlers and other things for Mongrel.
|
||||
* Timeout now works again but couldn't find an alternative to the buggy Timeout class.
|
||||
* SwitchTower friendly signal handling for mongrel_rails.
|
||||
* Win32: New option that lets you set a mongrel service's CPU affinity.
|
||||
* Win32: Indicates default environment used for the services.
|
||||
* Win32: Avoids touching signals when on windows.
|
||||
* Tested on: Linux, Win32, FreeBSD, NetBSD, OSX.
|
||||
|
||||
"Download 0.3.7":http://rubyforge.org/frs/?group_id=1306
|
||||
|
||||
|
||||
h2. Feb-22: Mongrel 0.3.6 -- Win32 Services Galore
|
||||
|
||||
Thanks to Luis Lavena we have an almost complete win32 service
|
||||
|
|
|
@ -182,7 +182,7 @@ module Mongrel
|
|||
params[Const::REMOTE_ADDR]=socket.peeraddr[3]
|
||||
host,port = params[Const::HTTP_HOST].split(":")
|
||||
params[Const::SERVER_NAME]=host
|
||||
params[Const::SERVER_PORT]=port if port
|
||||
params[Const::SERVER_PORT]=port || 80
|
||||
params[Const::SERVER_PROTOCOL]=Const::SERVER_PROTOCOL_VALUE
|
||||
params[Const::SERVER_SOFTWARE]=Const::MONGREL_VERSION
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue