unicorn-shopify 4.8.2.5.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.CHANGELOG.old +25 -0
- data/.document +28 -0
- data/.gitignore +25 -0
- data/.mailmap +26 -0
- data/.olddoc.yml +15 -0
- data/Application_Timeouts +77 -0
- data/CONTRIBUTORS +35 -0
- data/COPYING +674 -0
- data/DESIGN +97 -0
- data/Documentation/.gitignore +5 -0
- data/Documentation/GNUmakefile +30 -0
- data/Documentation/unicorn.1.txt +185 -0
- data/Documentation/unicorn_rails.1.txt +175 -0
- data/FAQ +61 -0
- data/GIT-VERSION-GEN +39 -0
- data/GNUmakefile +252 -0
- data/HACKING +120 -0
- data/ISSUES +100 -0
- data/KNOWN_ISSUES +79 -0
- data/LICENSE +67 -0
- data/Links +59 -0
- data/PHILOSOPHY +145 -0
- data/README +145 -0
- data/Rakefile +16 -0
- data/SIGNALS +123 -0
- data/Sandbox +103 -0
- data/TODO +5 -0
- data/TUNING +101 -0
- data/archive/.gitignore +3 -0
- data/archive/slrnpull.conf +4 -0
- data/bin/unicorn +126 -0
- data/bin/unicorn_rails +209 -0
- data/examples/big_app_gc.rb +2 -0
- data/examples/echo.ru +27 -0
- data/examples/init.sh +74 -0
- data/examples/logger_mp_safe.rb +25 -0
- data/examples/logrotate.conf +29 -0
- data/examples/nginx.conf +156 -0
- data/examples/unicorn.conf.minimal.rb +13 -0
- data/examples/unicorn.conf.rb +113 -0
- data/ext/unicorn_http/CFLAGS +13 -0
- data/ext/unicorn_http/c_util.h +124 -0
- data/ext/unicorn_http/common_field_optimization.h +111 -0
- data/ext/unicorn_http/ext_help.h +82 -0
- data/ext/unicorn_http/extconf.rb +10 -0
- data/ext/unicorn_http/global_variables.h +97 -0
- data/ext/unicorn_http/httpdate.c +78 -0
- data/ext/unicorn_http/unicorn_http.rl +934 -0
- data/ext/unicorn_http/unicorn_http_common.rl +76 -0
- data/lib/unicorn.rb +112 -0
- data/lib/unicorn/app/old_rails.rb +35 -0
- data/lib/unicorn/app/old_rails/static.rb +59 -0
- data/lib/unicorn/cgi_wrapper.rb +147 -0
- data/lib/unicorn/configurator.rb +686 -0
- data/lib/unicorn/const.rb +21 -0
- data/lib/unicorn/http_request.rb +125 -0
- data/lib/unicorn/http_response.rb +73 -0
- data/lib/unicorn/http_server.rb +816 -0
- data/lib/unicorn/launcher.rb +62 -0
- data/lib/unicorn/oob_gc.rb +81 -0
- data/lib/unicorn/preread_input.rb +33 -0
- data/lib/unicorn/socket_helper.rb +197 -0
- data/lib/unicorn/stream_input.rb +146 -0
- data/lib/unicorn/tee_input.rb +133 -0
- data/lib/unicorn/tmpio.rb +27 -0
- data/lib/unicorn/util.rb +90 -0
- data/lib/unicorn/worker.rb +140 -0
- data/setup.rb +1586 -0
- data/t/.gitignore +4 -0
- data/t/GNUmakefile +74 -0
- data/t/README +42 -0
- data/t/before_murder.ru +7 -0
- data/t/bin/content-md5-put +36 -0
- data/t/bin/sha1sum.rb +17 -0
- data/t/bin/unused_listen +40 -0
- data/t/broken-app.ru +12 -0
- data/t/detach.ru +11 -0
- data/t/env.ru +3 -0
- data/t/fails-rack-lint.ru +5 -0
- data/t/heartbeat-timeout.ru +12 -0
- data/t/hijack.ru +42 -0
- data/t/listener_names.ru +4 -0
- data/t/my-tap-lib.sh +201 -0
- data/t/oob_gc.ru +20 -0
- data/t/oob_gc_path.ru +20 -0
- data/t/pid.ru +3 -0
- data/t/preread_input.ru +17 -0
- data/t/rack-input-tests.ru +21 -0
- data/t/t0000-http-basic.sh +50 -0
- data/t/t0001-reload-bad-config.sh +53 -0
- data/t/t0002-config-conflict.sh +49 -0
- data/t/t0002-parser-error.sh +94 -0
- data/t/t0003-working_directory.sh +51 -0
- data/t/t0004-heartbeat-timeout.sh +69 -0
- data/t/t0004-working_directory_broken.sh +24 -0
- data/t/t0005-working_directory_app.rb.sh +40 -0
- data/t/t0006-reopen-logs.sh +83 -0
- data/t/t0006.ru +13 -0
- data/t/t0007-working_directory_no_embed_cli.sh +44 -0
- data/t/t0008-back_out_of_upgrade.sh +110 -0
- data/t/t0009-broken-app.sh +56 -0
- data/t/t0009-winch_ttin.sh +59 -0
- data/t/t0010-reap-logging.sh +55 -0
- data/t/t0011-active-unix-socket.sh +79 -0
- data/t/t0012-reload-empty-config.sh +85 -0
- data/t/t0013-rewindable-input-false.sh +24 -0
- data/t/t0013.ru +12 -0
- data/t/t0014-rewindable-input-true.sh +24 -0
- data/t/t0014.ru +12 -0
- data/t/t0015-configurator-internals.sh +25 -0
- data/t/t0018-write-on-close.sh +23 -0
- data/t/t0019-max_header_len.sh +49 -0
- data/t/t0020-at_exit-handler.sh +49 -0
- data/t/t0021-process_detach.sh +29 -0
- data/t/t0022-listener_names-preload_app.sh +32 -0
- data/t/t0023-before-murder.sh +40 -0
- data/t/t0024-before-murder_once.sh +52 -0
- data/t/t0100-rack-input-tests.sh +124 -0
- data/t/t0116-client_body_buffer_size.sh +80 -0
- data/t/t0116.ru +16 -0
- data/t/t0200-rack-hijack.sh +27 -0
- data/t/t0300-no-default-middleware.sh +20 -0
- data/t/t9000-preread-input.sh +48 -0
- data/t/t9001-oob_gc.sh +47 -0
- data/t/t9002-oob_gc-path.sh +75 -0
- data/t/test-lib.sh +128 -0
- data/t/write-on-close.ru +11 -0
- data/test/aggregate.rb +15 -0
- data/test/benchmark/README +50 -0
- data/test/benchmark/dd.ru +18 -0
- data/test/benchmark/stack.ru +8 -0
- data/test/exec/README +5 -0
- data/test/exec/test_exec.rb +1047 -0
- data/test/test_helper.rb +297 -0
- data/test/unit/test_configurator.rb +175 -0
- data/test/unit/test_droplet.rb +28 -0
- data/test/unit/test_http_parser.rb +854 -0
- data/test/unit/test_http_parser_ng.rb +622 -0
- data/test/unit/test_request.rb +182 -0
- data/test/unit/test_response.rb +93 -0
- data/test/unit/test_server.rb +268 -0
- data/test/unit/test_signals.rb +188 -0
- data/test/unit/test_socket_helper.rb +197 -0
- data/test/unit/test_stream_input.rb +203 -0
- data/test/unit/test_tee_input.rb +304 -0
- data/test/unit/test_upload.rb +306 -0
- data/test/unit/test_util.rb +105 -0
- data/unicorn.gemspec +41 -0
- metadata +311 -0
data/ISSUES
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
= Issues
|
|
2
|
+
|
|
3
|
+
mailto:unicorn-public@bogomips.org is the best place to report bugs,
|
|
4
|
+
submit patches and/or obtain support after you have searched the
|
|
5
|
+
{email archives}[http://bogomips.org/unicorn-public/] and
|
|
6
|
+
{documentation}[http://unicorn.bogomips.org/].
|
|
7
|
+
|
|
8
|
+
* No subscription will ever be required to email the public inbox.
|
|
9
|
+
* Cc: all participants in a thread or commit, as subscription is optional
|
|
10
|
+
* Do not {top post}[http://catb.org/jargon/html/T/top-post.html] in replies
|
|
11
|
+
* Quote as little as possible of the message you're replying to
|
|
12
|
+
* Do not send HTML mail, it will likely be flagged as spam
|
|
13
|
+
|
|
14
|
+
If your issue is of a sensitive nature or you're just shy in public,
|
|
15
|
+
then feel free to email us privately at mailto:unicorn@bogomips.org
|
|
16
|
+
instead and your issue will be handled discreetly.
|
|
17
|
+
|
|
18
|
+
If you don't get a response within a few days, we may have forgotten
|
|
19
|
+
about it so feel free to ask again.
|
|
20
|
+
|
|
21
|
+
== Bugs in related projects
|
|
22
|
+
|
|
23
|
+
unicorn is sometimes affected by bugs in its dependencies. Bugs
|
|
24
|
+
triggered by unicorn in mainline Ruby, rack, GNU C library (glibc),
|
|
25
|
+
or the Linux kernel will be reported upstream and fixed.
|
|
26
|
+
|
|
27
|
+
For bugs in Ruby itself, we may forward bugs to
|
|
28
|
+
https://bugs.ruby-lang.org/ and discuss+fix them on the ruby-core
|
|
29
|
+
list at mailto:ruby-core@ruby-lang.org
|
|
30
|
+
Subscription to post is required to ruby-core, unfortunately:
|
|
31
|
+
mailto:ruby-core-request@ruby-lang.org?subject=subscribe
|
|
32
|
+
|
|
33
|
+
For uncommon bugs in Rack, we may forward bugs to
|
|
34
|
+
mailto:rack-devel@googlegroups.com and discuss there.
|
|
35
|
+
Subscription (without any web UI or Google account) is possible via:
|
|
36
|
+
mailto:rack-devel+subscribe@googlegroups.com
|
|
37
|
+
Note: not everyone can use the proprietary bug tracker used by Rack,
|
|
38
|
+
but their mailing list remains operational.
|
|
39
|
+
|
|
40
|
+
Uncommon bugs we encounter in the Linux kernel should be Cc:-ed to the
|
|
41
|
+
Linux kernel mailing list (LKML) at mailto:linux-kernel@vger.kernel.org
|
|
42
|
+
and subsystem maintainers such as mailto:netdev@vger.kernel.org
|
|
43
|
+
(for networking issues). It is expected practice to Cc: anybody
|
|
44
|
+
involved with any problematic commits (including those in the
|
|
45
|
+
Signed-off-by: and other trailer lines). No subscription is necessary,
|
|
46
|
+
and the our mailing list follows the same conventions as LKML for
|
|
47
|
+
interopability. There is a kernel.org Bugzilla instance, but it is
|
|
48
|
+
ignored by most developers.
|
|
49
|
+
|
|
50
|
+
Likewise for any rare glibc bugs we might encounter, we should Cc:
|
|
51
|
+
mailto:libc-alpha@sourceware.org
|
|
52
|
+
Keep in mind glibc upstream does use Bugzilla for tracking bugs:
|
|
53
|
+
https://sourceware.org/bugzilla/
|
|
54
|
+
|
|
55
|
+
== Submitting Patches
|
|
56
|
+
|
|
57
|
+
See the HACKING document (and additionally, the
|
|
58
|
+
{SubmittingPatches}[https://git.kernel.org/cgit/git/git.git/tree/Documentation/SubmittingPatches]
|
|
59
|
+
document distributed with git) on guidelines for patch submission.
|
|
60
|
+
|
|
61
|
+
== Contact Info
|
|
62
|
+
|
|
63
|
+
* public: mailto:unicorn-public@bogomips.org
|
|
64
|
+
* private: mailto:unicorn@bogomips.org
|
|
65
|
+
|
|
66
|
+
We operate a {public-inbox}[http://public-inbox.org/] which
|
|
67
|
+
feeds the mailing list. You may subscribe either using
|
|
68
|
+
{ssoma}[http://ssoma.public-inbox.org/] or by sending a mail
|
|
69
|
+
to mailto:unicorn-public+subscribe@bogomips.org
|
|
70
|
+
|
|
71
|
+
ssoma is a mail archiver/fetcher using git. It operates in a similar
|
|
72
|
+
fashion to tools such as slrnpull, fetchmail, or getmail. ssoma
|
|
73
|
+
subscription instructions:
|
|
74
|
+
|
|
75
|
+
URL=git://bogomips.org/unicorn-public
|
|
76
|
+
LISTNAME=unicorn
|
|
77
|
+
|
|
78
|
+
# to initialize a maildir (this may be a new or existing maildir,
|
|
79
|
+
# ssoma will not touch existing messages)
|
|
80
|
+
# If you prefer mbox, use mbox:/path/to/mbox as the last argument
|
|
81
|
+
# You may also use imap://$MAILSERVER/INBOX for an IMAP account
|
|
82
|
+
# or imaps:// for an IMAPS account, as well.
|
|
83
|
+
ssoma add $LISTNAME $URL maildir:/path/to/maildir
|
|
84
|
+
|
|
85
|
+
# read with your favorite MUA (only using mutt as an example)
|
|
86
|
+
mutt -f /path/to/maildir # (or /path/to/mbox)
|
|
87
|
+
|
|
88
|
+
# to keep your mbox or maildir up-to-date, periodically run the following:
|
|
89
|
+
ssoma sync $LISTNAME
|
|
90
|
+
|
|
91
|
+
# your MUA may modify and delete messages from the maildir or mbox,
|
|
92
|
+
# this does not affect ssoma functionality at all
|
|
93
|
+
|
|
94
|
+
# to sync all your ssoma subscriptions
|
|
95
|
+
ssoma sync
|
|
96
|
+
|
|
97
|
+
# You may wish to sync in your cronjob
|
|
98
|
+
ssoma sync --cron
|
|
99
|
+
|
|
100
|
+
HTML archives are available here: http://bogomips.org/unicorn-public/
|
data/KNOWN_ISSUES
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
= Known Issues
|
|
2
|
+
|
|
3
|
+
Occasionally odd {issues}[link:ISSUES.html] arise without a transparent or
|
|
4
|
+
acceptable solution. Those issues are documented here.
|
|
5
|
+
|
|
6
|
+
* Some libraries/applications may install signal handlers which conflict
|
|
7
|
+
with signal handlers unicorn uses. Leaving "preload_app false"
|
|
8
|
+
(the default) will allow unicorn to always override existing signal
|
|
9
|
+
handlers.
|
|
10
|
+
|
|
11
|
+
* Issues with FreeBSD jails can be worked around as documented by Tatsuya Ono:
|
|
12
|
+
http://mid.gmane.org/CAHBuKRj09FdxAgzsefJWotexw-7JYZGJMtgUp_dhjPz9VbKD6Q@mail.gmail.com
|
|
13
|
+
|
|
14
|
+
* PRNGs (pseudo-random number generators) loaded before forking
|
|
15
|
+
(e.g. "preload_app true") may need to have their internal state
|
|
16
|
+
reset in the after_fork hook. Starting with \Unicorn 3.6.1, we
|
|
17
|
+
have builtin workarounds for Kernel#rand and OpenSSL::Random users,
|
|
18
|
+
but applications may use other PRNGs.
|
|
19
|
+
|
|
20
|
+
* For notes on sandboxing tools such as Bundler or Isolate,
|
|
21
|
+
see the {Sandbox}[link:Sandbox.html] page.
|
|
22
|
+
|
|
23
|
+
* nginx with "sendfile on" under FreeBSD 8 is broken when
|
|
24
|
+
uploads are buffered to disk. Disabling sendfile is required to
|
|
25
|
+
work around this bug which should be fixed in newer versions of FreeBSD.
|
|
26
|
+
|
|
27
|
+
* When using "preload_app true", with apps using background threads
|
|
28
|
+
need to restart them in the after_fork hook because threads are never
|
|
29
|
+
shared with child processes. Additionally, any synchronization
|
|
30
|
+
primitives (Mutexes, Monitors, ConditionVariables) should be
|
|
31
|
+
reinitialized in case they are held during fork time to avoid
|
|
32
|
+
deadlocks. The core Ruby Logger class needlessly uses a MonitorMutex
|
|
33
|
+
which can be disabled with a {monkey patch}[link:examples/logger_mp_safe.rb]
|
|
34
|
+
|
|
35
|
+
== Known Issues (Old)
|
|
36
|
+
|
|
37
|
+
* Under some versions of Ruby 1.8, it is necessary to call +srand+ in an
|
|
38
|
+
after_fork hook to get correct random number generation. We have a builtin
|
|
39
|
+
workaround for this starting with \Unicorn 3.6.1
|
|
40
|
+
|
|
41
|
+
See http://redmine.ruby-lang.org/issues/show/4338
|
|
42
|
+
|
|
43
|
+
* On Ruby 1.8 prior to Ruby 1.8.7-p248, *BSD platforms have a broken
|
|
44
|
+
stdio that causes failure for file uploads larger than 112K. Upgrade
|
|
45
|
+
your version of Ruby or continue using Unicorn 1.x/3.4.x.
|
|
46
|
+
|
|
47
|
+
* Under Ruby 1.9.1, methods like Array#shuffle and Array#sample will
|
|
48
|
+
segfault if called after forking. Upgrade to Ruby 1.9.2 or call
|
|
49
|
+
"Kernel.rand" in your after_fork hook to reinitialize the random
|
|
50
|
+
number generator.
|
|
51
|
+
|
|
52
|
+
See http://redmine.ruby-lang.org/issues/show/2962 for more details
|
|
53
|
+
|
|
54
|
+
* Rails 2.3.2 bundles its own version of Rack. This may cause subtle
|
|
55
|
+
bugs when simultaneously loaded with the system-wide Rack Rubygem
|
|
56
|
+
which Unicorn depends on. Upgrading to Rails 2.3.4 (or later) is
|
|
57
|
+
strongly recommended for all Rails 2.3.x users for this (and security
|
|
58
|
+
reasons). Rails 2.2.x series (or before) did not bundle Rack and are
|
|
59
|
+
should be unnaffected. If there is any reason which forces your
|
|
60
|
+
application to use Rails 2.3.2 and you have no other choice, then
|
|
61
|
+
you may edit your Unicorn gemspec and remove the Rack dependency.
|
|
62
|
+
|
|
63
|
+
ref: http://mid.gmane.org/20091014221552.GA30624@dcvr.yhbt.net
|
|
64
|
+
Note: the workaround described in the article above only made
|
|
65
|
+
the issue more subtle and we didn't notice them immediately.
|
|
66
|
+
|
|
67
|
+
* WONTFIX: code reloading and restarts with Sinatra 0.3.x (and likely older
|
|
68
|
+
versions) apps is broken. The workaround is to force production
|
|
69
|
+
mode to disable code reloading as well as disabling "run" in your
|
|
70
|
+
Sinatra application:
|
|
71
|
+
set :env, :production
|
|
72
|
+
set :run, false
|
|
73
|
+
Since this is no longer an issue with Sinatra 0.9.x apps, this will not be
|
|
74
|
+
fixed on our end. Since Unicorn is itself the application launcher, the
|
|
75
|
+
at_exit handler used in old Sinatra always caused Mongrel to be launched
|
|
76
|
+
whenever a Unicorn worker was about to exit.
|
|
77
|
+
|
|
78
|
+
Also remember we're capable of replacing the running binary without dropping
|
|
79
|
+
any connections regardless of framework :)
|
data/LICENSE
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
Unicorn is copyrighted free software by all contributors, see logs in
|
|
2
|
+
revision control for names and email addresses of all of them.
|
|
3
|
+
|
|
4
|
+
You can redistribute it and/or modify it under either the terms of the
|
|
5
|
+
GNU General Public License (GPL) as published by the Free Software
|
|
6
|
+
Foundation (FSF), either version 2 of the License, or (at your option)
|
|
7
|
+
any later version. We currently prefer the GPLv3 or later for
|
|
8
|
+
derivative works, but the GPLv2 is fine.
|
|
9
|
+
|
|
10
|
+
The complete texts of the GPLv2 and GPLv3 are below:
|
|
11
|
+
GPLv2 - http://www.gnu.org/licenses/gpl-2.0.txt
|
|
12
|
+
GPLv3 - http://www.gnu.org/licenses/gpl-3.0.txt
|
|
13
|
+
|
|
14
|
+
You may (against our _preference_) also use the Ruby 1.8 license terms
|
|
15
|
+
which we inherited from the original Mongrel project when we forked it:
|
|
16
|
+
|
|
17
|
+
=== Ruby 1.8-specific terms (if you're not using the GPL)
|
|
18
|
+
|
|
19
|
+
1. You may make and give away verbatim copies of the source form of the
|
|
20
|
+
software without restriction, provided that you duplicate all of the
|
|
21
|
+
original copyright notices and associated disclaimers.
|
|
22
|
+
|
|
23
|
+
2. You may modify your copy of the software in any way, provided that
|
|
24
|
+
you do at least ONE of the following:
|
|
25
|
+
|
|
26
|
+
a) place your modifications in the Public Domain or otherwise make them
|
|
27
|
+
Freely Available, such as by posting said modifications to Usenet or an
|
|
28
|
+
equivalent medium, or by allowing the author to include your
|
|
29
|
+
modifications in the software.
|
|
30
|
+
|
|
31
|
+
b) use the modified software only within your corporation or
|
|
32
|
+
organization.
|
|
33
|
+
|
|
34
|
+
c) rename any non-standard executables so the names do not conflict with
|
|
35
|
+
standard executables, which must also be provided.
|
|
36
|
+
|
|
37
|
+
d) make other distribution arrangements with the author.
|
|
38
|
+
|
|
39
|
+
3. You may distribute the software in object code or executable
|
|
40
|
+
form, provided that you do at least ONE of the following:
|
|
41
|
+
|
|
42
|
+
a) distribute the executables and library files of the software,
|
|
43
|
+
together with instructions (in the manual page or equivalent) on where
|
|
44
|
+
to get the original distribution.
|
|
45
|
+
|
|
46
|
+
b) accompany the distribution with the machine-readable source of the
|
|
47
|
+
software.
|
|
48
|
+
|
|
49
|
+
c) give non-standard executables non-standard names, with
|
|
50
|
+
instructions on where to get the original software distribution.
|
|
51
|
+
|
|
52
|
+
d) make other distribution arrangements with the author.
|
|
53
|
+
|
|
54
|
+
4. You may modify and include the part of the software into any other
|
|
55
|
+
software (possibly commercial). But some files in the distribution
|
|
56
|
+
are not written by the author, so that they are not under this terms.
|
|
57
|
+
|
|
58
|
+
5. The scripts and library files supplied as input to or produced as
|
|
59
|
+
output from the software do not automatically fall under the
|
|
60
|
+
copyright of the software, but belong to whomever generated them,
|
|
61
|
+
and may be sold commercially, and may be aggregated with this
|
|
62
|
+
software.
|
|
63
|
+
|
|
64
|
+
6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
|
|
65
|
+
IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
|
66
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
67
|
+
PURPOSE.
|
data/Links
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
= Related Projects
|
|
2
|
+
|
|
3
|
+
If you're interested in \Unicorn, you may be interested in some of the projects
|
|
4
|
+
listed below. If you have any links to add/change/remove, please tell us at
|
|
5
|
+
mailto:unicorn-public@bogomips.org!
|
|
6
|
+
|
|
7
|
+
== Disclaimer
|
|
8
|
+
|
|
9
|
+
The \Unicorn project is not responsible for the content in these links.
|
|
10
|
+
Furthermore, the \Unicorn project has never, does not and will never endorse:
|
|
11
|
+
|
|
12
|
+
* any for-profit entities or services
|
|
13
|
+
* any non-{Free Software}[http://www.gnu.org/philosophy/free-sw.html]
|
|
14
|
+
|
|
15
|
+
The existence of these links does not imply endorsement of any entities
|
|
16
|
+
or services behind them.
|
|
17
|
+
|
|
18
|
+
=== For use with \Unicorn
|
|
19
|
+
|
|
20
|
+
* {Bluepill}[https://github.com/arya/bluepill] -
|
|
21
|
+
a simple process monitoring tool written in Ruby
|
|
22
|
+
|
|
23
|
+
* {golden_brindle}[https://github.com/simonoff/golden_brindle] - tool to
|
|
24
|
+
manage multiple \Unicorn instances/applications on a single server
|
|
25
|
+
|
|
26
|
+
* {raindrops}[http://raindrops.bogomips.org/] - real-time stats for
|
|
27
|
+
preforking Rack servers
|
|
28
|
+
|
|
29
|
+
* {UnXF}[http://bogomips.org/unxf/] Un-X-Forward* the Rack environment,
|
|
30
|
+
useful since unicorn is designed to be deployed behind a reverse proxy.
|
|
31
|
+
|
|
32
|
+
=== \Unicorn is written to work with
|
|
33
|
+
|
|
34
|
+
* {Rack}[http://rack.github.io/] - a minimal interface between webservers
|
|
35
|
+
supporting Ruby and Ruby frameworks
|
|
36
|
+
|
|
37
|
+
* {Ruby}[http://www.ruby-lang.org/] - the programming language of Rack and \Unicorn
|
|
38
|
+
|
|
39
|
+
* {nginx}[http://nginx.org/] - the reverse proxy for use with \Unicorn
|
|
40
|
+
|
|
41
|
+
* {kgio}[http://bogomips.org/kgio/] - the I/O library written for \Unicorn
|
|
42
|
+
|
|
43
|
+
=== Derivatives
|
|
44
|
+
|
|
45
|
+
* {Green Unicorn}[http://gunicorn.org/] - a Python version of \Unicorn
|
|
46
|
+
|
|
47
|
+
* {Rainbows!}[http://rainbows.bogomips.org/] - \Unicorn for sleepy
|
|
48
|
+
apps and slow clients (historical).
|
|
49
|
+
|
|
50
|
+
* {yahns}[http://yahns.yhbt.net/] - like Rainbows!, but with fewer options
|
|
51
|
+
and designed for energy efficiency on idle sites.
|
|
52
|
+
|
|
53
|
+
=== Prior Work
|
|
54
|
+
|
|
55
|
+
* {Mongrel}[http://rubygems.org/gems/mongrel] - the awesome webserver
|
|
56
|
+
unicorn is based on
|
|
57
|
+
|
|
58
|
+
* {david}[http://bogomips.org/david.git] - a tool to explain why you need
|
|
59
|
+
nginx in front of \Unicorn
|
data/PHILOSOPHY
ADDED
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
= The Philosophy Behind unicorn
|
|
2
|
+
|
|
3
|
+
Being a server that only runs on Unix-like platforms, unicorn is
|
|
4
|
+
strongly tied to the Unix philosophy of doing one thing and (hopefully)
|
|
5
|
+
doing it well. Despite using HTTP, unicorn is strictly a _backend_
|
|
6
|
+
application server for running Rack-based Ruby applications.
|
|
7
|
+
|
|
8
|
+
== Avoid Complexity
|
|
9
|
+
|
|
10
|
+
Instead of attempting to be efficient at serving slow clients, unicorn
|
|
11
|
+
relies on a buffering reverse proxy to efficiently deal with slow
|
|
12
|
+
clients.
|
|
13
|
+
|
|
14
|
+
unicorn uses an old-fashioned preforking worker model with blocking I/O.
|
|
15
|
+
Our processing model is the antithesis of more modern (and theoretically
|
|
16
|
+
more efficient) server processing models using threads or non-blocking
|
|
17
|
+
I/O with events.
|
|
18
|
+
|
|
19
|
+
=== Threads and Events Are Hard
|
|
20
|
+
|
|
21
|
+
...to many developers. Reasons for this is beyond the scope of this
|
|
22
|
+
document. unicorn avoids concurrency within each worker process so you
|
|
23
|
+
have fewer things to worry about when developing your application. Of
|
|
24
|
+
course unicorn can use multiple worker processes to utilize multiple
|
|
25
|
+
CPUs or spindles. Applications can still use threads internally, however.
|
|
26
|
+
|
|
27
|
+
== Slow Clients Are Problematic
|
|
28
|
+
|
|
29
|
+
Most benchmarks we've seen don't tell you this, and unicorn doesn't
|
|
30
|
+
care about slow clients... but <i>you</i> should.
|
|
31
|
+
|
|
32
|
+
A "slow client" can be any client outside of your datacenter. Network
|
|
33
|
+
traffic within a local network is always faster than traffic that
|
|
34
|
+
crosses outside of it. The laws of physics do not allow otherwise.
|
|
35
|
+
|
|
36
|
+
Persistent connections were introduced in HTTP/1.1 reduce latency from
|
|
37
|
+
connection establishment and TCP slow start. They also waste server
|
|
38
|
+
resources when clients are idle.
|
|
39
|
+
|
|
40
|
+
Persistent connections mean one of the unicorn worker processes
|
|
41
|
+
(depending on your application, it can be very memory hungry) would
|
|
42
|
+
spend a significant amount of its time idle keeping the connection alive
|
|
43
|
+
<i>and not doing anything else</i>. Being single-threaded and using
|
|
44
|
+
blocking I/O, a worker cannot serve other clients while keeping a
|
|
45
|
+
connection alive. Thus unicorn does not implement persistent
|
|
46
|
+
connections.
|
|
47
|
+
|
|
48
|
+
If your application responses are larger than the socket buffer or if
|
|
49
|
+
you're handling large requests (uploads), worker processes will also be
|
|
50
|
+
bottlenecked by the speed of the *client* connection. You should
|
|
51
|
+
not allow unicorn to serve clients outside of your local network.
|
|
52
|
+
|
|
53
|
+
== Application Concurrency != Network Concurrency
|
|
54
|
+
|
|
55
|
+
Performance is asymmetric across the different subsystems of the machine
|
|
56
|
+
and parts of the network. CPUs and main memory can process gigabytes of
|
|
57
|
+
data in a second; clients on the Internet are usually only capable of a
|
|
58
|
+
tiny fraction of that. unicorn deployments should avoid dealing with
|
|
59
|
+
slow clients directly and instead rely on a reverse proxy to shield it
|
|
60
|
+
from the effects of slow I/O.
|
|
61
|
+
|
|
62
|
+
== Improved Performance Through Reverse Proxying
|
|
63
|
+
|
|
64
|
+
By acting as a buffer to shield unicorn from slow I/O, a reverse proxy
|
|
65
|
+
will inevitably incur overhead in the form of extra data copies.
|
|
66
|
+
However, as I/O within a local network is fast (and faster still
|
|
67
|
+
with local sockets), this overhead is negligible for the vast majority
|
|
68
|
+
of HTTP requests and responses.
|
|
69
|
+
|
|
70
|
+
The ideal reverse proxy complements the weaknesses of unicorn.
|
|
71
|
+
A reverse proxy for unicorn should meet the following requirements:
|
|
72
|
+
|
|
73
|
+
1. It should fully buffer all HTTP requests (and large responses).
|
|
74
|
+
Each request should be "corked" in the reverse proxy and sent
|
|
75
|
+
as fast as possible to the backend unicorn processes. This is
|
|
76
|
+
the most important feature to look for when choosing a
|
|
77
|
+
reverse proxy for unicorn.
|
|
78
|
+
|
|
79
|
+
2. It should spend minimal time in userspace. Network (and disk) I/O
|
|
80
|
+
are system-level tasks and usually managed by the kernel.
|
|
81
|
+
This may change if userspace TCP stacks become more popular in the
|
|
82
|
+
future; but the reverse proxy should not waste time with
|
|
83
|
+
application-level logic. These concerns should be separated
|
|
84
|
+
|
|
85
|
+
3. It should avoid context switches and CPU scheduling overhead.
|
|
86
|
+
In many (most?) cases, network devices and their interrupts are
|
|
87
|
+
only be handled by one CPU at a time. It should avoid contention
|
|
88
|
+
within the system by serializing all network I/O into one (or few)
|
|
89
|
+
userspace processes. Network I/O is not a CPU-intensive task and
|
|
90
|
+
it is not helpful to use multiple CPU cores (at least not for GigE).
|
|
91
|
+
|
|
92
|
+
4. It should efficiently manage persistent connections (and
|
|
93
|
+
pipelining) to slow clients. If you care to serve slow clients
|
|
94
|
+
outside your network, then these features of HTTP/1.1 will help.
|
|
95
|
+
|
|
96
|
+
5. It should (optionally) serve static files. If you have static
|
|
97
|
+
files on your site (especially large ones), they are far more
|
|
98
|
+
efficiently served with as few data copies as possible (e.g. with
|
|
99
|
+
sendfile() to completely avoid copying the data to userspace).
|
|
100
|
+
|
|
101
|
+
nginx is the only (Free) solution we know of that meets the above
|
|
102
|
+
requirements.
|
|
103
|
+
|
|
104
|
+
Indeed, the folks behind unicorn have deployed nginx as a reverse-proxy not
|
|
105
|
+
only for Ruby applications, but also for production applications running
|
|
106
|
+
Apache/mod_perl, Apache/mod_php and Apache Tomcat. In every single
|
|
107
|
+
case, performance improved because application servers were able to use
|
|
108
|
+
backend resources more efficiently and spend less time waiting on slow
|
|
109
|
+
I/O.
|
|
110
|
+
|
|
111
|
+
== Worse Is Better
|
|
112
|
+
|
|
113
|
+
Requirements and scope for applications change frequently and
|
|
114
|
+
drastically. Thus languages like Ruby and frameworks like Rails were
|
|
115
|
+
built to give developers fewer things to worry about in the face of
|
|
116
|
+
rapid change.
|
|
117
|
+
|
|
118
|
+
On the other hand, stable protocols which host your applications (HTTP
|
|
119
|
+
and TCP) only change rarely. This is why we recommend you NOT tie your
|
|
120
|
+
rapidly-changing application logic directly into the processes that deal
|
|
121
|
+
with the stable outside world. Instead, use HTTP as a common RPC
|
|
122
|
+
protocol to communicate between your frontend and backend.
|
|
123
|
+
|
|
124
|
+
In short: separate your concerns.
|
|
125
|
+
|
|
126
|
+
Of course a theoretical "perfect" solution would combine the pieces
|
|
127
|
+
and _maybe_ give you better performance at the end of the day, but
|
|
128
|
+
that is not the Unix way.
|
|
129
|
+
|
|
130
|
+
== Just Worse in Some Cases
|
|
131
|
+
|
|
132
|
+
unicorn is not suited for all applications. unicorn is optimized for
|
|
133
|
+
applications that are CPU/memory/disk intensive and spend little time
|
|
134
|
+
waiting on external resources (e.g. a database server or external API).
|
|
135
|
+
|
|
136
|
+
unicorn is highly inefficient for Comet/reverse-HTTP/push applications
|
|
137
|
+
where the HTTP connection spends a large amount of time idle.
|
|
138
|
+
Nevertheless, the ease of troubleshooting, debugging, and management of
|
|
139
|
+
unicorn may still outweigh the drawbacks for these applications.
|
|
140
|
+
|
|
141
|
+
The {Rainbows!}[http://rainbows.bogomips.org/] aims to fill the gap for
|
|
142
|
+
odd corner cases where the nginx + unicorn combination is not enough.
|
|
143
|
+
While Rainbows! management/administration is largely identical to
|
|
144
|
+
unicorn, Rainbows! is far more ambitious and has seen little real-world
|
|
145
|
+
usage.
|