unicorn 3.6.0 → 4.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +1 -0
- data/.manifest +13 -0
- data/ChangeLog +783 -1
- data/DESIGN +0 -8
- data/Documentation/GNUmakefile +1 -1
- data/GIT-VERSION-FILE +1 -1
- data/GIT-VERSION-GEN +1 -1
- data/GNUmakefile +2 -2
- data/HACKING +11 -0
- data/KNOWN_ISSUES +2 -2
- data/LATEST +24 -24
- data/Links +53 -0
- data/NEWS +66 -0
- data/PHILOSOPHY +49 -49
- data/Sandbox +13 -4
- data/TODO +0 -2
- data/TUNING +31 -9
- data/bin/unicorn +2 -1
- data/bin/unicorn_rails +2 -1
- data/examples/big_app_gc.rb +2 -33
- data/examples/nginx.conf +17 -4
- data/ext/unicorn_http/ext_help.h +16 -0
- data/ext/unicorn_http/extconf.rb +1 -0
- data/ext/unicorn_http/global_variables.h +9 -3
- data/ext/unicorn_http/unicorn_http.c +357 -259
- data/ext/unicorn_http/unicorn_http.rl +148 -50
- data/lib/unicorn/configurator.rb +36 -8
- data/lib/unicorn/const.rb +5 -3
- data/lib/unicorn/http_request.rb +1 -3
- data/lib/unicorn/http_server.rb +82 -95
- data/lib/unicorn/oob_gc.rb +61 -50
- data/lib/unicorn/socket_helper.rb +23 -8
- data/lib/unicorn/worker.rb +45 -4
- data/lib/unicorn.rb +8 -6
- data/script/isolate_for_tests +4 -2
- data/t/broken-app.ru +12 -0
- data/t/heartbeat-timeout.ru +12 -0
- data/t/oob_gc.ru +21 -0
- data/t/oob_gc_path.ru +21 -0
- data/t/t0001-reload-bad-config.sh +1 -0
- data/t/t0002-parser-error.sh +64 -1
- data/t/t0004-heartbeat-timeout.sh +69 -0
- data/t/t0009-broken-app.sh +56 -0
- data/t/t0019-max_header_len.sh +49 -0
- data/t/t0020-at_exit-handler.sh +49 -0
- data/t/t9001-oob_gc.sh +47 -0
- data/t/t9002-oob_gc-path.sh +75 -0
- data/test/benchmark/stack.ru +8 -0
- data/test/unit/test_droplet.rb +28 -0
- data/test/unit/test_http_parser.rb +60 -4
- data/test/unit/test_http_parser_ng.rb +54 -0
- data/test/unit/test_response.rb +1 -1
- data/test/unit/test_server.rb +1 -1
- data/test/unit/test_signals.rb +1 -1
- data/test/unit/test_socket_helper.rb +8 -0
- data/test/unit/test_upload.rb +1 -1
- data/unicorn.gemspec +3 -2
- metadata +44 -16
data/DESIGN
CHANGED
@@ -76,14 +76,6 @@
|
|
76
76
|
Applications that use threads continue to work if Unicorn
|
77
77
|
is only serving LAN or localhost clients.
|
78
78
|
|
79
|
-
* Timeout implementation is done via fchmod(2) in each worker
|
80
|
-
on a shared file descriptor to update st_ctime on the inode.
|
81
|
-
Master process wakeups for checking on timeouts is throttled
|
82
|
-
one a second to minimize the performance impact and simplify
|
83
|
-
the code path within the worker. Neither futimes(2) nor
|
84
|
-
pwrite(2)/pread(2) are supported by base MRI, nor are they as
|
85
|
-
portable on UNIX systems as fchmod(2).
|
86
|
-
|
87
79
|
* SIGKILL is used to terminate the timed-out workers from misbehaving apps
|
88
80
|
as reliably as possible on a UNIX system. The default timeout is a
|
89
81
|
generous 60 seconds (same default as in Mongrel).
|
data/Documentation/GNUmakefile
CHANGED
data/GIT-VERSION-FILE
CHANGED
@@ -1 +1 @@
|
|
1
|
-
GIT_VERSION =
|
1
|
+
GIT_VERSION = 4.0.0
|
data/GIT-VERSION-GEN
CHANGED
data/GNUmakefile
CHANGED
@@ -164,7 +164,7 @@ pkg_extra := GIT-VERSION-FILE ChangeLog LATEST NEWS \
|
|
164
164
|
ChangeLog: GIT-VERSION-FILE .wrongdoc.yml
|
165
165
|
wrongdoc prepare
|
166
166
|
|
167
|
-
.manifest: ChangeLog $(ext)/unicorn_http.c
|
167
|
+
.manifest: ChangeLog $(ext)/unicorn_http.c man
|
168
168
|
(git ls-files && for i in $@ $(pkg_extra); do echo $$i; done) | \
|
169
169
|
LC_ALL=C sort > $@+
|
170
170
|
cmp $@+ $@ || mv $@+ $@
|
@@ -176,7 +176,7 @@ doc: .document $(ext)/unicorn_http.c man html .wrongdoc.yml
|
|
176
176
|
$(RM) -r doc
|
177
177
|
wrongdoc all
|
178
178
|
install -m644 COPYING doc/COPYING
|
179
|
-
install -m644 $(shell grep '^[A-Z]' .document) doc/
|
179
|
+
install -m644 $(shell LC_ALL=C grep '^[A-Z]' .document) doc/
|
180
180
|
install -m644 $(man1_paths) doc/
|
181
181
|
tar cf - $$(git ls-files examples/) | (cd doc && tar xf -)
|
182
182
|
$(RM) $(man1_rdoc)
|
data/HACKING
CHANGED
@@ -107,6 +107,17 @@ git itself. See the Documentation/SubmittingPatches document
|
|
107
107
|
distributed with git on on patch submission guidelines to follow. Just
|
108
108
|
don't email the git mailing list or maintainer with Unicorn patches :)
|
109
109
|
|
110
|
+
== Building a Gem
|
111
|
+
|
112
|
+
In order to build the gem, you must install the following components:
|
113
|
+
|
114
|
+
* wrongdoc
|
115
|
+
* pandoc
|
116
|
+
|
117
|
+
You can build the Unicorn gem with the following command:
|
118
|
+
|
119
|
+
gmake gem
|
120
|
+
|
110
121
|
== Running Development Versions
|
111
122
|
|
112
123
|
It is easy to install the contents of your git working directory:
|
data/KNOWN_ISSUES
CHANGED
@@ -5,13 +5,13 @@ acceptable solution. Those issues are documented here.
|
|
5
5
|
|
6
6
|
* PRNGs (pseudo-random number generators) loaded before forking
|
7
7
|
(e.g. "preload_app true") may need to have their internal state
|
8
|
-
reset in the after_fork hook. Starting with \Unicorn 3.6.
|
8
|
+
reset in the after_fork hook. Starting with \Unicorn 3.6.1, we
|
9
9
|
have builtin workarounds for Kernel#rand and OpenSSL::Random users,
|
10
10
|
but applications may use other PRNGs.
|
11
11
|
|
12
12
|
* Under some versions of Ruby 1.8, it is necessary to call +srand+ in an
|
13
13
|
after_fork hook to get correct random number generation. We have a builtin
|
14
|
-
workaround for this starting with \Unicorn 3.6.
|
14
|
+
workaround for this starting with \Unicorn 3.6.1
|
15
15
|
|
16
16
|
See http://redmine.ruby-lang.org/issues/show/4338
|
17
17
|
|
data/LATEST
CHANGED
@@ -1,32 +1,32 @@
|
|
1
|
-
=== unicorn
|
1
|
+
=== unicorn 4.0.0 - for mythical hardware! / 2011-06-27 09:05 UTC
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
3
|
+
A single Unicorn instance may manage more than 1024 workers
|
4
|
+
without needing privileges to modify resource limits. As a
|
5
|
+
result of this, the "raindrops"[1] gem/library is now a required
|
6
|
+
dependency.
|
6
7
|
|
7
|
-
|
8
|
+
TCP socket defaults now favor low latency to mimic UNIX domain
|
9
|
+
socket behavior (tcp_nodelay: true, tcp_nopush: false). This
|
10
|
+
hurts throughput, users who want to favor throughput should
|
11
|
+
specify "tcp_nodelay: false, tcp_nopush: true" in the listen
|
12
|
+
directive.
|
8
13
|
|
9
|
-
|
10
|
-
|
14
|
+
Error logging is more consistent and all lines should be
|
15
|
+
formatted correctly in backtraces. This may break the
|
16
|
+
behavior of some log parsers.
|
11
17
|
|
12
|
-
|
13
|
-
|
18
|
+
The call stack is smaller and thus easier to examine backtraces
|
19
|
+
when debugging Rack applications.
|
14
20
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
end
|
21
|
+
There are some internal API changes and cleanups, but none that
|
22
|
+
affect applications designed for Rack. See "git log v3.7.0.."
|
23
|
+
for details.
|
19
24
|
|
20
|
-
|
25
|
+
For users who cannot install kgio[2] or raindrops, Unicorn 1.1.x
|
26
|
+
remains supported indefinitely. Unicorn 3.x will remain
|
27
|
+
supported if there is demand. We expect raindrops to introduce
|
28
|
+
fewer portability problems than kgio did, however.
|
21
29
|
|
22
|
-
|
23
|
-
|
24
|
-
make configuration easier especially since the "working_directory"
|
25
|
-
configurator directive exists. Brought up by Matthew Kocher:
|
26
|
-
http://thread.gmane.org/gmane.comp.lang.ruby.unicorn.general/900
|
27
|
-
|
28
|
-
* workers will just die (and restart) if log reopening fails for
|
29
|
-
any reason (including user error). This is to workaround the issue
|
30
|
-
reported by Emmanuel Gomez:
|
31
|
-
http://thread.gmane.org/gmane.comp.lang.ruby.unicorn.general/906
|
30
|
+
[1] http://raindrops.bogomips.org/
|
31
|
+
[2] http://bogomips.org/kgio/
|
32
32
|
|
data/Links
ADDED
@@ -0,0 +1,53 @@
|
|
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:mongrel-unicorn@rubyforge.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
|
+
=== \Unicorn is written to work with
|
30
|
+
|
31
|
+
* {Rack}[http://rack.rubyforge.org/] - a minimal interface between webservers
|
32
|
+
supporting Ruby and Ruby frameworks
|
33
|
+
|
34
|
+
* {Ruby}[http://ruby-lang.org/] - the programming language of Rack and \Unicorn
|
35
|
+
|
36
|
+
* {nginx}[http://nginx.org/] - the reverse proxy for use with \Unicorn
|
37
|
+
|
38
|
+
* {kgio}[http://bogomips.org/kgio/] - the I/O library written for \Unicorn
|
39
|
+
|
40
|
+
=== Derivatives
|
41
|
+
|
42
|
+
* {Green Unicorn}[http://gunicorn.org/] - a Python version of \Unicorn
|
43
|
+
|
44
|
+
* {Rainbows!}[http://rainbows.rubyforge.org/] - \Unicorn for sleepy
|
45
|
+
apps and slow clients.
|
46
|
+
|
47
|
+
=== Prior Work
|
48
|
+
|
49
|
+
* {Mongrel}[http://mongrel.rubyforge.org/] - the awesome webserver \Unicorn is
|
50
|
+
based on
|
51
|
+
|
52
|
+
* {david}[http://bogomips.org/david.git] - a tool to explain why you need
|
53
|
+
nginx in front of \Unicorn
|
data/NEWS
CHANGED
@@ -1,3 +1,69 @@
|
|
1
|
+
=== unicorn 4.0.0 - for mythical hardware! / 2011-06-27 09:05 UTC
|
2
|
+
|
3
|
+
A single Unicorn instance may manage more than 1024 workers
|
4
|
+
without needing privileges to modify resource limits. As a
|
5
|
+
result of this, the "raindrops"[1] gem/library is now a required
|
6
|
+
dependency.
|
7
|
+
|
8
|
+
TCP socket defaults now favor low latency to mimic UNIX domain
|
9
|
+
socket behavior (tcp_nodelay: true, tcp_nopush: false). This
|
10
|
+
hurts throughput, users who want to favor throughput should
|
11
|
+
specify "tcp_nodelay: false, tcp_nopush: true" in the listen
|
12
|
+
directive.
|
13
|
+
|
14
|
+
Error logging is more consistent and all lines should be
|
15
|
+
formatted correctly in backtraces. This may break the
|
16
|
+
behavior of some log parsers.
|
17
|
+
|
18
|
+
The call stack is smaller and thus easier to examine backtraces
|
19
|
+
when debugging Rack applications.
|
20
|
+
|
21
|
+
There are some internal API changes and cleanups, but none that
|
22
|
+
affect applications designed for Rack. See "git log v3.7.0.."
|
23
|
+
for details.
|
24
|
+
|
25
|
+
For users who cannot install kgio[2] or raindrops, Unicorn 1.1.x
|
26
|
+
remains supported indefinitely. Unicorn 3.x will remain
|
27
|
+
supported if there is demand. We expect raindrops to introduce
|
28
|
+
fewer portability problems than kgio did, however.
|
29
|
+
|
30
|
+
[1] http://raindrops.bogomips.org/
|
31
|
+
[2] http://bogomips.org/kgio/
|
32
|
+
|
33
|
+
=== unicorn 3.7.0 - minor feature update / 2011-06-09 20:51 UTC
|
34
|
+
|
35
|
+
* miscellaneous documentation improvements
|
36
|
+
* return 414 (instead of 400) for Request-URI Too Long
|
37
|
+
* strip leading and trailing linear whitespace in header values
|
38
|
+
|
39
|
+
User-visible improvements meant for Rainbows! users:
|
40
|
+
|
41
|
+
* add :ipv6only "listen" option (same as nginx)
|
42
|
+
|
43
|
+
=== unicorn 3.6.2 - fix Unicorn::OobGC module / 2011-04-30 06:40 UTC
|
44
|
+
|
45
|
+
The optional Unicorn::OobGC module is reimplemented to fix
|
46
|
+
breakage that appeared in v3.3.1. There are also minor
|
47
|
+
documentation updates, but no code changes as of 3.6.1 for
|
48
|
+
non-OobGC users.
|
49
|
+
|
50
|
+
There is also a v1.1.7 release to fix the same OobGC breakage
|
51
|
+
that appeared for 1.1.x users in the v1.1.6 release.
|
52
|
+
|
53
|
+
=== unicorn 1.1.7 - major fixes to minor components / 2011-04-30 06:33 UTC
|
54
|
+
|
55
|
+
No changes to the core code, so this release only affects users
|
56
|
+
of the Unicorn::OobGC and Unicorn::ExecCGI modules.
|
57
|
+
Unicorn::OobGC was totally broken by the fix in the v1.1.6
|
58
|
+
release and is now reimplemented. Unicorn::ExecCGI (which
|
59
|
+
hardly anybody uses) now returns proper HTTP status codes.
|
60
|
+
|
61
|
+
=== unicorn 3.6.1 - fix OpenSSL PRNG workaround / 2011-04-26 23:06 UTC
|
62
|
+
|
63
|
+
Our attempt in 3.6.0 to workaround a problem with the OpenSSL
|
64
|
+
PRNG actually made the problem worse. This release corrects the
|
65
|
+
workaround to properly reseed the OpenSSL PRNG after forking.
|
66
|
+
|
1
67
|
=== unicorn 3.6.0 - small fixes, PRNG workarounds / 2011-04-21 06:46 UTC
|
2
68
|
|
3
69
|
Mainly small fixes, improvements, and workarounds for fork() issues
|
data/PHILOSOPHY
CHANGED
@@ -1,17 +1,17 @@
|
|
1
|
-
= The Philosophy Behind
|
1
|
+
= The Philosophy Behind unicorn
|
2
2
|
|
3
|
-
Being a server that only runs on Unix-like platforms,
|
3
|
+
Being a server that only runs on Unix-like platforms, unicorn is
|
4
4
|
strongly tied to the Unix philosophy of doing one thing and (hopefully)
|
5
|
-
doing it well. Despite using HTTP,
|
5
|
+
doing it well. Despite using HTTP, unicorn is strictly a _backend_
|
6
6
|
application server for running Rack-based Ruby applications.
|
7
7
|
|
8
8
|
== Avoid Complexity
|
9
9
|
|
10
|
-
Instead of attempting to be efficient at serving slow clients,
|
10
|
+
Instead of attempting to be efficient at serving slow clients, unicorn
|
11
11
|
relies on a buffering reverse proxy to efficiently deal with slow
|
12
12
|
clients.
|
13
13
|
|
14
|
-
|
14
|
+
unicorn uses an old-fashioned preforking worker model with blocking I/O.
|
15
15
|
Our processing model is the antithesis of more modern (and theoretically
|
16
16
|
more efficient) server processing models using threads or non-blocking
|
17
17
|
I/O with events.
|
@@ -19,14 +19,14 @@ I/O with events.
|
|
19
19
|
=== Threads and Events Are Hard
|
20
20
|
|
21
21
|
...to many developers. Reasons for this is beyond the scope of this
|
22
|
-
document.
|
22
|
+
document. unicorn avoids concurrency within each worker process so you
|
23
23
|
have fewer things to worry about when developing your application. Of
|
24
|
-
course
|
24
|
+
course unicorn can use multiple worker processes to utilize multiple
|
25
25
|
CPUs or spindles. Applications can still use threads internally, however.
|
26
26
|
|
27
27
|
== Slow Clients Are Problematic
|
28
28
|
|
29
|
-
Most benchmarks we've seen don't tell you this, and
|
29
|
+
Most benchmarks we've seen don't tell you this, and unicorn doesn't
|
30
30
|
care about slow clients... but <i>you</i> should.
|
31
31
|
|
32
32
|
A "slow client" can be any client outside of your datacenter. Network
|
@@ -37,71 +37,71 @@ Persistent connections were introduced in HTTP/1.1 reduce latency from
|
|
37
37
|
connection establishment and TCP slow start. They also waste server
|
38
38
|
resources when clients are idle.
|
39
39
|
|
40
|
-
Persistent connections mean one of the
|
40
|
+
Persistent connections mean one of the unicorn worker processes
|
41
41
|
(depending on your application, it can be very memory hungry) would
|
42
42
|
spend a significant amount of its time idle keeping the connection alive
|
43
43
|
<i>and not doing anything else</i>. Being single-threaded and using
|
44
44
|
blocking I/O, a worker cannot serve other clients while keeping a
|
45
|
-
connection alive. Thus
|
45
|
+
connection alive. Thus unicorn does not implement persistent
|
46
46
|
connections.
|
47
47
|
|
48
48
|
If your application responses are larger than the socket buffer or if
|
49
49
|
you're handling large requests (uploads), worker processes will also be
|
50
50
|
bottlenecked by the speed of the *client* connection. You should
|
51
|
-
not allow
|
51
|
+
not allow unicorn to serve clients outside of your local network.
|
52
52
|
|
53
53
|
== Application Concurrency != Network Concurrency
|
54
54
|
|
55
55
|
Performance is asymmetric across the different subsystems of the machine
|
56
56
|
and parts of the network. CPUs and main memory can process gigabytes of
|
57
57
|
data in a second; clients on the Internet are usually only capable of a
|
58
|
-
tiny fraction of that.
|
58
|
+
tiny fraction of that. unicorn deployments should avoid dealing with
|
59
59
|
slow clients directly and instead rely on a reverse proxy to shield it
|
60
60
|
from the effects of slow I/O.
|
61
61
|
|
62
62
|
== Improved Performance Through Reverse Proxying
|
63
63
|
|
64
|
-
By acting as a buffer to shield
|
64
|
+
By acting as a buffer to shield unicorn from slow I/O, a reverse proxy
|
65
65
|
will inevitably incur overhead in the form of extra data copies.
|
66
66
|
However, as I/O within a local network is fast (and faster still
|
67
67
|
with local sockets), this overhead is neglible for the vast majority
|
68
68
|
of HTTP requests and responses.
|
69
69
|
|
70
|
-
The ideal reverse proxy complements the weaknesses of
|
71
|
-
A reverse proxy for
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
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 procceses. 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
100
|
|
101
101
|
nginx is the only (Free) solution we know of that meets the above
|
102
102
|
requirements.
|
103
103
|
|
104
|
-
Indeed, the folks behind
|
104
|
+
Indeed, the folks behind unicorn have deployed nginx as a reverse-proxy not
|
105
105
|
only for Ruby applications, but also for production applications running
|
106
106
|
Apache/mod_perl, Apache/mod_php and Apache Tomcat. In every single
|
107
107
|
case, performance improved because application servers were able to use
|
@@ -129,17 +129,17 @@ that is not the Unix way.
|
|
129
129
|
|
130
130
|
== Just Worse in Some Cases
|
131
131
|
|
132
|
-
|
132
|
+
unicorn is not suited for all applications. unicorn is optimized for
|
133
133
|
applications that are CPU/memory/disk intensive and spend little time
|
134
134
|
waiting on external resources (e.g. a database server or external API).
|
135
135
|
|
136
|
-
|
136
|
+
unicorn is highly inefficient for Comet/reverse-HTTP/push applications
|
137
137
|
where the HTTP connection spends a large amount of time idle.
|
138
138
|
Nevertheless, the ease of troubleshooting, debugging, and management of
|
139
|
-
|
139
|
+
unicorn may still outweigh the drawbacks for these applications.
|
140
140
|
|
141
141
|
The {Rainbows!}[http://rainbows.rubyforge.org/] aims to fill the gap for
|
142
|
-
odd corner cases where the nginx +
|
142
|
+
odd corner cases where the nginx + unicorn combination is not enough.
|
143
143
|
While Rainbows! management/administration is largely identical to
|
144
|
-
|
144
|
+
unicorn, Rainbows! is far more ambitious and has seen little real-world
|
145
145
|
usage.
|
data/Sandbox
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
Since unicorn includes executables and is usually used to start a Ruby
|
4
4
|
process, there are certain caveats to using it with tools that sandbox
|
5
5
|
RubyGems installations such as
|
6
|
-
{Bundler}[http://
|
6
|
+
{Bundler}[http://gembundler.com/] or
|
7
7
|
{Isolate}[http://github.com/jbarnette/isolate].
|
8
8
|
|
9
9
|
== General deployment
|
@@ -45,11 +45,20 @@ This is no longer be an issue as of bundler 0.9.17
|
|
45
45
|
|
46
46
|
ref: http://mid.gmane.org/8FC34B23-5994-41CC-B5AF-7198EF06909E@tramchase.com
|
47
47
|
|
48
|
+
=== BUNDLE_GEMFILE for Capistrano users
|
49
|
+
|
50
|
+
You may need to set or reset the BUNDLE_GEMFILE environment variable in
|
51
|
+
the before_exec hook:
|
52
|
+
|
53
|
+
before_exec do |server|
|
54
|
+
ENV["BUNDLE_GEMFILE"] = "/path/to/app/current/Gemfile"
|
55
|
+
end
|
56
|
+
|
48
57
|
=== Other ENV pollution issues
|
49
58
|
|
50
|
-
|
51
|
-
|
52
|
-
http://gist.github.com/534668
|
59
|
+
If you're using an older Bundler version (0.9.x), you may need to set or
|
60
|
+
reset GEM_HOME, GEM_PATH and PATH environment variables in the
|
61
|
+
before_exec hook as illustrated by http://gist.github.com/534668
|
53
62
|
|
54
63
|
== Isolate
|
55
64
|
|
data/TODO
CHANGED
data/TUNING
CHANGED
@@ -1,12 +1,34 @@
|
|
1
|
-
= Tuning Unicorn
|
1
|
+
= Tuning \Unicorn
|
2
2
|
|
3
|
-
Unicorn performance is generally as good as a (mostly) Ruby web server
|
3
|
+
\Unicorn performance is generally as good as a (mostly) Ruby web server
|
4
4
|
can provide. Most often the performance bottleneck is in the web
|
5
5
|
application running on Unicorn rather than Unicorn itself.
|
6
6
|
|
7
|
-
== Unicorn Configuration
|
7
|
+
== \Unicorn Configuration
|
8
8
|
|
9
9
|
See Unicorn::Configurator for details on the config file format.
|
10
|
+
+worker_processes+ is the most-commonly needed tuning parameter.
|
11
|
+
|
12
|
+
=== Unicorn::Configurator#worker_processes
|
13
|
+
|
14
|
+
* worker_processes should be scaled to the number of processes your
|
15
|
+
backend system(s) can support. DO NOT scale it to the number of
|
16
|
+
external network clients your application expects to be serving.
|
17
|
+
\Unicorn is NOT for serving slow clients, that is the job of nginx.
|
18
|
+
|
19
|
+
* worker_processes should be *at* *least* the number of CPU cores on
|
20
|
+
a dedicated server. If your application has occasionally slow
|
21
|
+
responses that are /not/ CPU-intensive, you may increase this to
|
22
|
+
workaround those inefficiencies.
|
23
|
+
|
24
|
+
* worker_processes may be increased for Unicorn::OobGC users to provide
|
25
|
+
more consistent response times.
|
26
|
+
|
27
|
+
* Never, ever, increase worker_processes to the point where the system
|
28
|
+
runs out of physical memory and hits swap. Production servers should
|
29
|
+
never see heavy swap activity.
|
30
|
+
|
31
|
+
=== Unicorn::Configurator#listen Options
|
10
32
|
|
11
33
|
* Setting a very low value for the :backlog parameter in "listen"
|
12
34
|
directives can allow failover to happen more quickly if your
|
@@ -30,6 +52,11 @@ See Unicorn::Configurator for details on the config file format.
|
|
30
52
|
and may also thrash CPU caches, cancelling out performance gains
|
31
53
|
one would normally expect.
|
32
54
|
|
55
|
+
* UNIX domain sockets are slighly faster than TCP sockets, but only
|
56
|
+
work if nginx is on the same machine.
|
57
|
+
|
58
|
+
== Other \Unicorn settings
|
59
|
+
|
33
60
|
* Setting "preload_app true" can allow copy-on-write-friendly GC to
|
34
61
|
be used to save memory. It will probably not work out of the box with
|
35
62
|
applications that open sockets or perform random I/O on files.
|
@@ -40,12 +67,7 @@ See Unicorn::Configurator for details on the config file format.
|
|
40
67
|
* On POSIX-compliant filesystems, it is safe for multiple threads or
|
41
68
|
processes to append to one log file as long as all the processes are
|
42
69
|
have them unbuffered (File#sync = true) or they are
|
43
|
-
record(line)-buffered in userspace.
|
44
|
-
|
45
|
-
* worker_processes should be scaled to the number of processes your
|
46
|
-
backend system(s) can support. DO NOT scale it to the number of
|
47
|
-
external network clients your application expects to be serving.
|
48
|
-
Unicorn is NOT for serving slow clients, that is the job of nginx.
|
70
|
+
record(line)-buffered in userspace before any writes.
|
49
71
|
|
50
72
|
== Kernel Parameters (Linux sysctl)
|
51
73
|
|
data/bin/unicorn
CHANGED
@@ -106,6 +106,7 @@ op = OptionParser.new("", 24, ' ') do |opts|
|
|
106
106
|
end
|
107
107
|
|
108
108
|
app = Unicorn.builder(ARGV[0] || 'config.ru', op)
|
109
|
+
op = nil
|
109
110
|
|
110
111
|
if $DEBUG
|
111
112
|
require 'pp'
|
@@ -117,4 +118,4 @@ if $DEBUG
|
|
117
118
|
end
|
118
119
|
|
119
120
|
Unicorn::Launcher.daemonize!(options) if rackup_opts[:daemonize]
|
120
|
-
Unicorn.
|
121
|
+
Unicorn::HttpServer.new(app, options).start.join
|
data/bin/unicorn_rails
CHANGED
@@ -186,6 +186,7 @@ def rails_builder(ru, op, daemonize)
|
|
186
186
|
end
|
187
187
|
|
188
188
|
app = rails_builder(ARGV[0], op, rackup_opts[:daemonize])
|
189
|
+
op = nil
|
189
190
|
|
190
191
|
if $DEBUG
|
191
192
|
require 'pp'
|
@@ -205,4 +206,4 @@ if rackup_opts[:daemonize]
|
|
205
206
|
options[:pid] = "tmp/pids/unicorn.pid"
|
206
207
|
Unicorn::Launcher.daemonize!(options)
|
207
208
|
end
|
208
|
-
Unicorn.
|
209
|
+
Unicorn::HttpServer.new(app, options).start.join
|
data/examples/big_app_gc.rb
CHANGED
@@ -1,33 +1,2 @@
|
|
1
|
-
#
|
2
|
-
#
|
3
|
-
# You could customize this patch to read REQ["PATH_INFO"] and only
|
4
|
-
# call GC.start after expensive requests.
|
5
|
-
#
|
6
|
-
# We could have this wrap the response body.close as middleware, but the
|
7
|
-
# scannable stack is would still be bigger than it would be here.
|
8
|
-
#
|
9
|
-
# This shouldn't hurt overall performance as long as the server cluster
|
10
|
-
# is at <=50% CPU capacity, and improves the performance of most memory
|
11
|
-
# intensive requests. This serves to improve _client-visible_
|
12
|
-
# performance (possibly at the cost of overall performance).
|
13
|
-
#
|
14
|
-
# We'll call GC after each request is been written out to the socket, so
|
15
|
-
# the client never sees the extra GC hit it. It's ideal to call the GC
|
16
|
-
# inside the HTTP server (vs middleware or hooks) since the stack is
|
17
|
-
# smaller at this point, so the GC will both be faster and more
|
18
|
-
# effective at releasing unused memory.
|
19
|
-
#
|
20
|
-
# This monkey patch is _only_ effective for applications that use a lot
|
21
|
-
# of memory, and will hurt simpler apps/endpoints that can process
|
22
|
-
# multiple requests before incurring GC.
|
23
|
-
|
24
|
-
class Unicorn::HttpServer
|
25
|
-
REQ = Unicorn::HttpRequest::REQ
|
26
|
-
alias _process_client process_client
|
27
|
-
undef_method :process_client
|
28
|
-
def process_client(client)
|
29
|
-
_process_client(client)
|
30
|
-
REQ.clear
|
31
|
-
GC.start
|
32
|
-
end
|
33
|
-
end if defined?(Unicorn)
|
1
|
+
# see {Unicorn::OobGC}[http://unicorn.bogomips.org/Unicorn/OobGC.html]
|
2
|
+
# Unicorn::OobGC was broken in Unicorn v3.3.1 - v3.6.1 and fixed in v3.6.2
|
data/examples/nginx.conf
CHANGED
@@ -87,6 +87,14 @@ http {
|
|
87
87
|
# listen 80 default deferred; # for Linux
|
88
88
|
# listen 80 default accept_filter=httpready; # for FreeBSD
|
89
89
|
|
90
|
+
# If you have IPv6, you'll likely want to have two separate listeners.
|
91
|
+
# One on IPv4 only (the default), and another on IPv6 only instead
|
92
|
+
# of a single dual-stack listener. A dual-stack listener will make
|
93
|
+
# for ugly IPv4 addresses in $remote_addr (e.g ":ffff:10.0.0.1"
|
94
|
+
# instead of just "10.0.0.1") and potentially trigger bugs in
|
95
|
+
# some software.
|
96
|
+
# listen [::]:80 ipv6only=on; # deferred or accept_filter recommended
|
97
|
+
|
90
98
|
client_max_body_size 4G;
|
91
99
|
server_name _;
|
92
100
|
|
@@ -125,10 +133,15 @@ http {
|
|
125
133
|
proxy_redirect off;
|
126
134
|
|
127
135
|
# set "proxy_buffering off" *only* for Rainbows! when doing
|
128
|
-
# Comet/long-poll
|
129
|
-
#
|
130
|
-
#
|
131
|
-
# clients,
|
136
|
+
# Comet/long-poll/streaming. It's also safe to set if you're using
|
137
|
+
# only serving fast clients with Unicorn + nginx, but not slow
|
138
|
+
# clients. You normally want nginx to buffer responses to slow
|
139
|
+
# clients, even with Rails 3.1 streaming because otherwise a slow
|
140
|
+
# client can become a bottleneck of Unicorn.
|
141
|
+
#
|
142
|
+
# The Rack application may also set "X-Accel-Buffering (yes|no)"
|
143
|
+
# in the response headers do disable/enable buffering on a
|
144
|
+
# per-response basis.
|
132
145
|
# proxy_buffering off;
|
133
146
|
|
134
147
|
proxy_pass http://app_server;
|