boourns-unicorn 4.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (155) hide show
  1. data/.CHANGELOG.old +25 -0
  2. data/.document +29 -0
  3. data/.gitignore +24 -0
  4. data/.mailmap +26 -0
  5. data/.wrongdoc.yml +10 -0
  6. data/Application_Timeouts +77 -0
  7. data/CONTRIBUTORS +35 -0
  8. data/COPYING +674 -0
  9. data/DESIGN +97 -0
  10. data/Documentation/.gitignore +5 -0
  11. data/Documentation/GNUmakefile +30 -0
  12. data/Documentation/unicorn.1.txt +174 -0
  13. data/Documentation/unicorn_rails.1.txt +175 -0
  14. data/FAQ +53 -0
  15. data/GIT-VERSION-GEN +40 -0
  16. data/GNUmakefile +267 -0
  17. data/HACKING +134 -0
  18. data/ISSUES +36 -0
  19. data/KNOWN_ISSUES +79 -0
  20. data/LICENSE +64 -0
  21. data/Links +56 -0
  22. data/PHILOSOPHY +145 -0
  23. data/README +149 -0
  24. data/Rakefile +97 -0
  25. data/SIGNALS +114 -0
  26. data/Sandbox +96 -0
  27. data/TODO +5 -0
  28. data/TUNING +98 -0
  29. data/bin/unicorn +121 -0
  30. data/bin/unicorn_rails +209 -0
  31. data/examples/big_app_gc.rb +2 -0
  32. data/examples/echo.ru +27 -0
  33. data/examples/git.ru +13 -0
  34. data/examples/init.sh +74 -0
  35. data/examples/logger_mp_safe.rb +25 -0
  36. data/examples/logrotate.conf +29 -0
  37. data/examples/nginx.conf +156 -0
  38. data/examples/unicorn.conf.minimal.rb +13 -0
  39. data/examples/unicorn.conf.rb +94 -0
  40. data/ext/unicorn_http/CFLAGS +13 -0
  41. data/ext/unicorn_http/c_util.h +124 -0
  42. data/ext/unicorn_http/common_field_optimization.h +111 -0
  43. data/ext/unicorn_http/ext_help.h +86 -0
  44. data/ext/unicorn_http/extconf.rb +10 -0
  45. data/ext/unicorn_http/global_variables.h +97 -0
  46. data/ext/unicorn_http/httpdate.c +82 -0
  47. data/ext/unicorn_http/unicorn_http.rl +1036 -0
  48. data/ext/unicorn_http/unicorn_http_common.rl +76 -0
  49. data/lib/unicorn.rb +107 -0
  50. data/lib/unicorn/app/exec_cgi.rb +154 -0
  51. data/lib/unicorn/app/inetd.rb +109 -0
  52. data/lib/unicorn/app/old_rails.rb +35 -0
  53. data/lib/unicorn/app/old_rails/static.rb +59 -0
  54. data/lib/unicorn/cgi_wrapper.rb +147 -0
  55. data/lib/unicorn/configurator.rb +630 -0
  56. data/lib/unicorn/const.rb +40 -0
  57. data/lib/unicorn/http_request.rb +83 -0
  58. data/lib/unicorn/http_response.rb +45 -0
  59. data/lib/unicorn/http_server.rb +755 -0
  60. data/lib/unicorn/launcher.rb +62 -0
  61. data/lib/unicorn/oob_gc.rb +71 -0
  62. data/lib/unicorn/preread_input.rb +33 -0
  63. data/lib/unicorn/socket_helper.rb +208 -0
  64. data/lib/unicorn/ssl_client.rb +11 -0
  65. data/lib/unicorn/ssl_configurator.rb +104 -0
  66. data/lib/unicorn/ssl_server.rb +42 -0
  67. data/lib/unicorn/stream_input.rb +149 -0
  68. data/lib/unicorn/tee_input.rb +126 -0
  69. data/lib/unicorn/tmpio.rb +29 -0
  70. data/lib/unicorn/util.rb +69 -0
  71. data/lib/unicorn/worker.rb +88 -0
  72. data/local.mk.sample +59 -0
  73. data/script/isolate_for_tests +32 -0
  74. data/setup.rb +1586 -0
  75. data/t/.gitignore +5 -0
  76. data/t/GNUmakefile +82 -0
  77. data/t/README +42 -0
  78. data/t/bin/content-md5-put +36 -0
  79. data/t/bin/sha1sum.rb +17 -0
  80. data/t/bin/unused_listen +40 -0
  81. data/t/bin/utee +12 -0
  82. data/t/broken-app.ru +12 -0
  83. data/t/detach.ru +11 -0
  84. data/t/env.ru +3 -0
  85. data/t/heartbeat-timeout.ru +12 -0
  86. data/t/listener_names.ru +4 -0
  87. data/t/my-tap-lib.sh +201 -0
  88. data/t/oob_gc.ru +21 -0
  89. data/t/oob_gc_path.ru +21 -0
  90. data/t/pid.ru +3 -0
  91. data/t/preread_input.ru +17 -0
  92. data/t/rack-input-tests.ru +21 -0
  93. data/t/sslgen.sh +71 -0
  94. data/t/t0000-http-basic.sh +50 -0
  95. data/t/t0001-reload-bad-config.sh +53 -0
  96. data/t/t0002-config-conflict.sh +49 -0
  97. data/t/t0002-parser-error.sh +94 -0
  98. data/t/t0003-working_directory.sh +51 -0
  99. data/t/t0004-heartbeat-timeout.sh +69 -0
  100. data/t/t0004-working_directory_broken.sh +24 -0
  101. data/t/t0005-working_directory_app.rb.sh +37 -0
  102. data/t/t0006-reopen-logs.sh +83 -0
  103. data/t/t0006.ru +13 -0
  104. data/t/t0007-working_directory_no_embed_cli.sh +44 -0
  105. data/t/t0008-back_out_of_upgrade.sh +110 -0
  106. data/t/t0009-broken-app.sh +56 -0
  107. data/t/t0009-winch_ttin.sh +59 -0
  108. data/t/t0010-reap-logging.sh +55 -0
  109. data/t/t0011-active-unix-socket.sh +79 -0
  110. data/t/t0012-reload-empty-config.sh +85 -0
  111. data/t/t0013-rewindable-input-false.sh +24 -0
  112. data/t/t0013.ru +12 -0
  113. data/t/t0014-rewindable-input-true.sh +24 -0
  114. data/t/t0014.ru +12 -0
  115. data/t/t0015-configurator-internals.sh +25 -0
  116. data/t/t0016-trust-x-forwarded-false.sh +30 -0
  117. data/t/t0017-trust-x-forwarded-true.sh +30 -0
  118. data/t/t0018-write-on-close.sh +23 -0
  119. data/t/t0019-max_header_len.sh +49 -0
  120. data/t/t0020-at_exit-handler.sh +49 -0
  121. data/t/t0021-process_detach.sh +29 -0
  122. data/t/t0022-listener_names-preload_app.sh +32 -0
  123. data/t/t0100-rack-input-tests.sh +124 -0
  124. data/t/t0116-client_body_buffer_size.sh +80 -0
  125. data/t/t0116.ru +16 -0
  126. data/t/t0600-https-server-basic.sh +48 -0
  127. data/t/t9000-preread-input.sh +48 -0
  128. data/t/t9001-oob_gc.sh +47 -0
  129. data/t/t9002-oob_gc-path.sh +75 -0
  130. data/t/test-lib.sh +113 -0
  131. data/t/write-on-close.ru +11 -0
  132. data/test/aggregate.rb +15 -0
  133. data/test/benchmark/README +50 -0
  134. data/test/benchmark/dd.ru +18 -0
  135. data/test/benchmark/stack.ru +8 -0
  136. data/test/exec/README +5 -0
  137. data/test/exec/test_exec.rb +1041 -0
  138. data/test/test_helper.rb +300 -0
  139. data/test/unit/test_configurator.rb +158 -0
  140. data/test/unit/test_droplet.rb +28 -0
  141. data/test/unit/test_http_parser.rb +860 -0
  142. data/test/unit/test_http_parser_ng.rb +716 -0
  143. data/test/unit/test_http_parser_xftrust.rb +38 -0
  144. data/test/unit/test_request.rb +197 -0
  145. data/test/unit/test_response.rb +99 -0
  146. data/test/unit/test_server.rb +289 -0
  147. data/test/unit/test_signals.rb +207 -0
  148. data/test/unit/test_sni_hostnames.rb +47 -0
  149. data/test/unit/test_socket_helper.rb +192 -0
  150. data/test/unit/test_stream_input.rb +204 -0
  151. data/test/unit/test_tee_input.rb +296 -0
  152. data/test/unit/test_upload.rb +306 -0
  153. data/test/unit/test_util.rb +99 -0
  154. data/unicorn.gemspec +44 -0
  155. metadata +333 -0
