unicorn 4.7.0 → 6.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.document +0 -1
- data/.gitattributes +5 -0
- data/.gitignore +2 -2
- data/.manifest +14 -21
- data/.olddoc.yml +22 -0
- data/Application_Timeouts +7 -7
- data/DESIGN +2 -4
- data/Documentation/.gitignore +1 -3
- data/Documentation/unicorn.1 +222 -0
- data/Documentation/unicorn_rails.1 +207 -0
- data/FAQ +23 -6
- data/GIT-VERSION-FILE +1 -1
- data/GIT-VERSION-GEN +1 -1
- data/GNUmakefile +139 -92
- data/HACKING +13 -28
- data/ISSUES +82 -19
- data/KNOWN_ISSUES +18 -18
- data/LATEST +22 -44
- data/LICENSE +2 -2
- data/Links +24 -22
- data/NEWS +729 -0
- data/PHILOSOPHY +0 -6
- data/README +50 -48
- data/Rakefile +0 -44
- data/SIGNALS +12 -3
- data/Sandbox +11 -10
- data/TODO +0 -2
- data/TUNING +30 -9
- data/archive/.gitignore +3 -0
- data/archive/slrnpull.conf +4 -0
- data/bin/unicorn +4 -2
- data/bin/unicorn_rails +3 -3
- data/examples/big_app_gc.rb +1 -1
- data/examples/init.sh +36 -8
- data/examples/logrotate.conf +17 -2
- data/examples/nginx.conf +14 -14
- data/examples/unicorn.conf.minimal.rb +2 -2
- data/examples/unicorn.conf.rb +14 -6
- data/examples/unicorn.socket +11 -0
- data/examples/unicorn@.service +40 -0
- data/ext/unicorn_http/common_field_optimization.h +23 -5
- data/ext/unicorn_http/ext_help.h +0 -20
- data/ext/unicorn_http/extconf.rb +37 -1
- data/ext/unicorn_http/global_variables.h +1 -1
- data/ext/unicorn_http/httpdate.c +2 -2
- data/ext/unicorn_http/unicorn_http.c +940 -644
- data/ext/unicorn_http/unicorn_http.rl +167 -170
- data/ext/unicorn_http/unicorn_http_common.rl +1 -1
- data/lib/unicorn/configurator.rb +110 -46
- data/lib/unicorn/const.rb +2 -25
- data/lib/unicorn/http_request.rb +110 -31
- data/lib/unicorn/http_response.rb +17 -31
- data/lib/unicorn/http_server.rb +292 -199
- data/lib/unicorn/launcher.rb +1 -1
- data/lib/unicorn/oob_gc.rb +16 -6
- data/lib/unicorn/socket_helper.rb +58 -78
- data/lib/unicorn/stream_input.rb +9 -11
- data/lib/unicorn/tee_input.rb +16 -11
- data/lib/unicorn/tmpio.rb +10 -6
- data/lib/unicorn/util.rb +5 -4
- data/lib/unicorn/version.rb +1 -1
- data/lib/unicorn/worker.rb +99 -22
- data/lib/unicorn.rb +69 -42
- data/man/man1/unicorn.1 +124 -122
- data/man/man1/unicorn_rails.1 +113 -127
- data/t/.gitignore +0 -1
- data/t/GNUmakefile +3 -80
- data/t/README +4 -4
- data/t/t0002-parser-error.sh +3 -3
- data/t/t0011-active-unix-socket.sh +1 -1
- data/t/t0012-reload-empty-config.sh +2 -1
- data/t/t0300-no-default-middleware.sh +6 -1
- data/t/t0301-no-default-middleware-ignored-in-config.sh +25 -0
- data/t/t0301.ru +13 -0
- data/t/test-lib.sh +2 -2
- data/test/benchmark/README +14 -4
- data/test/benchmark/ddstream.ru +50 -0
- data/test/benchmark/readinput.ru +40 -0
- data/test/benchmark/uconnect.perl +66 -0
- data/test/exec/test_exec.rb +74 -20
- data/test/test_helper.rb +42 -33
- data/test/unit/test_ccc.rb +91 -0
- data/test/unit/test_droplet.rb +1 -1
- data/test/unit/test_http_parser.rb +49 -19
- data/test/unit/test_http_parser_ng.rb +98 -115
- data/test/unit/test_request.rb +11 -11
- data/test/unit/test_response.rb +31 -19
- data/test/unit/test_server.rb +89 -15
- data/test/unit/test_signals.rb +9 -9
- data/test/unit/test_socket_helper.rb +20 -14
- data/test/unit/test_tee_input.rb +10 -0
- data/test/unit/test_upload.rb +10 -15
- data/test/unit/test_util.rb +28 -3
- data/unicorn.gemspec +28 -23
- data/unicorn_1 +1 -0
- data/unicorn_rails_1 +1 -0
- metadata +64 -134
- data/.wrongdoc.yml +0 -10
- data/ChangeLog +0 -4694
- data/Documentation/GNUmakefile +0 -30
- data/Documentation/unicorn.1.txt +0 -178
- data/Documentation/unicorn_rails.1.txt +0 -175
- data/examples/git.ru +0 -13
- data/lib/unicorn/app/exec_cgi.rb +0 -154
- data/lib/unicorn/app/inetd.rb +0 -109
- data/lib/unicorn/ssl_client.rb +0 -11
- data/lib/unicorn/ssl_configurator.rb +0 -104
- data/lib/unicorn/ssl_server.rb +0 -42
- data/local.mk.sample +0 -59
- data/script/isolate_for_tests +0 -32
- data/t/hijack.ru +0 -42
- data/t/sslgen.sh +0 -71
- data/t/t0016-trust-x-forwarded-false.sh +0 -30
- data/t/t0017-trust-x-forwarded-true.sh +0 -30
- data/t/t0200-rack-hijack.sh +0 -27
- data/t/t0600-https-server-basic.sh +0 -48
- data/test/unit/test_http_parser_xftrust.rb +0 -38
- data/test/unit/test_sni_hostnames.rb +0 -47
data/PHILOSOPHY
CHANGED
@@ -137,9 +137,3 @@ 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
|
-
|
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.
|
143
|
-
While Rainbows! management/administration is largely identical to
|
144
|
-
unicorn, Rainbows! is far more ambitious and has seen little real-world
|
145
|
-
usage.
|
data/README
CHANGED
@@ -1,22 +1,23 @@
|
|
1
|
-
=
|
1
|
+
= unicorn: Rack HTTP server for fast clients and Unix
|
2
2
|
|
3
|
-
|
3
|
+
unicorn is an HTTP server for Rack applications designed to only serve
|
4
4
|
fast clients on low-latency, high-bandwidth connections and take
|
5
5
|
advantage of features in Unix/Unix-like kernels. Slow clients should
|
6
6
|
only be served by placing a reverse proxy capable of fully buffering
|
7
|
-
both the the request and response in between
|
7
|
+
both the the request and response in between unicorn and slow clients.
|
8
8
|
|
9
9
|
== Features
|
10
10
|
|
11
11
|
* Designed for Rack, Unix, fast clients, and ease-of-debugging. We
|
12
12
|
cut out everything that is better supported by the operating system,
|
13
|
-
{nginx}[
|
13
|
+
{nginx}[https://nginx.org/] or {Rack}[https://rack.github.io/].
|
14
14
|
|
15
|
-
* Compatible with
|
15
|
+
* Compatible with Ruby 1.9.3 and later.
|
16
|
+
unicorn 4.x remains supported for Ruby 1.8 users.
|
16
17
|
|
17
|
-
* Process management:
|
18
|
+
* Process management: unicorn will reap and restart workers that
|
18
19
|
die from broken apps. There is no need to manage multiple processes
|
19
|
-
or ports yourself.
|
20
|
+
or ports yourself. unicorn can spawn and manage any number of
|
20
21
|
worker processes you choose to scale to your backend.
|
21
22
|
|
22
23
|
* Load balancing is done entirely by the operating system kernel.
|
@@ -26,25 +27,25 @@ both the the request and response in between \Unicorn and slow clients.
|
|
26
27
|
all run within their own isolated address space and only serve one
|
27
28
|
client at a time for maximum robustness.
|
28
29
|
|
29
|
-
* Supports all Rack applications, along with pre-Rack versions of
|
30
|
-
Ruby on Rails via a Rack wrapper.
|
31
|
-
|
32
30
|
* Builtin reopening of all log files in your application via
|
33
31
|
USR1 signal. This allows logrotate to rotate files atomically and
|
34
32
|
quickly via rename instead of the racy and slow copytruncate method.
|
35
|
-
|
33
|
+
unicorn also takes steps to ensure multi-line log entries from one
|
36
34
|
request all stay within the same file.
|
37
35
|
|
38
36
|
* nginx-style binary upgrades without losing connections.
|
39
|
-
You can upgrade
|
37
|
+
You can upgrade unicorn, your entire application, libraries
|
40
38
|
and even your Ruby interpreter without dropping clients.
|
41
39
|
|
40
|
+
* transparent upgrades using systemd socket activation is
|
41
|
+
supported since unicorn 5.0
|
42
|
+
|
42
43
|
* before_fork and after_fork hooks in case your application
|
43
44
|
has special needs when dealing with forked processes. These
|
44
45
|
should not be needed when the "preload_app" directive is
|
45
46
|
false (the default).
|
46
47
|
|
47
|
-
* Can be used with copy-on-write-friendly
|
48
|
+
* Can be used with copy-on-write-friendly GC in Ruby 2.0+
|
48
49
|
to save memory (by setting "preload_app" to true).
|
49
50
|
|
50
51
|
* Able to listen on multiple interfaces including UNIX sockets,
|
@@ -53,98 +54,99 @@ both the the request and response in between \Unicorn and slow clients.
|
|
53
54
|
|
54
55
|
* Simple and easy Ruby DSL for configuration.
|
55
56
|
|
56
|
-
* Decodes chunked
|
57
|
-
notification to be implemented as well as being able to tunnel
|
58
|
-
arbitrary stream-based protocols over HTTP.
|
57
|
+
* Decodes chunked requests on-the-fly.
|
59
58
|
|
60
59
|
== License
|
61
60
|
|
62
|
-
|
61
|
+
unicorn is copyright 2009-2018 by all contributors (see logs in git).
|
63
62
|
It is based on Mongrel 1.1.5.
|
64
63
|
Mongrel is copyright 2007 Zed A. Shaw and contributors.
|
65
64
|
|
66
|
-
|
65
|
+
unicorn is licensed under (your choice) of the GPLv2 or later
|
67
66
|
(GPLv3+ preferred), or Ruby (1.8)-specific terms.
|
68
67
|
See the included LICENSE file for details.
|
69
68
|
|
70
|
-
|
69
|
+
unicorn is 100% Free Software (including all development tools used).
|
71
70
|
|
72
71
|
== Install
|
73
72
|
|
74
73
|
The library consists of a C extension so you'll need a C compiler
|
75
74
|
and Ruby development libraries/headers.
|
76
75
|
|
77
|
-
You may
|
78
|
-
and run setup.rb after unpacking it:
|
79
|
-
|
80
|
-
http://rubyforge.org/frs/?group_id=1306
|
81
|
-
|
82
|
-
You may also install it via RubyGems on RubyGems.org:
|
76
|
+
You may install it via RubyGems on RubyGems.org:
|
83
77
|
|
84
78
|
gem install unicorn
|
85
79
|
|
86
80
|
You can get the latest source via git from the following locations
|
87
81
|
(these versions may not be stable):
|
88
82
|
|
89
|
-
|
90
|
-
|
83
|
+
https://yhbt.net/unicorn.git
|
84
|
+
https://repo.or.cz/unicorn.git (mirror)
|
91
85
|
|
92
|
-
You may browse the code from the web
|
93
|
-
tarballs here:
|
86
|
+
You may browse the code from the web:
|
94
87
|
|
95
|
-
*
|
96
|
-
*
|
88
|
+
* https://yhbt.net/unicorn.git
|
89
|
+
* https://repo.or.cz/w/unicorn.git (gitweb)
|
97
90
|
|
98
91
|
See the HACKING guide on how to contribute and build prerelease gems
|
99
92
|
from git.
|
100
93
|
|
101
94
|
== Usage
|
102
95
|
|
103
|
-
===
|
96
|
+
=== Rack (including Rails 3+) applications
|
104
97
|
|
105
98
|
In APP_ROOT, run:
|
106
99
|
|
107
100
|
unicorn
|
108
101
|
|
109
|
-
|
110
|
-
|
111
|
-
In RAILS_ROOT, run:
|
112
|
-
|
113
|
-
unicorn_rails
|
114
|
-
|
115
|
-
\Unicorn will bind to all interfaces on TCP port 8080 by default.
|
102
|
+
unicorn will bind to all interfaces on TCP port 8080 by default.
|
116
103
|
You may use the +--listen/-l+ switch to bind to a different
|
117
104
|
address:port or a UNIX socket.
|
118
105
|
|
119
106
|
=== Configuration File(s)
|
120
107
|
|
121
|
-
|
108
|
+
unicorn will look for the config.ru file used by rackup in APP_ROOT.
|
122
109
|
|
123
|
-
For deployments, it can use a config file for
|
110
|
+
For deployments, it can use a config file for unicorn-specific options
|
124
111
|
specified by the +--config-file/-c+ command-line switch. See
|
125
|
-
Unicorn::Configurator for the syntax of the
|
112
|
+
Unicorn::Configurator for the syntax of the unicorn-specific options.
|
126
113
|
The default settings are designed for maximum out-of-the-box
|
127
114
|
compatibility with existing applications.
|
128
115
|
|
129
116
|
Most command-line options for other Rack applications (above) are also
|
130
|
-
supported. Run `unicorn -h`
|
131
|
-
options.
|
117
|
+
supported. Run `unicorn -h` to see command-line options.
|
132
118
|
|
133
119
|
== Disclaimer
|
134
120
|
|
135
121
|
There is NO WARRANTY whatsoever if anything goes wrong, but
|
136
122
|
{let us know}[link:ISSUES.html] and we'll try our best to fix it.
|
137
123
|
|
138
|
-
|
124
|
+
unicorn is designed to only serve fast clients either on the local host
|
139
125
|
or a fast LAN. See the PHILOSOPHY and DESIGN documents for more details
|
140
126
|
regarding this.
|
141
127
|
|
128
|
+
Due to its ability to tolerate crashes and isolate clients, unicorn
|
129
|
+
is unfortunately known to prolong the existence of bugs in applications
|
130
|
+
and libraries which run on top of it.
|
131
|
+
|
142
132
|
== Contact
|
143
133
|
|
144
134
|
All feedback (bug reports, user/development dicussion, patches, pull
|
145
135
|
requests) go to the mailing list/newsgroup. See the ISSUES document for
|
146
|
-
information on the {mailing list}[mailto:
|
136
|
+
information on the {mailing list}[mailto:unicorn-public@yhbt.net].
|
137
|
+
|
138
|
+
The mailing list is archived at https://yhbt.net/unicorn-public/
|
139
|
+
|
140
|
+
Read-only NNTP access is available at:
|
141
|
+
nntp://news.public-inbox.org/inbox.comp.lang.ruby.unicorn and
|
142
|
+
nntp://news.gmane.io/gmane.comp.lang.ruby.unicorn.general
|
143
|
+
|
144
|
+
Read-only IMAP access is also avaialble at:
|
145
|
+
imaps://news.public-inbox.org/inbox.comp.lang.ruby.unicorn.0 and
|
146
|
+
imap://ou63pmih66umazou.onion/inbox.comp.lang.ruby.unicorn.0
|
147
|
+
AUTH=ANONYMOUS mechanism is supported, as is any username+password
|
148
|
+
combination.
|
147
149
|
|
148
|
-
For the latest on
|
149
|
-
unicorn@
|
150
|
+
For the latest on unicorn releases, you may also finger us at
|
151
|
+
unicorn@yhbt.net or check our NEWS page (and subscribe to our Atom
|
150
152
|
feed).
|
data/Rakefile
CHANGED
@@ -1,47 +1,3 @@
|
|
1
|
-
# -*- encoding: binary -*-
|
2
|
-
autoload :Gem, 'rubygems'
|
3
|
-
require 'wrongdoc'
|
4
|
-
|
5
|
-
cgit_url = Wrongdoc.config[:cgit_url]
|
6
|
-
git_url = Wrongdoc.config[:git_url]
|
7
|
-
|
8
|
-
desc "post to FM"
|
9
|
-
task :fm_update do
|
10
|
-
require 'tempfile'
|
11
|
-
require 'net/http'
|
12
|
-
require 'net/netrc'
|
13
|
-
require 'json'
|
14
|
-
version = ENV['VERSION'] or abort "VERSION= needed"
|
15
|
-
uri = URI.parse('https://freecode.com/projects/unicorn/releases.json')
|
16
|
-
rc = Net::Netrc.locate('unicorn-fm') or abort "~/.netrc not found"
|
17
|
-
api_token = rc.password
|
18
|
-
_, subject, body = `git cat-file tag v#{version}`.split(/\n\n/, 3)
|
19
|
-
tmp = Tempfile.new('fm-changelog')
|
20
|
-
tmp.puts subject
|
21
|
-
tmp.puts
|
22
|
-
tmp.puts body
|
23
|
-
tmp.flush
|
24
|
-
system(ENV["VISUAL"], tmp.path) or abort "#{ENV["VISUAL"]} failed: #$?"
|
25
|
-
changelog = File.read(tmp.path).strip
|
26
|
-
|
27
|
-
req = {
|
28
|
-
"auth_code" => api_token,
|
29
|
-
"release" => {
|
30
|
-
"tag_list" => "Experimental",
|
31
|
-
"version" => version,
|
32
|
-
"changelog" => changelog,
|
33
|
-
},
|
34
|
-
}.to_json
|
35
|
-
|
36
|
-
if ! changelog.strip.empty? && version =~ %r{\A[\d\.]+\d+\z}
|
37
|
-
Net::HTTP.start(uri.host, uri.port, :use_ssl => true) do |http|
|
38
|
-
p http.post(uri.path, req, {'Content-Type'=>'application/json'})
|
39
|
-
end
|
40
|
-
else
|
41
|
-
warn "not updating freshmeat for v#{version}"
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
1
|
# optional rake-compiler support in case somebody needs to cross compile
|
46
2
|
begin
|
47
3
|
mk = "ext/unicorn_http/Makefile"
|
data/SIGNALS
CHANGED
@@ -3,10 +3,13 @@
|
|
3
3
|
In general, signals need only be sent to the master process. However,
|
4
4
|
the signals Unicorn uses internally to communicate with the worker
|
5
5
|
processes are documented here as well. With the exception of TTIN/TTOU,
|
6
|
-
signal handling matches the behavior of {nginx}[http://nginx.
|
6
|
+
signal handling matches the behavior of {nginx}[http://nginx.org/] so it
|
7
7
|
should be possible to easily share process management scripts between
|
8
8
|
Unicorn and nginx.
|
9
9
|
|
10
|
+
One example init script is distributed with unicorn:
|
11
|
+
https://yhbt.net/unicorn/examples/init.sh
|
12
|
+
|
10
13
|
=== Master Process
|
11
14
|
|
12
15
|
* HUP - reloads config file and gracefully restart all workers.
|
@@ -42,6 +45,10 @@ Unicorn and nginx.
|
|
42
45
|
|
43
46
|
=== Worker Processes
|
44
47
|
|
48
|
+
Note: as of unicorn 4.8, the master uses a pipe to signal workers
|
49
|
+
instead of kill(2) for most cases. Using signals still (and works and
|
50
|
+
remains supported for external tools/libraries), however.
|
51
|
+
|
45
52
|
Sending signals directly to the worker processes should not normally be
|
46
53
|
needed. If the master process is running, any exited worker will be
|
47
54
|
automatically respawned.
|
@@ -49,6 +56,8 @@ automatically respawned.
|
|
49
56
|
* INT/TERM - Quick shutdown, immediately exit.
|
50
57
|
Unless WINCH has been sent to the master (or the master is killed),
|
51
58
|
the master process will respawn a worker to replace this one.
|
59
|
+
Immediate shutdown is still triggered using kill(2) and not the
|
60
|
+
internal pipe as of unicorn 4.8
|
52
61
|
|
53
62
|
* QUIT - Gracefully exit after finishing the current request.
|
54
63
|
Unless WINCH has been sent to the master (or the master is killed),
|
@@ -101,8 +110,8 @@ The procedure is exactly like that of nginx:
|
|
101
110
|
|
102
111
|
3. You can now send WINCH to the old master process so only the new workers
|
103
112
|
serve requests. If your unicorn process is bound to an interactive
|
104
|
-
terminal, you can skip this step. Step 5 will be more
|
105
|
-
you can also skip it if your process is not daemonized.
|
113
|
+
terminal (not daemonized), you can skip this step. Step 5 will be more
|
114
|
+
difficult but you can also skip it if your process is not daemonized.
|
106
115
|
|
107
116
|
4. You should now ensure that everything is running correctly with the
|
108
117
|
new workers as the old workers die off.
|
data/Sandbox
CHANGED
@@ -1,10 +1,10 @@
|
|
1
|
-
= Tips for using
|
1
|
+
= Tips for using unicorn with Sandbox installation tools
|
2
2
|
|
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}[
|
7
|
-
{Isolate}[
|
6
|
+
{Bundler}[https://bundler.io/] or
|
7
|
+
{Isolate}[https://github.com/jbarnette/isolate].
|
8
8
|
|
9
9
|
== General deployment
|
10
10
|
|
@@ -34,7 +34,7 @@ is the primary issue with sandboxing tools such as Bundler and Isolate.
|
|
34
34
|
If you're bundling unicorn, use "bundle exec unicorn" (or "bundle exec
|
35
35
|
unicorn_rails") to start unicorn with the correct environment variables
|
36
36
|
|
37
|
-
ref:
|
37
|
+
ref: https://yhbt.net/unicorn-public/9ECF07C4-5216-47BE-961D-AFC0F0C82060@internetfamo.us/
|
38
38
|
|
39
39
|
Otherwise (if you choose to not sandbox your unicorn installation), we
|
40
40
|
expect the tips for Isolate (below) apply, too.
|
@@ -43,7 +43,8 @@ expect the tips for Isolate (below) apply, too.
|
|
43
43
|
|
44
44
|
This is no longer be an issue as of bundler 0.9.17
|
45
45
|
|
46
|
-
ref:
|
46
|
+
ref:
|
47
|
+
https://yhbt.net/unicorn-public/8FC34B23-5994-41CC-B5AF-7198EF06909E@tramchase.com/
|
47
48
|
|
48
49
|
=== BUNDLE_GEMFILE for Capistrano users
|
49
50
|
|
@@ -58,14 +59,14 @@ the before_exec hook:
|
|
58
59
|
|
59
60
|
If you're using an older Bundler version (0.9.x), you may need to set or
|
60
61
|
reset GEM_HOME, GEM_PATH and PATH environment variables in the
|
61
|
-
before_exec hook as illustrated by
|
62
|
+
before_exec hook as illustrated by https://gist.github.com/534668
|
62
63
|
|
63
64
|
=== Ruby 2.0.0 close-on-exec and SIGUSR2 incompatibility
|
64
65
|
|
65
66
|
Ruby 2.0.0 enforces FD_CLOEXEC on file descriptors by default. unicorn
|
66
|
-
has been prepared for this behavior since unicorn 4.1.0,
|
67
|
-
|
68
|
-
https://
|
67
|
+
has been prepared for this behavior since unicorn 4.1.0, and bundler
|
68
|
+
needs the "--keep-file-descriptors" option for "bundle exec":
|
69
|
+
https://bundler.io/man/bundle-exec.1.html
|
69
70
|
|
70
71
|
== Isolate
|
71
72
|
|
@@ -86,7 +87,7 @@ For now workarounds include doing one of the following:
|
|
86
87
|
|
87
88
|
3. Explicitly setting RUBYLIB or $LOAD_PATH to include any gem path
|
88
89
|
where the unicorn gem is installed
|
89
|
-
(e.g. /usr/lib/ruby/gems/1.9.
|
90
|
+
(e.g. /usr/lib/ruby/gems/1.9.3/gems/unicorn-VERSION/lib)
|
90
91
|
|
91
92
|
=== RUBYOPT pollution from SIGUSR2 upgrades
|
92
93
|
|
data/TODO
CHANGED
data/TUNING
CHANGED
@@ -1,10 +1,10 @@
|
|
1
|
-
= Tuning
|
1
|
+
= Tuning unicorn
|
2
2
|
|
3
|
-
|
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
|
-
==
|
7
|
+
== unicorn Configuration
|
8
8
|
|
9
9
|
See Unicorn::Configurator for details on the config file format.
|
10
10
|
+worker_processes+ is the most-commonly needed tuning parameter.
|
@@ -14,12 +14,15 @@ See Unicorn::Configurator for details on the config file format.
|
|
14
14
|
* worker_processes should be scaled to the number of processes your
|
15
15
|
backend system(s) can support. DO NOT scale it to the number of
|
16
16
|
external network clients your application expects to be serving.
|
17
|
-
|
17
|
+
unicorn is NOT for serving slow clients, that is the job of nginx.
|
18
18
|
|
19
19
|
* worker_processes should be *at* *least* the number of CPU cores on
|
20
|
-
a dedicated server
|
21
|
-
responses that are /not/
|
22
|
-
workaround those inefficiencies.
|
20
|
+
a dedicated server (unless you do not have enough memory).
|
21
|
+
If your application has occasionally slow responses that are /not/
|
22
|
+
CPU-intensive, you may increase this to workaround those inefficiencies.
|
23
|
+
|
24
|
+
* Under Ruby 2.2 or later, Etc.nprocessors may be used to determine
|
25
|
+
the number of CPU cores present.
|
23
26
|
|
24
27
|
* worker_processes may be increased for Unicorn::OobGC users to provide
|
25
28
|
more consistent response times.
|
@@ -55,7 +58,7 @@ See Unicorn::Configurator for details on the config file format.
|
|
55
58
|
* UNIX domain sockets are slightly faster than TCP sockets, but only
|
56
59
|
work if nginx is on the same machine.
|
57
60
|
|
58
|
-
== Other
|
61
|
+
== Other unicorn settings
|
59
62
|
|
60
63
|
* Setting "preload_app true" can allow copy-on-write-friendly GC to
|
61
64
|
be used to save memory. It will probably not work out of the box with
|
@@ -69,10 +72,28 @@ See Unicorn::Configurator for details on the config file format.
|
|
69
72
|
have them unbuffered (File#sync = true) or they are
|
70
73
|
record(line)-buffered in userspace before any writes.
|
71
74
|
|
72
|
-
== Kernel Parameters (Linux sysctl)
|
75
|
+
== Kernel Parameters (Linux sysctl and sysfs)
|
73
76
|
|
74
77
|
WARNING: Do not change system parameters unless you know what you're doing!
|
75
78
|
|
79
|
+
* Transparent hugepages (THP) improves performance in many cases,
|
80
|
+
but can also increase memory use when relying on a
|
81
|
+
copy-on-write(CoW)-friendly GC (Ruby 2.0+) with "preload_app true".
|
82
|
+
CoW operates at the page level, so writing to a huge page would
|
83
|
+
trigger a 2 MB copy (x86-64), as opposed to a 4 KB copy on a
|
84
|
+
regular (non-huge) page.
|
85
|
+
|
86
|
+
Consider only allowing THP to be used when it is requested via the
|
87
|
+
madvise(2) syscall:
|
88
|
+
|
89
|
+
echo madvise >/sys/kernel/mm/transparent_hugepage/enabled
|
90
|
+
|
91
|
+
Or disabling it system-wide, via "never".
|
92
|
+
|
93
|
+
n.b. "page" in this context only applies to the OS kernel,
|
94
|
+
Ruby GC implementations also use this term for the same concept
|
95
|
+
in a way that is agnostic to the OS.
|
96
|
+
|
76
97
|
* net.core.rmem_max and net.core.wmem_max can increase the allowed
|
77
98
|
size of :rcvbuf and :sndbuf respectively. This is mostly only useful
|
78
99
|
for UNIX domain sockets which do not have auto-tuning buffer sizes.
|
data/archive/.gitignore
ADDED
data/bin/unicorn
CHANGED
@@ -6,6 +6,7 @@ require 'optparse'
|
|
6
6
|
ENV["RACK_ENV"] ||= "development"
|
7
7
|
rackup_opts = Unicorn::Configurator::RACKUP
|
8
8
|
options = rackup_opts[:options]
|
9
|
+
set_no_default_middleware = true
|
9
10
|
|
10
11
|
op = OptionParser.new("", 24, ' ') do |opts|
|
11
12
|
cmd = File.basename($0)
|
@@ -29,7 +30,7 @@ op = OptionParser.new("", 24, ' ') do |opts|
|
|
29
30
|
|
30
31
|
opts.on("-I", "--include PATH",
|
31
32
|
"specify $LOAD_PATH (may be used more than once)") do |path|
|
32
|
-
$LOAD_PATH.unshift(*path.split(
|
33
|
+
$LOAD_PATH.unshift(*path.split(':'))
|
33
34
|
end
|
34
35
|
|
35
36
|
opts.on("-r", "--require LIBRARY",
|
@@ -60,7 +61,7 @@ op = OptionParser.new("", 24, ' ') do |opts|
|
|
60
61
|
|
61
62
|
opts.on("-N", "--no-default-middleware",
|
62
63
|
"do not load middleware implied by RACK_ENV") do |e|
|
63
|
-
rackup_opts[:no_default_middleware] = true
|
64
|
+
rackup_opts[:no_default_middleware] = true if set_no_default_middleware
|
64
65
|
end
|
65
66
|
|
66
67
|
opts.on("-D", "--daemonize", "run daemonized in the background") do |d|
|
@@ -110,6 +111,7 @@ op = OptionParser.new("", 24, ' ') do |opts|
|
|
110
111
|
opts.parse! ARGV
|
111
112
|
end
|
112
113
|
|
114
|
+
set_no_default_middleware = false
|
113
115
|
app = Unicorn.builder(ARGV[0] || 'config.ru', op)
|
114
116
|
op = nil
|
115
117
|
|
data/bin/unicorn_rails
CHANGED
@@ -30,7 +30,7 @@ op = OptionParser.new("", 24, ' ') do |opts|
|
|
30
30
|
|
31
31
|
opts.on("-I", "--include PATH",
|
32
32
|
"specify $LOAD_PATH (may be used more than once)") do |path|
|
33
|
-
$LOAD_PATH.unshift(*path.split(
|
33
|
+
$LOAD_PATH.unshift(*path.split(':'))
|
34
34
|
end
|
35
35
|
|
36
36
|
opts.on("-r", "--require LIBRARY",
|
@@ -132,11 +132,11 @@ def rails_builder(ru, op, daemonize)
|
|
132
132
|
|
133
133
|
# this lambda won't run until after forking if preload_app is false
|
134
134
|
# this runs after config file reloading
|
135
|
-
lambda do
|
135
|
+
lambda do |x, server|
|
136
136
|
# Rails 3 includes a config.ru, use it if we find it after
|
137
137
|
# working_directory is bound.
|
138
138
|
::File.exist?('config.ru') and
|
139
|
-
return Unicorn.builder('config.ru', op).call
|
139
|
+
return Unicorn.builder('config.ru', op).call(x, server)
|
140
140
|
|
141
141
|
# Load Rails and (possibly) the private version of Rack it bundles.
|
142
142
|
begin
|
data/examples/big_app_gc.rb
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
# see {Unicorn::OobGC}[
|
1
|
+
# see {Unicorn::OobGC}[https://yhbt.net/unicorn/Unicorn/OobGC.html]
|
2
2
|
# Unicorn::OobGC was broken in Unicorn v3.3.1 - v3.6.1 and fixed in v3.6.2
|
data/examples/init.sh
CHANGED
@@ -1,7 +1,16 @@
|
|
1
1
|
#!/bin/sh
|
2
2
|
set -e
|
3
|
+
### BEGIN INIT INFO
|
4
|
+
# Provides: unicorn
|
5
|
+
# Required-Start: $local_fs $network
|
6
|
+
# Required-Stop: $local_fs $network
|
7
|
+
# Default-Start: 2 3 4 5
|
8
|
+
# Default-Stop: 0 1 6
|
9
|
+
# Short-Description: Start/stop unicorn Rack app server
|
10
|
+
### END INIT INFO
|
11
|
+
|
3
12
|
# Example init script, this can be used with nginx, too,
|
4
|
-
# since nginx and unicorn accept the same signals
|
13
|
+
# since nginx and unicorn accept the same signals.
|
5
14
|
|
6
15
|
# Feel free to change any of the following variables for your app:
|
7
16
|
TIMEOUT=${TIMEOUT-60}
|
@@ -9,21 +18,22 @@ APP_ROOT=/home/x/my_app/current
|
|
9
18
|
PID=$APP_ROOT/tmp/pids/unicorn.pid
|
10
19
|
CMD="/usr/bin/unicorn -D -c $APP_ROOT/config/unicorn.rb"
|
11
20
|
INIT_CONF=$APP_ROOT/config/init.conf
|
21
|
+
UPGRADE_DELAY=${UPGRADE_DELAY-2}
|
12
22
|
action="$1"
|
13
23
|
set -u
|
14
24
|
|
15
25
|
test -f "$INIT_CONF" && . $INIT_CONF
|
16
26
|
|
17
|
-
|
27
|
+
OLD="$PID.oldbin"
|
18
28
|
|
19
29
|
cd $APP_ROOT || exit 1
|
20
30
|
|
21
31
|
sig () {
|
22
|
-
test -s "$PID" && kill -$1
|
32
|
+
test -s "$PID" && kill -$1 $(cat $PID)
|
23
33
|
}
|
24
34
|
|
25
35
|
oldsig () {
|
26
|
-
test -s $
|
36
|
+
test -s "$OLD" && kill -$1 $(cat $OLD)
|
27
37
|
}
|
28
38
|
|
29
39
|
case $action in
|
@@ -45,18 +55,36 @@ restart|reload)
|
|
45
55
|
$CMD
|
46
56
|
;;
|
47
57
|
upgrade)
|
48
|
-
if
|
58
|
+
if oldsig 0
|
59
|
+
then
|
60
|
+
echo >&2 "Old upgraded process still running with $OLD"
|
61
|
+
exit 1
|
62
|
+
fi
|
63
|
+
|
64
|
+
cur_pid=
|
65
|
+
if test -s "$PID"
|
66
|
+
then
|
67
|
+
cur_pid=$(cat $PID)
|
68
|
+
fi
|
69
|
+
|
70
|
+
if test -n "$cur_pid" &&
|
71
|
+
kill -USR2 "$cur_pid" &&
|
72
|
+
sleep $UPGRADE_DELAY &&
|
73
|
+
new_pid=$(cat $PID) &&
|
74
|
+
test x"$new_pid" != x"$cur_pid" &&
|
75
|
+
kill -0 "$new_pid" &&
|
76
|
+
kill -QUIT "$cur_pid"
|
49
77
|
then
|
50
78
|
n=$TIMEOUT
|
51
|
-
while
|
79
|
+
while kill -0 "$cur_pid" 2>/dev/null && test $n -ge 0
|
52
80
|
do
|
53
81
|
printf '.' && sleep 1 && n=$(( $n - 1 ))
|
54
82
|
done
|
55
83
|
echo
|
56
84
|
|
57
|
-
if test $n -lt 0 &&
|
85
|
+
if test $n -lt 0 && kill -0 "$cur_pid" 2>/dev/null
|
58
86
|
then
|
59
|
-
echo >&2 "$
|
87
|
+
echo >&2 "$cur_pid still running after $TIMEOUT seconds"
|
60
88
|
exit 1
|
61
89
|
fi
|
62
90
|
exit 0
|
data/examples/logrotate.conf
CHANGED
@@ -2,7 +2,10 @@
|
|
2
2
|
# /etc/logrotate.d/unicorn_app on my Debian systems
|
3
3
|
#
|
4
4
|
# See the logrotate(8) manpage for more information:
|
5
|
-
#
|
5
|
+
# https://linux.die.net/man/8/logrotate
|
6
|
+
#
|
7
|
+
# public logrotate-related discussion in our archives:
|
8
|
+
# https://yhbt.net/unicorn-public/?q=logrotate
|
6
9
|
|
7
10
|
# Modify the following glob to match the logfiles your app writes to:
|
8
11
|
/var/log/unicorn_app/*.log {
|
@@ -22,7 +25,19 @@
|
|
22
25
|
# config. Unicorn supports the USR1 signal and we send it
|
23
26
|
# as our "lastaction" action:
|
24
27
|
lastaction
|
25
|
-
#
|
28
|
+
# For systemd users, assuming you use two services
|
29
|
+
# (as recommended) to allow zero-downtime upgrades.
|
30
|
+
# Only one service needs to be started, but signaling
|
31
|
+
# both here is harmless as long as they're both enabled
|
32
|
+
systemctl kill -s SIGUSR1 unicorn@1.service
|
33
|
+
systemctl kill -s SIGUSR1 unicorn@2.service
|
34
|
+
|
35
|
+
# Examples for other process management systems appreciated
|
36
|
+
# Mail us at unicorn-public@yhbt.net
|
37
|
+
# (see above for archives)
|
38
|
+
|
39
|
+
# If you use a pid file and assuming your pid file
|
40
|
+
# is in /var/run/unicorn_app/pid
|
26
41
|
pid=/var/run/unicorn_app/pid
|
27
42
|
test -s $pid && kill -USR1 "$(cat $pid)"
|
28
43
|
endscript
|