1
0
Fork 0
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:
zedshaw 2006-03-03 06:02:33 +00:00
parent f826d89b81
commit caabee7221
6 changed files with 201 additions and 72 deletions

View file

@ -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" />

View file

@ -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.

View file

@ -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.

View file

@ -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

View file

@ -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

View file

@ -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