data/Rakefile ADDED
@@ -0,0 +1,97 @@
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 RAA"
9
+ task :raa_update do
10
+ require 'net/http'
11
+ require 'net/netrc'
12
+ rc = Net::Netrc.locate('unicorn-raa') or abort "~/.netrc not found"
13
+ password = rc.password
14
+
15
+ s = Gem::Specification.load('unicorn.gemspec')
16
+ desc = [ s.description.strip ]
17
+ desc << ""
18
+ desc << "* #{s.email}"
19
+ desc << "* #{git_url}"
20
+ desc << "* #{cgit_url}"
21
+ desc = desc.join("\n")
22
+ uri = URI.parse('http://raa.ruby-lang.org/regist.rhtml')
23
+ form = {
24
+ :name => s.name,
25
+ :short_description => s.summary,
26
+ :version => s.version.to_s,
27
+ :status => 'stable',
28
+ :owner => s.authors.first,
29
+ :email => s.email,
30
+ :category_major => 'Library',
31
+ :category_minor => 'Web',
32
+ :url => s.homepage,
33
+ :download => "http://rubyforge.org/frs/?group_id=1306",
34
+ :license => "Ruby's",
35
+ :description_style => 'Plain',
36
+ :description => desc,
37
+ :pass => password,
38
+ :submit => "Update",
39
+ }
40
+ res = Net::HTTP.post_form(uri, form)
41
+ p res
42
+ puts res.body
43
+ end
44
+
45
+ desc "post to FM"
46
+ task :fm_update do
47
+ require 'tempfile'
48
+ require 'net/http'
49
+ require 'net/netrc'
50
+ require 'json'
51
+ version = ENV['VERSION'] or abort "VERSION= needed"
52
+ uri = URI.parse('https://freecode.com/projects/unicorn/releases.json')
53
+ rc = Net::Netrc.locate('unicorn-fm') or abort "~/.netrc not found"
54
+ api_token = rc.password
55
+ _, subject, body = `git cat-file tag v#{version}`.split(/\n\n/, 3)
56
+ tmp = Tempfile.new('fm-changelog')
57
+ tmp.puts subject
58
+ tmp.puts
59
+ tmp.puts body
60
+ tmp.flush
61
+ system(ENV["VISUAL"], tmp.path) or abort "#{ENV["VISUAL"]} failed: #$?"
62
+ changelog = File.read(tmp.path).strip
63
+
64
+ req = {
65
+ "auth_code" => api_token,
66
+ "release" => {
67
+ "tag_list" => "Experimental",
68
+ "version" => version,
69
+ "changelog" => changelog,
70
+ },
71
+ }.to_json
72
+
73
+ if ! changelog.strip.empty? && version =~ %r{\A[\d\.]+\d+\z}
74
+ Net::HTTP.start(uri.host, uri.port, :use_ssl => true) do |http|
75
+ p http.post(uri.path, req, {'Content-Type'=>'application/json'})
76
+ end
77
+ else
78
+ warn "not updating freshmeat for v#{version}"
79
+ end
80
+ end
81
+
82
+ # optional rake-compiler support in case somebody needs to cross compile
83
+ begin
84
+ mk = "ext/unicorn_http/Makefile"
85
+ if File.readable?(mk)
86
+ warn "run 'gmake -C ext/unicorn_http clean' and\n" \
87
+ "remove #{mk} before using rake-compiler"
88
+ elsif ENV['VERSION']
89
+ unless File.readable?("ext/unicorn_http/unicorn_http.c")
90
+ abort "run 'gmake ragel' or 'make ragel' to generate the Ragel source"
91
+ end
92
+ spec = Gem::Specification.load('unicorn.gemspec')
93
+ require 'rake/extensiontask'
94
+ Rake::ExtensionTask.new('unicorn_http', spec)
95
+ end
96
+ rescue LoadError
97
+ end
data/SIGNALS ADDED
@@ -0,0 +1,114 @@
1
+ == Signal handling
2
+
3
+ In general, signals need only be sent to the master process. However,
4
+ the signals Unicorn uses internally to communicate with the worker
5
+ processes are documented here as well. With the exception of TTIN/TTOU,
6
+ signal handling matches the behavior of {nginx}[http://nginx.net/] so it
7
+ should be possible to easily share process management scripts between
8
+ Unicorn and nginx.
9
+
10
+ === Master Process
11
+
12
+ * HUP - reloads config file and gracefully restart all workers.
13
+ If the "preload_app" directive is false (the default), then workers
14
+ will also pick up any application code changes when restarted. If
15
+ "preload_app" is true, then application code changes will have no
16
+ effect; USR2 + QUIT (see below) must be used to load newer code in
17
+ this case. When reloading the application, +Gem.refresh+ will
18
+ be called so updated code for your application can pick up newly
19
+ installed RubyGems. It is not recommended that you uninstall
20
+ libraries your application depends on while Unicorn is running,
21
+ as respawned workers may enter a spawn loop when they fail to
22
+ load an uninstalled dependency.
23
+
24
+ * INT/TERM - quick shutdown, kills all workers immediately
25
+
26
+ * QUIT - graceful shutdown, waits for workers to finish their
27
+ current request before finishing.
28
+
29
+ * USR1 - reopen all logs owned by the master and all workers
30
+ See Unicorn::Util.reopen_logs for what is considered a log.
31
+
32
+ * USR2 - reexecute the running binary. A separate QUIT
33
+ should be sent to the original process once the child is verified to
34
+ be up and running.
35
+
36
+ * WINCH - gracefully stops workers but keep the master running.
37
+ This will only work for daemonized processes.
38
+
39
+ * TTIN - increment the number of worker processes by one
40
+
41
+ * TTOU - decrement the number of worker processes by one
42
+
43
+ === Worker Processes
44
+
45
+ Sending signals directly to the worker processes should not normally be
46
+ needed. If the master process is running, any exited worker will be
47
+ automatically respawned.
48
+
49
+ * INT/TERM - Quick shutdown, immediately exit.
50
+ Unless WINCH has been sent to the master (or the master is killed),
51
+ the master process will respawn a worker to replace this one.
52
+
53
+ * QUIT - Gracefully exit after finishing the current request.
54
+ Unless WINCH has been sent to the master (or the master is killed),
55
+ the master process will respawn a worker to replace this one.
56
+
57
+ * USR1 - Reopen all logs owned by the worker process.
58
+ See Unicorn::Util.reopen_logs for what is considered a log.
59
+ Log files are not reopened until it is done processing
60
+ the current request, so multiple log lines for one request
61
+ (as done by Rails) will not be split across multiple logs.
62
+
63
+ It is NOT recommended to send the USR1 signal directly to workers via
64
+ "killall -USR1 unicorn" if you are using user/group-switching support
65
+ in your workers. You will encounter incorrect file permissions and
66
+ workers will need to be respawned. Sending USR1 to the master process
67
+ first will ensure logs have the correct permissions before the master
68
+ forwards the USR1 signal to workers.
69
+
70
+ === Procedure to replace a running unicorn executable
71
+
72
+ You may replace a running instance of unicorn with a new one without
73
+ losing any incoming connections. Doing so will reload all of your
74
+ application code, Unicorn config, Ruby executable, and all libraries.
75
+ The only things that will not change (due to OS limitations) are:
76
+
77
+ 1. The path to the unicorn executable script. If you want to change to
78
+ a different installation of Ruby, you can modify the shebang
79
+ line to point to your alternative interpreter.
80
+
81
+ The procedure is exactly like that of nginx:
82
+
83
+ 1. Send USR2 to the master process
84
+
85
+ 2. Check your process manager or pid files to see if a new master spawned
86
+ successfully. If you're using a pid file, the old process will have
87
+ ".oldbin" appended to its path. You should have two master instances
88
+ of unicorn running now, both of which will have workers servicing
89
+ requests. Your process tree should look something like this:
90
+
91
+ unicorn master (old)
92
+ \_ unicorn worker[0]
93
+ \_ unicorn worker[1]
94
+ \_ unicorn worker[2]
95
+ \_ unicorn worker[3]
96
+ \_ unicorn master
97
+ \_ unicorn worker[0]
98
+ \_ unicorn worker[1]
99
+ \_ unicorn worker[2]
100
+ \_ unicorn worker[3]
101
+
102
+ 3. You can now send WINCH to the old master process so only the new workers
103
+ serve requests. If your unicorn process is bound to an interactive
104
+ terminal, you can skip this step. Step 5 will be more difficult but
105
+ you can also skip it if your process is not daemonized.
106
+
107
+ 4. You should now ensure that everything is running correctly with the
108
+ new workers as the old workers die off.
109
+
110
+ 5. If everything seems ok, then send QUIT to the old master. You're done!
111
+
112
+ If something is broken, then send HUP to the old master to reload
113
+ the config and restart its workers. Then send QUIT to the new master
114
+ process.
data/Sandbox ADDED
@@ -0,0 +1,96 @@
1
+ = Tips for using \Unicorn with Sandbox installation tools
2
+
3
+ Since unicorn includes executables and is usually used to start a Ruby
4
+ process, there are certain caveats to using it with tools that sandbox
5
+ RubyGems installations such as
6
+ {Bundler}[http://gembundler.com/] or
7
+ {Isolate}[http://github.com/jbarnette/isolate].
8
+
9
+ == General deployment
10
+
11
+ If you're sandboxing your unicorn installation and using Capistrano (or
12
+ similar), it's required that you sandbox your RubyGems in a per-application
13
+ shared directory that can be used between different revisions.
14
+
15
+ unicorn will stash its original command-line at startup for the USR2
16
+ upgrades, and cleaning up old revisions will cause revision-specific
17
+ installations of unicorn to go missing and upgrades to fail. If you
18
+ find yourself in this situation and can't afford downtime, you can
19
+ override the existing unicorn executable path in the config file like
20
+ this:
21
+
22
+ Unicorn::HttpServer::START_CTX[0] = "/some/path/to/bin/unicorn"
23
+
24
+ Then use HUP to reload, and then continue with the USR2+QUIT upgrade
25
+ sequence.
26
+
27
+ Environment variable pollution when exec-ing a new process (with USR2)
28
+ is the primary issue with sandboxing tools such as Bundler and Isolate.
29
+
30
+ == Bundler
31
+
32
+ === Running
33
+
34
+ If you're bundling unicorn, use "bundle exec unicorn" (or "bundle exec
35
+ unicorn_rails") to start unicorn with the correct environment variables
36
+
37
+ ref: http://mid.gmane.org/9ECF07C4-5216-47BE-961D-AFC0F0C82060@internetfamo.us
38
+
39
+ Otherwise (if you choose to not sandbox your unicorn installation), we
40
+ expect the tips for Isolate (below) apply, too.
41
+
42
+ === RUBYOPT pollution from SIGUSR2 upgrades
43
+
44
+ This is no longer be an issue as of bundler 0.9.17
45
+
46
+ ref: http://mid.gmane.org/8FC34B23-5994-41CC-B5AF-7198EF06909E@tramchase.com
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
+
57
+ === Other ENV pollution issues
58
+
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
62
+
63
+ == Isolate
64
+
65
+ === Running
66
+
67
+ Installing "unicorn" as a system-wide Rubygem and using the
68
+ isolate gem may cause issues if you're using any of the bundled
69
+ application-level libraries in unicorn/app/* (for compatibility
70
+ with CGI-based applications, Rails <= 2.2.2, or ExecCgi).
71
+ For now workarounds include doing one of the following:
72
+
73
+ 1. Isolating unicorn, setting GEM_HOME to your Isolate path,
74
+ and running the isolated version of unicorn. You *must* set
75
+ GEM_HOME before running your isolated unicorn install in this way.
76
+
77
+ 2. Installing the same version of unicorn as a system-wide Rubygem
78
+ *and* isolating unicorn as well.
79
+
80
+ 3. Explicitly setting RUBYLIB or $LOAD_PATH to include any gem path
81
+ where the unicorn gem is installed
82
+ (e.g. /usr/lib/ruby/gems/1.9.1/gems/unicorn-VERSION/lib)
83
+
84
+ === RUBYOPT pollution from SIGUSR2 upgrades
85
+
86
+ If you are using Isolate, using Isolate 2.x is strongly recommended as
87
+ environment modifications are idempotent.
88
+
89
+ If you are stuck with 1.x versions of Isolate, it is recommended that
90
+ you disable it with the <tt>before_exec</tt> hook prevent the PATH and
91
+ RUBYOPT environment variable modifications from propagating between
92
+ upgrades in your Unicorn config file:
93
+
94
+ before_exec do |server|
95
+ Isolate.disable
96
+ end
data/TODO ADDED
@@ -0,0 +1,5 @@
1
+ * Documentation improvements
2
+
3
+ * improve test suite
4
+
5
+ * Rack 2.x support (when Rack 2.x exists)
data/TUNING ADDED
@@ -0,0 +1,98 @@
1
+ = Tuning \Unicorn
2
+
3
+ \Unicorn performance is generally as good as a (mostly) Ruby web server
4
+ can provide. Most often the performance bottleneck is in the web
5
+ application running on Unicorn rather than Unicorn itself.
6
+
7
+ == \Unicorn Configuration
8
+
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
32
+
33
+ * Setting a very low value for the :backlog parameter in "listen"
34
+ directives can allow failover to happen more quickly if your
35
+ cluster is configured for it.
36
+
37
+ * If you're doing extremely simple benchmarks and getting connection
38
+ errors under high request rates, increasing your :backlog parameter
39
+ above the already-generous default of 1024 can help avoid connection
40
+ errors. Keep in mind this is not recommended for real traffic if
41
+ you have another machine to failover to (see above).
42
+
43
+ * :rcvbuf and :sndbuf parameters generally do not need to be set for TCP
44
+ listeners under Linux 2.6 because auto-tuning is enabled. UNIX domain
45
+ sockets do not have auto-tuning buffer sizes; so increasing those will
46
+ allow syscalls and task switches to be saved for larger requests
47
+ and responses. If your app only generates small responses or expects
48
+ small requests, you may shrink the buffer sizes to save memory, too.
49
+
50
+ * Having socket buffers too large can also be detrimental or have
51
+ little effect. Huge buffers can put more pressure on the allocator
52
+ and may also thrash CPU caches, cancelling out performance gains
53
+ one would normally expect.
54
+
55
+ * UNIX domain sockets are slightly faster than TCP sockets, but only
56
+ work if nginx is on the same machine.
57
+
58
+ == Other \Unicorn settings
59
+
60
+ * Setting "preload_app true" can allow copy-on-write-friendly GC to
61
+ be used to save memory. It will probably not work out of the box with
62
+ applications that open sockets or perform random I/O on files.
63
+ Databases like TokyoCabinet use concurrency-safe pread()/pwrite()
64
+ functions for safe sharing of database file descriptors across
65
+ processes.
66
+
67
+ * On POSIX-compliant filesystems, it is safe for multiple threads or
68
+ processes to append to one log file as long as all the processes are
69
+ have them unbuffered (File#sync = true) or they are
70
+ record(line)-buffered in userspace before any writes.
71
+
72
+ == Kernel Parameters (Linux sysctl)
73
+
74
+ WARNING: Do not change system parameters unless you know what you're doing!
75
+
76
+ * net.core.rmem_max and net.core.wmem_max can increase the allowed
77
+ size of :rcvbuf and :sndbuf respectively. This is mostly only useful
78
+ for UNIX domain sockets which do not have auto-tuning buffer sizes.
79
+
80
+ * For load testing/benchmarking with UNIX domain sockets, you should
81
+ consider increasing net.core.somaxconn or else nginx will start
82
+ failing to connect under heavy load. You may also consider setting
83
+ a higher :backlog to listen on as noted earlier.
84
+
85
+ * If you're running out of local ports, consider lowering
86
+ net.ipv4.tcp_fin_timeout to 20-30 (default: 60 seconds). Also
87
+ consider widening the usable port range by changing
88
+ net.ipv4.ip_local_port_range.
89
+
90
+ * Setting net.ipv4.tcp_timestamps=1 will also allow setting
91
+ net.ipv4.tcp_tw_reuse=1 and net.ipv4.tcp_tw_recycle=1, which along
92
+ with the above settings can slow down port exhaustion. Not all
93
+ networks are compatible with these settings, check with your friendly
94
+ network administrator before changing these.
95
+
96
+ * Increasing the MTU size can reduce framing overhead for larger
97
+ transfers. One often-overlooked detail is that the loopback
98
+ device (usually "lo") can have its MTU increased, too.
data/bin/unicorn ADDED
@@ -0,0 +1,121 @@
1
+ #!/this/will/be/overwritten/or/wrapped/anyways/do/not/worry/ruby
2
+ # -*- encoding: binary -*-
3
+ require 'unicorn/launcher'
4
+ require 'optparse'
5
+
6
+ ENV["RACK_ENV"] ||= "development"
7
+ rackup_opts = Unicorn::Configurator::RACKUP
8
+ options = rackup_opts[:options]
9
+
10
+ op = OptionParser.new("", 24, ' ') do |opts|
11
+ cmd = File.basename($0)
12
+ opts.banner = "Usage: #{cmd} " \
13
+ "[ruby options] [#{cmd} options] [rackup config file]"
14
+ opts.separator "Ruby options:"
15
+
16
+ lineno = 1
17
+ opts.on("-e", "--eval LINE", "evaluate a LINE of code") do |line|
18
+ eval line, TOPLEVEL_BINDING, "-e", lineno
19
+ lineno += 1
20
+ end
21
+
22
+ opts.on("-d", "--debug", "set debugging flags (set $DEBUG to true)") do
23
+ $DEBUG = true
24
+ end
25
+
26
+ opts.on("-w", "--warn", "turn warnings on for your script") do
27
+ $-w = true
28
+ end
29
+
30
+ opts.on("-I", "--include PATH",
31
+ "specify $LOAD_PATH (may be used more than once)") do |path|
32
+ $LOAD_PATH.unshift(*path.split(/:/))
33
+ end
34
+
35
+ opts.on("-r", "--require LIBRARY",
36
+ "require the library, before executing your script") do |library|
37
+ require library
38
+ end
39
+
40
+ opts.separator "#{cmd} options:"
41
+
42
+ # some of these switches exist for rackup command-line compatibility,
43
+
44
+ opts.on("-o", "--host HOST",
45
+ "listen on HOST (default: #{Unicorn::Const::DEFAULT_HOST})") do |h|
46
+ rackup_opts[:host] = h
47
+ rackup_opts[:set_listener] = true
48
+ end
49
+
50
+ opts.on("-p", "--port PORT",
51
+ "use PORT (default: #{Unicorn::Const::DEFAULT_PORT})") do |p|
52
+ rackup_opts[:port] = p.to_i
53
+ rackup_opts[:set_listener] = true
54
+ end
55
+
56
+ opts.on("-E", "--env RACK_ENV",
57
+ "use RACK_ENV for defaults (default: development)") do |e|
58
+ ENV["RACK_ENV"] = e
59
+ end
60
+
61
+ opts.on("-D", "--daemonize", "run daemonized in the background") do |d|
62
+ rackup_opts[:daemonize] = !!d
63
+ end
64
+
65
+ opts.on("-P", "--pid FILE", "DEPRECATED") do |f|
66
+ warn %q{Use of --pid/-P is strongly discouraged}
67
+ warn %q{Use the 'pid' directive in the Unicorn config file instead}
68
+ options[:pid] = f
69
+ end
70
+
71
+ opts.on("-s", "--server SERVER",
72
+ "this flag only exists for compatibility") do |s|
73
+ warn "-s/--server only exists for compatibility with rackup"
74
+ end
75
+
76
+ # Unicorn-specific stuff
77
+ opts.on("-l", "--listen {HOST:PORT|PATH}",
78
+ "listen on HOST:PORT or PATH",
79
+ "this may be specified multiple times",
80
+ "(default: #{Unicorn::Const::DEFAULT_LISTEN})") do |address|
81
+ options[:listeners] << address
82
+ end
83
+
84
+ opts.on("-c", "--config-file FILE", "Unicorn-specific config file") do |f|
85
+ options[:config_file] = f
86
+ end
87
+
88
+ # I'm avoiding Unicorn-specific config options on the command-line.
89
+ # IMNSHO, config options on the command-line are redundant given
90
+ # config files and make things unnecessarily complicated with multiple
91
+ # places to look for a config option.
92
+
93
+ opts.separator "Common options:"
94
+
95
+ opts.on_tail("-h", "--help", "Show this message") do
96
+ puts opts.to_s.gsub(/^.*DEPRECATED.*$/s, '')
97
+ exit
98
+ end
99
+
100
+ opts.on_tail("-v", "--version", "Show version") do
101
+ puts "#{cmd} v#{Unicorn::Const::UNICORN_VERSION}"
102
+ exit
103
+ end
104
+
105
+ opts.parse! ARGV
106
+ end
107
+
108
+ app = Unicorn.builder(ARGV[0] || 'config.ru', op)
109
+ op = nil
110
+
111
+ if $DEBUG
112
+ require 'pp'
113
+ pp({
114
+ :unicorn_options => options,
115
+ :app => app,
116
+ :daemonize => rackup_opts[:daemonize],
117
+ })
118
+ end
119
+
120
+ Unicorn::Launcher.daemonize!(options) if rackup_opts[:daemonize]
121
+ Unicorn::HttpServer.new(app, options).start.join