unicorn 3.6.0 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. data/.document +1 -0
  2. data/.manifest +13 -0
  3. data/ChangeLog +783 -1
  4. data/DESIGN +0 -8
  5. data/Documentation/GNUmakefile +1 -1
  6. data/GIT-VERSION-FILE +1 -1
  7. data/GIT-VERSION-GEN +1 -1
  8. data/GNUmakefile +2 -2
  9. data/HACKING +11 -0
  10. data/KNOWN_ISSUES +2 -2
  11. data/LATEST +24 -24
  12. data/Links +53 -0
  13. data/NEWS +66 -0
  14. data/PHILOSOPHY +49 -49
  15. data/Sandbox +13 -4
  16. data/TODO +0 -2
  17. data/TUNING +31 -9
  18. data/bin/unicorn +2 -1
  19. data/bin/unicorn_rails +2 -1
  20. data/examples/big_app_gc.rb +2 -33
  21. data/examples/nginx.conf +17 -4
  22. data/ext/unicorn_http/ext_help.h +16 -0
  23. data/ext/unicorn_http/extconf.rb +1 -0
  24. data/ext/unicorn_http/global_variables.h +9 -3
  25. data/ext/unicorn_http/unicorn_http.c +357 -259
  26. data/ext/unicorn_http/unicorn_http.rl +148 -50
  27. data/lib/unicorn/configurator.rb +36 -8
  28. data/lib/unicorn/const.rb +5 -3
  29. data/lib/unicorn/http_request.rb +1 -3
  30. data/lib/unicorn/http_server.rb +82 -95
  31. data/lib/unicorn/oob_gc.rb +61 -50
  32. data/lib/unicorn/socket_helper.rb +23 -8
  33. data/lib/unicorn/worker.rb +45 -4
  34. data/lib/unicorn.rb +8 -6
  35. data/script/isolate_for_tests +4 -2
  36. data/t/broken-app.ru +12 -0
  37. data/t/heartbeat-timeout.ru +12 -0
  38. data/t/oob_gc.ru +21 -0
  39. data/t/oob_gc_path.ru +21 -0
  40. data/t/t0001-reload-bad-config.sh +1 -0
  41. data/t/t0002-parser-error.sh +64 -1
  42. data/t/t0004-heartbeat-timeout.sh +69 -0
  43. data/t/t0009-broken-app.sh +56 -0
  44. data/t/t0019-max_header_len.sh +49 -0
  45. data/t/t0020-at_exit-handler.sh +49 -0
  46. data/t/t9001-oob_gc.sh +47 -0
  47. data/t/t9002-oob_gc-path.sh +75 -0
  48. data/test/benchmark/stack.ru +8 -0
  49. data/test/unit/test_droplet.rb +28 -0
  50. data/test/unit/test_http_parser.rb +60 -4
  51. data/test/unit/test_http_parser_ng.rb +54 -0
  52. data/test/unit/test_response.rb +1 -1
  53. data/test/unit/test_server.rb +1 -1
  54. data/test/unit/test_signals.rb +1 -1
  55. data/test/unit/test_socket_helper.rb +8 -0
  56. data/test/unit/test_upload.rb +1 -1
  57. data/unicorn.gemspec +3 -2
  58. 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).
@@ -1,7 +1,7 @@
1
1
  all::
2
2
 
3
3
  PANDOC = pandoc
4
- PANDOC_OPTS = -f markdown --email-obfuscation=none --sanitize-html
4
+ PANDOC_OPTS = -f markdown --email-obfuscation=none
5
5
  pandoc = $(PANDOC) $(PANDOC_OPTS)
6
6
  pandoc_html = $(pandoc) --toc -t html --no-wrap
7
7
 
data/GIT-VERSION-FILE CHANGED
@@ -1 +1 @@
1
- GIT_VERSION = 3.6.0
1
+ GIT_VERSION = 4.0.0
data/GIT-VERSION-GEN CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/bin/sh
2
2
 
3
3
  GVF=GIT-VERSION-FILE
4
- DEF_VER=v3.6.0.GIT
4
+ DEF_VER=v4.0.0.GIT
5
5
 
6
6
  LF='
7
7
  '
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.0, we
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.0
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 3.6.0 - small fixes, PRNG workarounds / 2011-04-21 06:46 UTC
1
+ === unicorn 4.0.0 - for mythical hardware! / 2011-06-27 09:05 UTC
2
2
 
3
- Mainly small fixes, improvements, and workarounds for fork() issues
4
- with pseudo-random number generators shipped with Ruby (Kernel#rand,
5
- OpenSSL::Random (used by SecureRandom and also by Rails).
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
- The PRNG issues are documented in depth here (and links to Ruby Redmine):
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
- http://bogomips.org/unicorn.git/commit?id=1107ede7
10
- http://bogomips.org/unicorn.git/commit?id=b3241621
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
- If you're too lazy to upgrade, you can just do this in your after_fork
13
- hooks:
18
+ The call stack is smaller and thus easier to examine backtraces
19
+ when debugging Rack applications.
14
20
 
15
- after_fork do |server,worker|
16
- tmp = srand
17
- OpenSSL::Random.seed(tmp.to_s) if defined?(OpenSSL::Random)
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
- There are also small log reopening (SIGUSR1) improvements:
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
- * relative paths may also be reopened, there's a small chance this
23
- will break with a handful of setups, but unlikely. This should
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 Unicorn
1
+ = The Philosophy Behind unicorn
2
2
 
3
- Being a server that only runs on Unix-like platforms, Unicorn is
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, Unicorn is strictly a _backend_
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, Unicorn
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
- Unicorn uses an old-fashioned preforking worker model with blocking I/O.
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. Unicorn avoids concurrency within each worker process so you
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 Unicorn can use multiple worker processes to utilize multiple
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 Unicorn doesn't
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 Unicorn worker processes
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 Unicorn does not implement persistent
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 Unicorn to serve clients outside of your local network.
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. Unicorn deployments should avoid dealing with
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 Unicorn from slow I/O, a reverse proxy
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 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).
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 Unicorn have deployed nginx as a reverse-proxy not
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
- Unicorn is not suited for all applications. Unicorn is optimized for
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
- Unicorn is highly inefficient for Comet/reverse-HTTP/push applications
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
- Unicorn may still outweigh the drawbacks for these applications.
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 + Unicorn combination is not enough.
142
+ odd corner cases where the nginx + unicorn combination is not enough.
143
143
  While Rainbows! management/administration is largely identical to
144
- Unicorn, Rainbows! is far more ambitious and has seen little real-world
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://github.com/carlhuda/bundler] or
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
- You may need to set or reset BUNDLE_GEMFILE, GEM_HOME, GEM_PATH and PATH
51
- environment variables in the before_exec hook as illustrated by
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
@@ -2,6 +2,4 @@
2
2
 
3
3
  * improve test suite
4
4
 
5
- * scalability to >= 1024 worker processes for crazy NUMA systems
6
-
7
5
  * Rack 2.x support (when Rack 2.x exists)
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.run(app, options)
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.run(app, options)
209
+ Unicorn::HttpServer.new(app, options).start.join
@@ -1,33 +1,2 @@
1
- # Run GC after every request, before attempting to accept more connections.
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 stuff. It's also safe to set if you're
129
- # using only serving fast clients with Unicorn + nginx.
130
- # Otherwise you _want_ nginx to buffer responses to slow
131
- # clients, really.
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;