passenger 5.0.10 → 5.0.11
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of passenger might be problematic. Click here for more details.
- checksums.yaml +8 -8
- checksums.yaml.gz.asc +7 -7
- data.tar.gz.asc +7 -7
- data/CHANGELOG +18 -0
- data/CONTRIBUTING.md +3 -3
- data/bin/passenger-status +12 -4
- data/build/agents.rb +45 -45
- data/build/apache2.rb +1 -1
- data/build/basics.rb +1 -1
- data/build/cxx_tests.rb +12 -12
- data/doc/CloudLicensingConfiguration.html +10 -10
- data/doc/CloudLicensingConfiguration.txt.md +10 -10
- data/doc/DebuggingAndStressTesting.md +3 -3
- data/doc/Design and Architecture.html +30 -30
- data/doc/Design and Architecture.txt +28 -28
- data/doc/ServerOptimizationGuide.html +3 -3
- data/doc/ServerOptimizationGuide.txt.md +3 -3
- data/doc/Users guide Apache.html +24 -12
- data/doc/Users guide Apache.txt +2 -2
- data/doc/Users guide Nginx.html +24 -12
- data/doc/Users guide Nginx.txt +2 -2
- data/doc/Users guide Standalone.html +18 -6
- data/doc/images/passenger_architecture.png +0 -0
- data/doc/images/passenger_architecture.svg +10 -9
- data/doc/images/{helper_agent_core_architecture.png → passenger_core_architecture.png} +0 -0
- data/doc/users_guide_snippets/environment_variables.txt +1 -1
- data/doc/users_guide_snippets/installation/verify_running_epilogue.txt +1 -1
- data/doc/users_guide_snippets/support_information.txt +1 -1
- data/doc/users_guide_snippets/tips.txt +2 -2
- data/doc/users_guide_snippets/under_the_hood/relationship_with_ruby.txt +1 -1
- data/ext/apache2/Bucket.h +5 -5
- data/ext/apache2/Configuration.cpp +1 -1
- data/ext/apache2/Configuration.hpp +2 -3
- data/ext/apache2/ConfigurationFields.hpp +3 -0
- data/ext/apache2/ConfigurationFields.hpp.erb +3 -0
- data/ext/apache2/Hooks.cpp +42 -34
- data/ext/common/Account.h +3 -3
- data/ext/common/AgentsStarter.cpp +7 -7
- data/ext/common/AgentsStarter.h +20 -20
- data/ext/common/ApplicationPool2/Options.h +12 -12
- data/ext/common/Constants.h +10 -8
- data/ext/common/Logging.cpp +22 -1
- data/ext/common/Logging.h +19 -2
- data/ext/common/ServerKit/AcceptLoadBalancer.h +3 -3
- data/ext/common/ServerKit/Server.h +24 -0
- data/ext/common/UnionStation/Connection.h +1 -1
- data/ext/common/UnionStation/Core.h +21 -21
- data/ext/common/UnionStation/Transaction.h +3 -3
- data/ext/common/Utils.cpp +2 -2
- data/ext/common/Utils/IOUtils.cpp +5 -1
- data/ext/common/{agents → agent}/ApiServerUtils.h +3 -3
- data/ext/common/{agents → agent}/Base.cpp +2 -2
- data/ext/common/{agents → agent}/Base.h +0 -0
- data/ext/common/{agents/HelperAgent → agent/Core}/ApiServer.h +33 -9
- data/ext/common/{agents/HelperAgent → agent/Core}/Main.cpp +60 -59
- data/ext/common/{agents/HelperAgent → agent/Core}/OptionParser.h +32 -25
- data/ext/common/{agents/HelperAgent → agent/Core}/RequestHandler.h +17 -17
- data/ext/common/{agents/HelperAgent → agent/Core}/RequestHandler/AppResponse.h +0 -0
- data/ext/common/{agents/HelperAgent → agent/Core}/RequestHandler/BufferBody.cpp +0 -0
- data/ext/common/{agents/HelperAgent → agent/Core}/RequestHandler/CheckoutSession.cpp +0 -0
- data/ext/common/{agents/HelperAgent → agent/Core}/RequestHandler/Client.h +2 -2
- data/ext/common/{agents/HelperAgent → agent/Core}/RequestHandler/ForwardResponse.cpp +0 -0
- data/ext/common/{agents/HelperAgent → agent/Core}/RequestHandler/Hooks.cpp +0 -0
- data/ext/common/{agents/HelperAgent → agent/Core}/RequestHandler/InitRequest.cpp +4 -3
- data/ext/common/{agents/HelperAgent → agent/Core}/RequestHandler/Request.h +1 -1
- data/ext/common/{agents/HelperAgent → agent/Core}/RequestHandler/SendRequest.cpp +0 -0
- data/ext/common/{agents/HelperAgent → agent/Core}/RequestHandler/TurboCaching.h +1 -1
- data/ext/common/{agents/HelperAgent → agent/Core}/RequestHandler/Utils.cpp +0 -0
- data/ext/common/{agents/HelperAgent → agent/Core}/ResponseCache.h +0 -0
- data/ext/common/{agents → agent}/Main.cpp +9 -9
- data/ext/common/{agents → agent}/SpawnPreparer/Main.cpp +0 -0
- data/ext/common/{agents/HelperAgent/SystemMetricsTool.cpp → agent/SystemMetrics/Main.cpp} +0 -0
- data/ext/common/{agents → agent}/TempDirToucher/Main.cpp +0 -0
- data/ext/common/{agents/LoggingAgent → agent/UstRouter}/ApiServer.h +7 -7
- data/ext/common/{agents/LoggingAgent → agent/UstRouter}/DataStoreId.h +0 -0
- data/ext/common/{agents/LoggingAgent → agent/UstRouter}/FilterSupport.cpp +0 -0
- data/ext/common/{agents/LoggingAgent → agent/UstRouter}/FilterSupport.h +0 -0
- data/ext/common/{agents/LoggingAgent → agent/UstRouter}/LoggingServer.h +4 -4
- data/ext/common/{agents/LoggingAgent → agent/UstRouter}/Main.cpp +45 -45
- data/ext/common/{agents/LoggingAgent → agent/UstRouter}/OptionParser.h +20 -20
- data/ext/common/{agents/LoggingAgent → agent/UstRouter}/RemoteSender.h +0 -0
- data/ext/common/{agents → agent}/Watchdog/AgentWatcher.cpp +0 -0
- data/ext/common/{agents → agent}/Watchdog/ApiServer.h +1 -1
- data/ext/common/{agents/Watchdog/HelperAgentWatcher.cpp → agent/Watchdog/CoreWatcher.cpp} +14 -10
- data/ext/common/{agents → agent}/Watchdog/InstanceDirToucher.cpp +0 -0
- data/ext/common/{agents → agent}/Watchdog/Main.cpp +131 -75
- data/ext/common/{agents/Watchdog/LoggingAgentWatcher.cpp → agent/Watchdog/UstRouterWatcher.cpp} +13 -9
- data/ext/nginx/CacheLocationConfig.c +11 -6
- data/ext/nginx/CacheLocationConfig.c.erb +11 -6
- data/ext/nginx/Configuration.c +22 -7
- data/ext/nginx/Configuration.h +1 -19
- data/ext/nginx/ConfigurationFields.h +19 -0
- data/ext/nginx/ConfigurationFields.h.erb +19 -0
- data/ext/nginx/ContentHandler.c +33 -33
- data/ext/nginx/CreateLocationConfig.c +3 -1
- data/ext/nginx/CreateLocationConfig.c.erb +3 -1
- data/ext/nginx/MergeLocationConfig.c +8 -4
- data/ext/nginx/MergeLocationConfig.c.erb +7 -3
- data/ext/nginx/ngx_http_passenger_module.c +33 -42
- data/helper-scripts/backtrace-sanitizer.rb +2 -2
- data/lib/phusion_passenger.rb +1 -1
- data/lib/phusion_passenger/admin_tools/instance.rb +2 -2
- data/lib/phusion_passenger/admin_tools/instance_registry.rb +7 -3
- data/lib/phusion_passenger/common_library.rb +8 -8
- data/lib/phusion_passenger/config/about_command.rb +1 -1
- data/lib/phusion_passenger/config/api_call_command.rb +3 -3
- data/lib/phusion_passenger/config/installation_utils.rb +34 -21
- data/lib/phusion_passenger/config/reopen_logs_command.rb +2 -2
- data/lib/phusion_passenger/config/restart_app_command.rb +18 -4
- data/lib/phusion_passenger/constants.rb +7 -5
- data/lib/phusion_passenger/loader_shared_helpers.rb +2 -6
- data/lib/phusion_passenger/message_client.rb +8 -8
- data/lib/phusion_passenger/platform_info/ruby.rb +1 -2
- data/lib/phusion_passenger/preloader_shared_helpers.rb +1 -1
- data/lib/phusion_passenger/request_handler.rb +3 -2
- data/lib/phusion_passenger/request_handler/thread_handler.rb +4 -4
- data/lib/phusion_passenger/standalone/start_command.rb +13 -3
- data/lib/phusion_passenger/standalone/start_command/builtin_engine.rb +2 -1
- data/lib/phusion_passenger/union_station/core.rb +18 -18
- data/lib/phusion_passenger/union_station/transaction.rb +5 -5
- data/resources/oss-binaries.phusionpassenger.com.crt +0 -84
- data/resources/templates/standalone/config.erb +1 -0
- metadata +40 -40
- metadata.gz.asc +7 -7
@@ -26,7 +26,7 @@ Whenever a Phusion Passenger agent process crashes because of a signal (SIGABRT,
|
|
26
26
|
|
27
27
|
* A simple libc-level backtrace of the current thread. This backtrace may or may not correspond to the thread that caused the crash.
|
28
28
|
* A detailed backtrace report, covering all threads. This report even contains the values of variables on the stack. The report is obtained through the [crash-watch](https://github.com/FooBarWidget/crash-watch) tool so you must have it installed. Crash-watch in turn requires gdb, which must also be installed.
|
29
|
-
* Agent-specific diagnostics information. For example the
|
29
|
+
* Agent-specific diagnostics information. For example the Passenger core will report the status of its process pool and its connected clients.
|
30
30
|
|
31
31
|
You can change the crash behavior with the following environment variables:
|
32
32
|
|
@@ -55,6 +55,6 @@ To enable, set the environment variable `PASSENGER_SIMULATE_SYSCALL_FAILURES`. T
|
|
55
55
|
|
56
56
|
`program_nameN` specifies the name of the Phusion Passenger process for which system call failure simulation should be enabled. This is followed by a list of system call `errno` names and the respective probabilities (between 0 and 1). For example:
|
57
57
|
|
58
|
-
export PASSENGER_SIMULATE_SYSCALL_FAILURES='watchdog=ENOSPC:0.01;
|
58
|
+
export PASSENGER_SIMULATE_SYSCALL_FAILURES='PassengerAgent watchdog=ENOSPC:0.01;PassengerAgent core=EMFILE:0.001,ECONNREFUSED:0.02'
|
59
59
|
|
60
|
-
This will enable system call failure simulation only for the watchdog and the
|
60
|
+
This will enable system call failure simulation only for the watchdog and the core, but not for the UstRouter. All system calls in the watchdog will have a 1% probability of throwing ENOSPC. All system calls in the HTTP server will have a 0.1% probability of throwing EMFILE, and a 2% probability of throwing ECONNREFUSED.
|
@@ -1091,14 +1091,14 @@ pre {
|
|
1091
1091
|
<div class="foo toclevel4"><a href="#_the_rationale_behind_reverse_proxying">1.1.2. The rationale behind reverse proxying</a></div>
|
1092
1092
|
<div class="foo toclevel3"><a href="#_phusion_passenger_architecture_overview">1.2. Phusion Passenger architecture overview</a></div>
|
1093
1093
|
<div class="foo toclevel4"><a href="#_web_server_module">1.2.1. Web server module</a></div>
|
1094
|
-
<div class="foo toclevel4"><a href="#
|
1095
|
-
<div class="foo toclevel4"><a href="#
|
1094
|
+
<div class="foo toclevel4"><a href="#_passenger_core">1.2.2. Passenger core</a></div>
|
1095
|
+
<div class="foo toclevel4"><a href="#_ustrouter">1.2.3. UstRouter</a></div>
|
1096
1096
|
<div class="foo toclevel4"><a href="#_watchdog">1.2.4. Watchdog</a></div>
|
1097
1097
|
<div class="foo toclevel4"><a href="#_command_line_tools">1.2.5. Command line tools</a></div>
|
1098
1098
|
<div class="foo toclevel4"><a href="#_passenger_standalone">1.2.6. Passenger Standalone</a></div>
|
1099
1099
|
<div class="foo toclevel3"><a href="#_build_system_and_source_tree">1.3. Build system and source tree</a></div>
|
1100
1100
|
<div class="foo toclevel2"><a href="#_initialization">2. Initialization</a></div>
|
1101
|
-
<div class="foo toclevel2"><a href="#
|
1101
|
+
<div class="foo toclevel2"><a href="#passenger_core_architecture">3. Passenger core architecture</a></div>
|
1102
1102
|
<div class="foo toclevel3"><a href="#_request_handling">3.1. Request handling</a></div>
|
1103
1103
|
<div class="foo toclevel4"><a href="#_one_client_per_request">3.1.1. One client per request</a></div>
|
1104
1104
|
<div class="foo toclevel4"><a href="#request_handler_forwarding_to_app">3.1.2. Forwarding to the application</a></div>
|
@@ -1254,31 +1254,31 @@ end</pre>
|
|
1254
1254
|
<img src="images/passenger_architecture_overview.png" alt="An overview of Phusion Passenger’s architecture">
|
1255
1255
|
</span></p></div>
|
1256
1256
|
<div class="paragraph"><p>Phusion Passenger is not a single, monolithic entity. Instead, it consists of multiple components and processes that work together. Part of the reason why Phusion Passenger is split like this, is because it’s technically necessary (no other way to implement it). But another part of the reason is stability and robustness. Individual components can crash and can be restarted independently from each other. If we were to put everything inside a single process, then a crash will take down all of Phusion Passenger.</p></div>
|
1257
|
-
<div class="paragraph"><p>Thus, if the
|
1257
|
+
<div class="paragraph"><p>Thus, if the Passenger core crashes, or if an application process crashes, they can both be restarted without affecting the web server’s stability.</p></div>
|
1258
1258
|
<div class="sect3">
|
1259
1259
|
<span class="anchor_helper" id="_web_server_module"></span><h4 data-anchor="_web_server_module">1.2.1. Web server module</h4>
|
1260
|
-
<div class="paragraph"><p>When an HTTP client sends a request, it is received by the web server (Nginx or Apache). Both Apache and Nginx can be extended with <strong>modules</strong>. Phusion Passenger provides such a module. The module is loaded into Nginx/Apache. It checks whether the request should be handled by a Phusion Passenger-served web application, and if so, forwards the request to the
|
1261
|
-
<div class="paragraph"><p>The Nginx module and Apache module have an entirely different code base. Their code bases are in <span class="monospaced">ext/nginx</span> and <span class="monospaced">ext/apache2</span>, respectively. Both modules are relatively small because they outsource most logic to the
|
1260
|
+
<div class="paragraph"><p>When an HTTP client sends a request, it is received by the web server (Nginx or Apache). Both Apache and Nginx can be extended with <strong>modules</strong>. Phusion Passenger provides such a module. The module is loaded into Nginx/Apache. It checks whether the request should be handled by a Phusion Passenger-served web application, and if so, forwards the request to the Passenger core. The internal wire protocol used during this forwarding, is a modified version of <a href="http://en.wikipedia.org/wiki/SCGI">SCGI</a>.</p></div>
|
1261
|
+
<div class="paragraph"><p>The Nginx module and Apache module have an entirely different code base. Their code bases are in <span class="monospaced">ext/nginx</span> and <span class="monospaced">ext/apache2</span>, respectively. Both modules are relatively small because they outsource most logic to the Passenger core, and because they utilize a common library (<span class="monospaced">ext/common</span>). This allows us to support both Nginx and Apache without having to write a lot of things twice.</p></div>
|
1262
1262
|
</div>
|
1263
1263
|
<div class="sect3">
|
1264
|
-
<span class="anchor_helper" id="
|
1265
|
-
<div class="paragraph"><p>The <strong>
|
1266
|
-
<div class="paragraph"><p>The
|
1267
|
-
<div class="paragraph"><p>The
|
1264
|
+
<span class="anchor_helper" id="_passenger_core"></span><h4 data-anchor="_passenger_core">1.2.2. Passenger core</h4>
|
1265
|
+
<div class="paragraph"><p>The <strong>Passenger core</strong> is where most of the processing is done. The core keeps track of which application processes currently exist, and using load balancing rules, determines which process a request should be forwarded to. The core also takes care of <strong>application spawning</strong>: if it determines that having more application processes is necessary or beneficial, then it will make that happen. Process spawning is subject to user-configured limits: the core will never spawn more processes than a user-configured maximum.</p></div>
|
1266
|
+
<div class="paragraph"><p>The core also has monitoring and statistics gathering capabilities. It constantly keeps track of applications' memory usage, how many requests they’ve handled, etc. This information can later be queried from administration tools. And if an application process crashes, the core restarts it.</p></div>
|
1267
|
+
<div class="paragraph"><p>The core is by far the largest and most complex part of the system, but it is itself composed of several smaller subsystems. Most of the <a href="#passenger_core_architecture">core architecture</a> chapter is devoted to describing the core.</p></div>
|
1268
1268
|
</div>
|
1269
1269
|
<div class="sect3">
|
1270
|
-
<span class="anchor_helper" id="
|
1271
|
-
<div class="paragraph"><p>The
|
1270
|
+
<span class="anchor_helper" id="_ustrouter"></span><h4 data-anchor="_ustrouter">1.2.3. UstRouter</h4>
|
1271
|
+
<div class="paragraph"><p>The core cooperates with the <strong>UstRouter</strong>. This latter is responsible for sending data to <a href="https://www.unionstationapp.com">Union Station</a>, a monitoring web service. If you didn’t explicitly tell Phusion Passenger to send data to Union Station, then the UstRouter sits idle and does not consume resources.</p></div>
|
1272
1272
|
</div>
|
1273
1273
|
<div class="sect3">
|
1274
1274
|
<span class="anchor_helper" id="_watchdog"></span><h4 data-anchor="_watchdog">1.2.4. Watchdog</h4>
|
1275
|
-
<div class="paragraph"><p>The
|
1275
|
+
<div class="paragraph"><p>The core and the UstRouter contain complex logic, so they could contain bugs which could crash them.
|
1276
1276
|
So as a safety measure, they are both monitored by the <strong>Watchdog</strong>. If either of them crash, they are restarted by the Watchdog. This setup seeks to ensure that the system stays up, no matter what.</p></div>
|
1277
1277
|
<div class="paragraph"><p>You might now wonder: what happens if the Watchdog crashes? Shouldn’t the Watchdog be monitored by another Watchdog? We’ve contemplated this possibility, but the Watchdog is very simple, and since 2012 we haven’t seen a single report of the Watchdog crashing, nor have we been able to make it crash since that time. So, for the sake of keeping the codebase as simple as possible, we’ve chosen not to introduce multiple Watchdogs.</p></div>
|
1278
1278
|
</div>
|
1279
1279
|
<div class="sect3">
|
1280
1280
|
<span class="anchor_helper" id="_command_line_tools"></span><h4 data-anchor="_command_line_tools">1.2.5. Command line tools</h4>
|
1281
|
-
<div class="paragraph"><p>Finally, there is an array of <strong>command line tools</strong> which support Phusion Passenger. The installers — <span class="monospaced">passenger-install-*-module</span> — are responsible for installing Phusion Passenger. There are administrative tools such as <span class="monospaced">passenger-status</span> and <span class="monospaced">passenger-memory-stats</span>. And many more. Some of these tools may communicate with one of the agents. For example, the <span class="monospaced">passenger-status</span> queries the
|
1281
|
+
<div class="paragraph"><p>Finally, there is an array of <strong>command line tools</strong> which support Phusion Passenger. The installers — <span class="monospaced">passenger-install-*-module</span> — are responsible for installing Phusion Passenger. There are administrative tools such as <span class="monospaced">passenger-status</span> and <span class="monospaced">passenger-memory-stats</span>. And many more. Some of these tools may communicate with one of the agents. For example, the <span class="monospaced">passenger-status</span> queries the core for information that the core has collected. How this communication is done, is described in <a href="#instance_state_and_communication">Instance state and communication</a>.</p></div>
|
1282
1282
|
</div>
|
1283
1283
|
<div class="sect3">
|
1284
1284
|
<span class="anchor_helper" id="_passenger_standalone"></span><h4 data-anchor="_passenger_standalone">1.2.6. Passenger Standalone</h4>
|
@@ -1287,7 +1287,7 @@ So as a safety measure, they are both monitored by the <strong>Watchdog</strong>
|
|
1287
1287
|
</div>
|
1288
1288
|
<div class="sect2">
|
1289
1289
|
<span class="anchor_helper" id="_build_system_and_source_tree"></span><h3 data-anchor="_build_system_and_source_tree">1.3. Build system and source tree</h3>
|
1290
|
-
<div class="paragraph"><p>Phusion Passenger is written mostly in C++ and Ruby. The web server modules,
|
1290
|
+
<div class="paragraph"><p>Phusion Passenger is written mostly in C++ and Ruby. The web server modules, core, UstRouter and Watchdog are written in C++. Most command line tools are written in Ruby. You can find each component here:</p></div>
|
1291
1291
|
<div class="ulist"><ul>
|
1292
1292
|
<li>
|
1293
1293
|
<p>
|
@@ -1296,7 +1296,7 @@ The web server modules can be found in <span class="monospaced">ext/apache2</spa
|
|
1296
1296
|
</li>
|
1297
1297
|
<li>
|
1298
1298
|
<p>
|
1299
|
-
The
|
1299
|
+
The Passenger core, UstRouter and Watchdog can be found in <span class="monospaced">ext/common/agent</span>.
|
1300
1300
|
</p>
|
1301
1301
|
</li>
|
1302
1302
|
<li>
|
@@ -1346,17 +1346,17 @@ The Phusion Passenger module inside Nginx/Apache proceeds with starting the Watc
|
|
1346
1346
|
</li>
|
1347
1347
|
<li>
|
1348
1348
|
<p>
|
1349
|
-
The Watchdog first initializes a <a href="#instance_state_and_communication">"instance directory"</a>, which is a temporary directory containing files that will be used during the life time of this Phusion Passenger instance. For example, the directory contains Unix domain socket files, so that the different Phusion Passenger processes can communicate with each other. The Watchdog is implemented in <span class="monospaced">ext/common/
|
1349
|
+
The Watchdog first initializes a <a href="#instance_state_and_communication">"instance directory"</a>, which is a temporary directory containing files that will be used during the life time of this Phusion Passenger instance. For example, the directory contains Unix domain socket files, so that the different Phusion Passenger processes can communicate with each other. The Watchdog is implemented in <span class="monospaced">ext/common/agent/Watchdog/Main.cpp</span>.
|
1350
1350
|
</p>
|
1351
1351
|
</li>
|
1352
1352
|
<li>
|
1353
1353
|
<p>
|
1354
|
-
The Watchdog starts the
|
1354
|
+
The Watchdog starts the Passenger core and the UstRouter simultaneously. Each performs its own initialization.
|
1355
1355
|
</p>
|
1356
1356
|
</li>
|
1357
1357
|
<li>
|
1358
1358
|
<p>
|
1359
|
-
When the
|
1359
|
+
When the core is done initializing, it will send a message back to the Watchdog saying that it’s done. The UstRouter does something similar. When the Watchdog has received both acknowledgment messages, it finishes initialization. If the Watchdog notices that one of the agents have exited without sending an acknowledgment message, then it enters an error state.
|
1360
1360
|
</p>
|
1361
1361
|
</li>
|
1362
1362
|
<li>
|
@@ -1369,19 +1369,19 @@ The Watchdog reports successful startup back to the Phusion Passenger module tha
|
|
1369
1369
|
</div>
|
1370
1370
|
</div>
|
1371
1371
|
<div class="sect1">
|
1372
|
-
<span class="anchor_helper" id="
|
1372
|
+
<span class="anchor_helper" id="passenger_core_architecture"></span><h2 data-anchor="passenger_core_architecture">3. Passenger core architecture</h2>
|
1373
1373
|
<div class="sectionbody">
|
1374
1374
|
<div class="paragraph"><p><span class="image">
|
1375
|
-
<img src="images/
|
1375
|
+
<img src="images/passenger_core_architecture.png" alt="Passenger core architecture">
|
1376
1376
|
</span></p></div>
|
1377
|
-
<div class="paragraph"><p>The
|
1377
|
+
<div class="paragraph"><p>The Passenger core consists of two subsystems. One is the <strong>request handling subsystem</strong>. The other is <strong>the ApplicationPool subsystem</strong>, which performs the bulk of process management. The core also uses a number of support libraries. The largest third-party support libraries are shown in the diagram. Many more — internal — support libraries are used, but they’re omitted from the diagram. You can find these internal support libraries in the directory <span class="monospaced">ext/common/Utils</span>.</p></div>
|
1378
1378
|
<div class="sect2">
|
1379
1379
|
<span class="anchor_helper" id="_request_handling"></span><h3 data-anchor="_request_handling">3.1. Request handling</h3>
|
1380
|
-
<div class="paragraph"><p>Recall that requests are first received from the web server. The web server serializes the request into a slightly modified version of <a href="http://en.wikipedia.org/wiki/SCGI">the SCGI format</a>, and sends it to the
|
1380
|
+
<div class="paragraph"><p>Recall that requests are first received from the web server. The web server serializes the request into a slightly modified version of <a href="http://en.wikipedia.org/wiki/SCGI">the SCGI format</a>, and sends it to the core’s RequestHandler. The RequestHandler performs some work, and eventually sends back a regular HTTP response. The web server parses the RequestHandler response, and sends a response to the original HTTP client.</p></div>
|
1381
1381
|
<div class="paragraph"><p>The RequestHandler listens on a Unix domain socket file. This Unix domain socket file is called <span class="monospaced">request</span>, and is located in <a href="#instance_state_and_communication">the instance directory</a>.</p></div>
|
1382
1382
|
<div class="sect3">
|
1383
1383
|
<span class="anchor_helper" id="_one_client_per_request"></span><h4 data-anchor="_one_client_per_request">3.1.1. One client per request</h4>
|
1384
|
-
<div class="paragraph"><p>The web server creates a new connection to the
|
1384
|
+
<div class="paragraph"><p>The web server creates a new connection to the core on every request. Thus, from the viewpoint of the RequestHandler, its client is the web server. Every time a client connects (i.e. a new request is forwarded), the RequestHandler creates a new Client object which represents that request. All request-specific state is stored inside the Client. After the RequestHandler is done processing a request, it closes the client socket.</p></div>
|
1385
1385
|
<div class="paragraph"><p>Note that in the diagram, a Client has a 0..1 association with RequestHandler. That’s because when a Client is disconnected, the pointer to the associated RequestHandler is set to NULL. There might be background operations left which still have a pointer to the Client. As soon as those background operations finish, they check whether the Client has a valid pointer to the RequestHandler. If so, they commit their work; if not, they discard their work. The Client is destroyed when all its associated background operations have finished.</p></div>
|
1386
1386
|
</div>
|
1387
1387
|
<div class="sect3">
|
@@ -1539,7 +1539,7 @@ DummySpawner (not shown in diagram) — only used in unit tests.
|
|
1539
1539
|
<div class="sect1">
|
1540
1540
|
<span class="anchor_helper" id="app_spawning_and_loading"></span><h2 data-anchor="app_spawning_and_loading">4. Application spawning and loading</h2>
|
1541
1541
|
<div class="sectionbody">
|
1542
|
-
<div class="paragraph"><p>Application processes are spawned from the
|
1542
|
+
<div class="paragraph"><p>Application processes are spawned from the Passenger core process. Spawning a process involves a lot of <strong>preparation work</strong>, such as setting up communication channels, setting up the current working directory, environment variables, etc. This preparation work is done by <a href="#spawner_subsystem">a Spawner object</a>, together with various support executables.</p></div>
|
1543
1543
|
<div class="paragraph"><p>When preparation is done, your application’s entry point has to be loaded somehow. That loading is done through a language-specific <strong>loader program</strong>. The loader program communicates with the Spawner through the communication channel that was set up earlier, initializes the language-specific environment, sets up a server, and reports back to the Spawner. This communication is done through a certain <strong>protocol</strong>.</p></div>
|
1544
1544
|
<div class="sect2">
|
1545
1545
|
<span class="anchor_helper" id="_preparation_work"></span><h3 data-anchor="_preparation_work">4.1. Preparation work</h3>
|
@@ -1553,7 +1553,7 @@ DummySpawner (not shown in diagram) — only used in unit tests.
|
|
1553
1553
|
</div>
|
1554
1554
|
<div class="sect3">
|
1555
1555
|
<span class="anchor_helper" id="_loading_spawnpreparer_possibly_through_bash"></span><h4 data-anchor="_loading_spawnpreparer_possibly_through_bash">4.1.2. Loading SpawnPreparer, possibly through bash</h4>
|
1556
|
-
<div class="paragraph"><p>Because the
|
1556
|
+
<div class="paragraph"><p>Because the Passenger core is heavily multi-threaded, the child process has been forked by the Spawner <a href="http://pubs.opengroup.org/onlinepubs/009695399/functions/fork.html">may only perform async-signal-safe operations</a>:</p></div>
|
1557
1557
|
<div class="quoteblock">
|
1558
1558
|
<div class="content">"A process shall be created with a single thread. If a multi-threaded process calls fork(), the new process shall contain a replica of the calling thread and its entire address space, possibly including the states of mutexes and other resources. Consequently, to avoid errors, the child process may only execute async-signal-safe operations until such time as one of the exec functions is called. Fork handlers may be established by means of the pthread_atfork() function in order to maintain application invariants across fork() calls."</div>
|
1559
1559
|
<div class="attribution">
|
@@ -1772,7 +1772,7 @@ The maximum number of <strong>concurrent connections</strong> the server support
|
|
1772
1772
|
<div class="olist arabic"><ol class="arabic">
|
1773
1773
|
<li>
|
1774
1774
|
<p>
|
1775
|
-
Just write the error message to stdout as you normally do, and abort without printing the <span class="monospaced">!> Ready</span> message. The
|
1775
|
+
Just write the error message to stdout as you normally do, and abort without printing the <span class="monospaced">!> Ready</span> message. The Passenger core will read everything that the loader has written to stdout, and use it as the error message. This error message is considered to be plain text.
|
1776
1776
|
</p>
|
1777
1777
|
</li>
|
1778
1778
|
<li>
|
@@ -1802,7 +1802,7 @@ No more clients will be routed to this particular process.
|
|
1802
1802
|
</div>
|
1803
1803
|
<div class="sect3">
|
1804
1804
|
<span class="anchor_helper" id="_stdout_and_stderr_forwarding"></span><h4 data-anchor="_stdout_and_stderr_forwarding">4.2.7. Stdout and stderr forwarding</h4>
|
1805
|
-
<div class="paragraph"><p>All lines that the loader writes to stdout, and that are not prefixed with `!> `, are forwarded by the
|
1805
|
+
<div class="paragraph"><p>All lines that the loader writes to stdout, and that are not prefixed with `!> `, are forwarded by the Passenger core to its own stdout. Similarly, everything that the loader writes to stderr, whether prefixed with `!> ` or not, is forwarded by the Passenger core to its own stdout.</p></div>
|
1806
1806
|
<div class="paragraph"><p>While the Spawner is still doing its work, it takes care of this forwarding by itself. Once the Spawner is done, it outsources this work to two PipeWatcher objects, each which spawns a background thread for this purpose.</p></div>
|
1807
1807
|
</div>
|
1808
1808
|
</div>
|
@@ -1838,7 +1838,7 @@ It sends a response back to the Spawner. This is similar to how the loader does
|
|
1838
1838
|
</div>
|
1839
1839
|
<div class="sect2">
|
1840
1840
|
<span class="anchor_helper" id="app_types_registry"></span><h3 data-anchor="app_types_registry">4.4. The AppTypes registry</h3>
|
1841
|
-
<div class="paragraph"><p>When the web server receives a request, the Phusion Passenger module inside it autodetects the type of application that the request belongs to. It does that by examening the filesystem and checking which one of the startup files exist. For example, if <span class="monospaced">config.ru</span> exists, then it assumes that it’s a Ruby app. Or if <span class="monospaced">app.js</span> exists, then it assumes that it’s a Node.js app. The Phusion Passenger module forwards the inferred application type to the
|
1841
|
+
<div class="paragraph"><p>When the web server receives a request, the Phusion Passenger module inside it autodetects the type of application that the request belongs to. It does that by examening the filesystem and checking which one of the startup files exist. For example, if <span class="monospaced">config.ru</span> exists, then it assumes that it’s a Ruby app. Or if <span class="monospaced">app.js</span> exists, then it assumes that it’s a Node.js app. The Phusion Passenger module forwards the inferred application type to the Passenger core.</p></div>
|
1842
1842
|
<div class="paragraph"><p>Given an application type, the associated loader and preloader can be looked up.</p></div>
|
1843
1843
|
<div class="paragraph"><p>Information about the supported application types, startup files, loaders and preloaders are defined in the following places:</p></div>
|
1844
1844
|
<div class="ulist"><ul>
|
@@ -1869,7 +1869,7 @@ The method <span class="monospaced">looks_like_app_directory?</span> in the file
|
|
1869
1869
|
<div class="sect1">
|
1870
1870
|
<span class="anchor_helper" id="instance_state_and_communication"></span><h2 data-anchor="instance_state_and_communication">5. Instance state and communication</h2>
|
1871
1871
|
<div class="sectionbody">
|
1872
|
-
<div class="paragraph"><p>Every time you start Phusion Passenger, you’ve created a new <strong>instance</strong>. Every instance consists of multiple processes that work together (Watchdog,
|
1872
|
+
<div class="paragraph"><p>Every time you start Phusion Passenger, you’ve created a new <strong>instance</strong>. Every instance consists of multiple processes that work together (Watchdog, Passenger core, UstRouter, application processes). All those processes have to be able to communicate with each other. Those processes must also <strong>not</strong> communicate with the processes belonging to other instances. For example, if you start Apache+Passenger <strong>and</strong> Nginx+Passenger, then we don’t want the Passenger core that’s started from Apache to use UstRouter that’s started from Nginx.</p></div>
|
1873
1873
|
<div class="paragraph"><p>Clearly, the processes can’t listen on a specific TCP port for communication. Nor can they listen on a fixed Unix domain socket filename.</p></div>
|
1874
1874
|
<div class="paragraph"><p>That is where the <em>instance directory</em> comes in. Every Phusion Passenger instance has its own, unique temporary directory. That directory is removed when the instance halts. The directory contains Unix domain socket files that the processes listen on. Every Phusion Passenger related process knows where its own instance directory is, and thus, knows how to communicate with other processes belonging to the same instance. The instance directory is implemented in <span class="monospaced">ext/common/InstanceDirectory.h</span>.</p></div>
|
1875
1875
|
<div class="paragraph"><p>Administration tools such as <span class="monospaced">passenger-status</span> query information using instance directories. First, they check which instance directories exist on the system. If they find only one, then they query the sockets inside that sole instance directory. Otherwise, they abort with an error and ask the user to specifically select the instance to query.</p></div>
|
@@ -92,36 +92,36 @@ image:images/passenger_architecture_overview.png[An overview of Phusion Passenge
|
|
92
92
|
|
93
93
|
Phusion Passenger is not a single, monolithic entity. Instead, it consists of multiple components and processes that work together. Part of the reason why Phusion Passenger is split like this, is because it's technically necessary (no other way to implement it). But another part of the reason is stability and robustness. Individual components can crash and can be restarted independently from each other. If we were to put everything inside a single process, then a crash will take down all of Phusion Passenger.
|
94
94
|
|
95
|
-
Thus, if the
|
95
|
+
Thus, if the Passenger core crashes, or if an application process crashes, they can both be restarted without affecting the web server's stability.
|
96
96
|
|
97
97
|
==== Web server module
|
98
98
|
|
99
|
-
When an HTTP client sends a request, it is received by the web server (Nginx or Apache). Both Apache and Nginx can be extended with **modules**. Phusion Passenger provides such a module. The module is loaded into Nginx/Apache. It checks whether the request should be handled by a Phusion Passenger-served web application, and if so, forwards the request to the
|
99
|
+
When an HTTP client sends a request, it is received by the web server (Nginx or Apache). Both Apache and Nginx can be extended with **modules**. Phusion Passenger provides such a module. The module is loaded into Nginx/Apache. It checks whether the request should be handled by a Phusion Passenger-served web application, and if so, forwards the request to the Passenger core. The internal wire protocol used during this forwarding, is a modified version of link:http://en.wikipedia.org/wiki/SCGI[SCGI].
|
100
100
|
|
101
|
-
The Nginx module and Apache module have an entirely different code base. Their code bases are in `ext/nginx` and `ext/apache2`, respectively. Both modules are relatively small because they outsource most logic to the
|
101
|
+
The Nginx module and Apache module have an entirely different code base. Their code bases are in `ext/nginx` and `ext/apache2`, respectively. Both modules are relatively small because they outsource most logic to the Passenger core, and because they utilize a common library (`ext/common`). This allows us to support both Nginx and Apache without having to write a lot of things twice.
|
102
102
|
|
103
|
-
====
|
103
|
+
==== Passenger core
|
104
104
|
|
105
|
-
The **
|
105
|
+
The **Passenger core** is where most of the processing is done. The core keeps track of which application processes currently exist, and using load balancing rules, determines which process a request should be forwarded to. The core also takes care of **application spawning**: if it determines that having more application processes is necessary or beneficial, then it will make that happen. Process spawning is subject to user-configured limits: the core will never spawn more processes than a user-configured maximum.
|
106
106
|
|
107
|
-
The
|
107
|
+
The core also has monitoring and statistics gathering capabilities. It constantly keeps track of applications' memory usage, how many requests they've handled, etc. This information can later be queried from administration tools. And if an application process crashes, the core restarts it.
|
108
108
|
|
109
|
-
The
|
109
|
+
The core is by far the largest and most complex part of the system, but it is itself composed of several smaller subsystems. Most of the <<passenger_core_architecture,core architecture>> chapter is devoted to describing the core.
|
110
110
|
|
111
|
-
====
|
111
|
+
==== UstRouter
|
112
112
|
|
113
|
-
The
|
113
|
+
The core cooperates with the **UstRouter**. This latter is responsible for sending data to link:https://www.unionstationapp.com[Union Station], a monitoring web service. If you didn't explicitly tell Phusion Passenger to send data to Union Station, then the UstRouter sits idle and does not consume resources.
|
114
114
|
|
115
115
|
==== Watchdog
|
116
116
|
|
117
|
-
The
|
117
|
+
The core and the UstRouter contain complex logic, so they could contain bugs which could crash them.
|
118
118
|
So as a safety measure, they are both monitored by the **Watchdog**. If either of them crash, they are restarted by the Watchdog. This setup seeks to ensure that the system stays up, no matter what.
|
119
119
|
|
120
120
|
You might now wonder: what happens if the Watchdog crashes? Shouldn't the Watchdog be monitored by another Watchdog? We've contemplated this possibility, but the Watchdog is very simple, and since 2012 we haven't seen a single report of the Watchdog crashing, nor have we been able to make it crash since that time. So, for the sake of keeping the codebase as simple as possible, we've chosen not to introduce multiple Watchdogs.
|
121
121
|
|
122
122
|
==== Command line tools
|
123
123
|
|
124
|
-
Finally, there is an array of **command line tools** which support Phusion Passenger. The installers -- `passenger-install-*-module` -- are responsible for installing Phusion Passenger. There are administrative tools such as `passenger-status` and `passenger-memory-stats`. And many more. Some of these tools may communicate with one of the agents. For example, the `passenger-status` queries the
|
124
|
+
Finally, there is an array of **command line tools** which support Phusion Passenger. The installers -- `passenger-install-*-module` -- are responsible for installing Phusion Passenger. There are administrative tools such as `passenger-status` and `passenger-memory-stats`. And many more. Some of these tools may communicate with one of the agents. For example, the `passenger-status` queries the core for information that the core has collected. How this communication is done, is described in <<instance_state_and_communication,Instance state and communication>>.
|
125
125
|
|
126
126
|
==== Passenger Standalone
|
127
127
|
|
@@ -129,10 +129,10 @@ You might have noticed that Phusion Passenger Standalone is not part of the diag
|
|
129
129
|
|
130
130
|
=== Build system and source tree
|
131
131
|
|
132
|
-
Phusion Passenger is written mostly in C\++ and Ruby. The web server modules,
|
132
|
+
Phusion Passenger is written mostly in C\++ and Ruby. The web server modules, core, UstRouter and Watchdog are written in C++. Most command line tools are written in Ruby. You can find each component here:
|
133
133
|
|
134
134
|
* The web server modules can be found in `ext/apache2` and `ext/nginx`.
|
135
|
-
* The
|
135
|
+
* The Passenger core, UstRouter and Watchdog can be found in `ext/common/agent`.
|
136
136
|
* The command line tools can be found in `bin`, with some parts of their code in `lib`.
|
137
137
|
|
138
138
|
More information can be found in the link:https://github.com/phusion/passenger/blob/master/CONTRIBUTING.md[Contributors Guide]. This guide also teaches you how to compile Phusion Passenger.
|
@@ -152,33 +152,33 @@ Phusion Passenger initializes as follows.
|
|
152
152
|
* `ext/apache2/Hooks.cpp`, in the constructor for the `Hooks` class.
|
153
153
|
* `ext/common/AgentsStarter.h` and `AgentsStarter.cpp`. Most of the logic pertaining starting the Watchdog is in this file.
|
154
154
|
|
155
|
-
3. The Watchdog first initializes a <<instance_state_and_communication,"instance directory">>, which is a temporary directory containing files that will be used during the life time of this Phusion Passenger instance. For example, the directory contains Unix domain socket files, so that the different Phusion Passenger processes can communicate with each other. The Watchdog is implemented in `ext/common/
|
155
|
+
3. The Watchdog first initializes a <<instance_state_and_communication,"instance directory">>, which is a temporary directory containing files that will be used during the life time of this Phusion Passenger instance. For example, the directory contains Unix domain socket files, so that the different Phusion Passenger processes can communicate with each other. The Watchdog is implemented in `ext/common/agent/Watchdog/Main.cpp`.
|
156
156
|
|
157
|
-
4. The Watchdog starts the
|
157
|
+
4. The Watchdog starts the Passenger core and the UstRouter simultaneously. Each performs its own initialization.
|
158
158
|
|
159
|
-
5. When the
|
159
|
+
5. When the core is done initializing, it will send a message back to the Watchdog saying that it's done. The UstRouter does something similar. When the Watchdog has received both acknowledgment messages, it finishes initialization. If the Watchdog notices that one of the agents have exited without sending an acknowledgment message, then it enters an error state.
|
160
160
|
|
161
161
|
6. The Watchdog reports successful startup back to the Phusion Passenger module that's running inside Nginx/Apache. Or, if initialization didn't success, the Watchdog reports back an error. The Phusion Passenger module inside Nginx/Apache then logs the error.
|
162
162
|
|
163
163
|
After initialization, Phusion Passenger is ready to receive and to process requests.
|
164
164
|
|
165
165
|
|
166
|
-
[[
|
167
|
-
==
|
166
|
+
[[passenger_core_architecture]]
|
167
|
+
== Passenger core architecture
|
168
168
|
|
169
|
-
image:images/
|
169
|
+
image:images/passenger_core_architecture.png[Passenger core architecture]
|
170
170
|
|
171
|
-
The
|
171
|
+
The Passenger core consists of two subsystems. One is the *request handling subsystem*. The other is *the ApplicationPool subsystem*, which performs the bulk of process management. The core also uses a number of support libraries. The largest third-party support libraries are shown in the diagram. Many more -- internal -- support libraries are used, but they're omitted from the diagram. You can find these internal support libraries in the directory `ext/common/Utils`.
|
172
172
|
|
173
173
|
=== Request handling
|
174
174
|
|
175
|
-
Recall that requests are first received from the web server. The web server serializes the request into a slightly modified version of link:http://en.wikipedia.org/wiki/SCGI[the SCGI format], and sends it to the
|
175
|
+
Recall that requests are first received from the web server. The web server serializes the request into a slightly modified version of link:http://en.wikipedia.org/wiki/SCGI[the SCGI format], and sends it to the core's RequestHandler. The RequestHandler performs some work, and eventually sends back a regular HTTP response. The web server parses the RequestHandler response, and sends a response to the original HTTP client.
|
176
176
|
|
177
177
|
The RequestHandler listens on a Unix domain socket file. This Unix domain socket file is called `request`, and is located in <<instance_state_and_communication,the instance directory>>.
|
178
178
|
|
179
179
|
==== One client per request
|
180
180
|
|
181
|
-
The web server creates a new connection to the
|
181
|
+
The web server creates a new connection to the core on every request. Thus, from the viewpoint of the RequestHandler, its client is the web server. Every time a client connects (i.e. a new request is forwarded), the RequestHandler creates a new Client object which represents that request. All request-specific state is stored inside the Client. After the RequestHandler is done processing a request, it closes the client socket.
|
182
182
|
|
183
183
|
Note that in the diagram, a Client has a 0..1 association with RequestHandler. That's because when a Client is disconnected, the pointer to the associated RequestHandler is set to NULL. There might be background operations left which still have a pointer to the Client. As soon as those background operations finish, they check whether the Client has a valid pointer to the RequestHandler. If so, they commit their work; if not, they discard their work. The Client is destroyed when all its associated background operations have finished.
|
184
184
|
|
@@ -257,7 +257,7 @@ The details of the spawning process is described in <<app_spawning_and_loading,A
|
|
257
257
|
[[app_spawning_and_loading]]
|
258
258
|
== Application spawning and loading
|
259
259
|
|
260
|
-
Application processes are spawned from the
|
260
|
+
Application processes are spawned from the Passenger core process. Spawning a process involves a lot of **preparation work**, such as setting up communication channels, setting up the current working directory, environment variables, etc. This preparation work is done by <<spawner_subsystem,a Spawner object>>, together with various support executables.
|
261
261
|
|
262
262
|
When preparation is done, your application's entry point has to be loaded somehow. That loading is done through a language-specific **loader program**. The loader program communicates with the Spawner through the communication channel that was set up earlier, initializes the language-specific environment, sets up a server, and reports back to the Spawner. This communication is done through a certain **protocol**.
|
263
263
|
|
@@ -274,7 +274,7 @@ The communication channel in question is -- from the viewpoint of the (pre)loade
|
|
274
274
|
|
275
275
|
==== Loading SpawnPreparer, possibly through bash
|
276
276
|
|
277
|
-
Because the
|
277
|
+
Because the Passenger core is heavily multi-threaded, the child process has been forked by the Spawner link:http://pubs.opengroup.org/onlinepubs/009695399/functions/fork.html[may only perform async-signal-safe operations]:
|
278
278
|
|
279
279
|
[quote, The Open Group's POSIX specification, fork() man page]
|
280
280
|
"A process shall be created with a single thread. If a multi-threaded process calls fork(), the new process shall contain a replica of the calling thread and its entire address space, possibly including the states of mutexes and other resources. Consequently, to avoid errors, the child process may only execute async-signal-safe operations until such time as one of the exec functions is called. Fork handlers may be established by means of the pthread_atfork() function in order to maintain application invariants across fork() calls."
|
@@ -417,7 +417,7 @@ After reporting readiness, the loader can <<loader_main_loop,enter a main loop a
|
|
417
417
|
|
418
418
|
If something goes wrong in any of the stages, the loader can report an error in two ways:
|
419
419
|
|
420
|
-
1. Just write the error message to stdout as you normally do, and abort without printing the `!> Ready` message. The
|
420
|
+
1. Just write the error message to stdout as you normally do, and abort without printing the `!> Ready` message. The Passenger core will read everything that the loader has written to stdout, and use it as the error message. This error message is considered to be plain text.
|
421
421
|
2. Abort after printing a special `!> Error` message. The loader can signal that the message is HTML. The RequestHandler will format the error message as HTML.
|
422
422
|
|
423
423
|
[[loader_main_loop]]
|
@@ -434,7 +434,7 @@ If the server was listening on a Unix domain socket file, then the loader doesn'
|
|
434
434
|
|
435
435
|
==== Stdout and stderr forwarding
|
436
436
|
|
437
|
-
All lines that the loader writes to stdout, and that are not prefixed with `!> `, are forwarded by the
|
437
|
+
All lines that the loader writes to stdout, and that are not prefixed with `!> `, are forwarded by the Passenger core to its own stdout. Similarly, everything that the loader writes to stderr, whether prefixed with `!> ` or not, is forwarded by the Passenger core to its own stdout.
|
438
438
|
|
439
439
|
While the Spawner is still doing its work, it takes care of this forwarding by itself. Once the Spawner is done, it outsources this work to two PipeWatcher objects, each which spawns a background thread for this purpose.
|
440
440
|
|
@@ -459,7 +459,7 @@ When a spawn command is received, the preloader forks off a child process (which
|
|
459
459
|
[[app_types_registry]]
|
460
460
|
=== The AppTypes registry
|
461
461
|
|
462
|
-
When the web server receives a request, the Phusion Passenger module inside it autodetects the type of application that the request belongs to. It does that by examening the filesystem and checking which one of the startup files exist. For example, if `config.ru` exists, then it assumes that it's a Ruby app. Or if `app.js` exists, then it assumes that it's a Node.js app. The Phusion Passenger module forwards the inferred application type to the
|
462
|
+
When the web server receives a request, the Phusion Passenger module inside it autodetects the type of application that the request belongs to. It does that by examening the filesystem and checking which one of the startup files exist. For example, if `config.ru` exists, then it assumes that it's a Ruby app. Or if `app.js` exists, then it assumes that it's a Node.js app. The Phusion Passenger module forwards the inferred application type to the Passenger core.
|
463
463
|
|
464
464
|
Given an application type, the associated loader and preloader can be looked up.
|
465
465
|
|
@@ -474,7 +474,7 @@ Information about the supported application types, startup files, loaders and pr
|
|
474
474
|
[[instance_state_and_communication]]
|
475
475
|
== Instance state and communication
|
476
476
|
|
477
|
-
Every time you start Phusion Passenger, you've created a new *instance*. Every instance consists of multiple processes that work together (Watchdog,
|
477
|
+
Every time you start Phusion Passenger, you've created a new *instance*. Every instance consists of multiple processes that work together (Watchdog, Passenger core, UstRouter, application processes). All those processes have to be able to communicate with each other. Those processes must also *not* communicate with the processes belonging to other instances. For example, if you start Apache+Passenger *and* Nginx+Passenger, then we don't want the Passenger core that's started from Apache to use UstRouter that's started from Nginx.
|
478
478
|
|
479
479
|
Clearly, the processes can't listen on a specific TCP port for communication. Nor can they listen on a fixed Unix domain socket filename.
|
480
480
|
|
@@ -566,15 +566,15 @@ PassengerThreadCount 195
|
|
566
566
|
|
567
567
|
<p>In certain situations, using the builtin HTTP engine in Passenger Standalone may yield some performance benefits because it skips a layer of processing.</p>
|
568
568
|
|
569
|
-
<p>Passenger normally works by integrating into Nginx or Apache. As described in the <a href="Design%20and%
|
569
|
+
<p>Passenger normally works by integrating into Nginx or Apache. As described in the <a href="Design%20and%20Architecture.html">Design & Architecture</a> document, requests are first handled by Nginx or Apache, and then forwarded to the Passenger core process (the Passenger core) and the application process. This architecture provides various benefits, such as security benefits (Nginx and Apache's HTTP connection handling routines are thoroughly battle-tested and secure) and feature benefits (e.g. Gzip compression, superb static file handling).</p>
|
570
570
|
|
571
571
|
<p>This is even true if you use the Standalone mode. Although it acts standalone, it is implemented under the hood by running Passenger in a builtin Nginx engine.</p>
|
572
572
|
|
573
573
|
<p>However, the fact that all requests go through Nginx or Apache means that there is a slight overhead, which can be avoided. This overhead is small (much smaller than typical application and network overhead), and using Nginx or Apache is very useful, but in certain special situations it may be beneficial to skip this layer.</p>
|
574
574
|
|
575
575
|
<ul>
|
576
|
-
<li>In <strong>microbenchmarks</strong>, the overhead of Nginx and Apache are very noticeable. Removing Nginx and Apache from the setup, and benchmarking against the Passenger
|
577
|
-
<li>In some <strong>multi-server setups</strong>, Nginx and Apache may be redundant. Recall that in typical multi-server setups there is a load balancer which forwards requests to one of the many web servers. Each web server in this setup runs Passenger. But the load balancer is sometimes already responsible for many of the tasks that Nginx and Apache perform, e.g. the secure handling of HTTP connections, buffering, slow client protection or even static file serving. In these cases, removing Nginx and Apache from the web servers and load balancing to the Passenger
|
576
|
+
<li>In <strong>microbenchmarks</strong>, the overhead of Nginx and Apache are very noticeable. Removing Nginx and Apache from the setup, and benchmarking against the Passenger core directly, will yield much better results.</li>
|
577
|
+
<li>In some <strong>multi-server setups</strong>, Nginx and Apache may be redundant. Recall that in typical multi-server setups there is a load balancer which forwards requests to one of the many web servers. Each web server in this setup runs Passenger. But the load balancer is sometimes already responsible for many of the tasks that Nginx and Apache perform, e.g. the secure handling of HTTP connections, buffering, slow client protection or even static file serving. In these cases, removing Nginx and Apache from the web servers and load balancing to the Passenger core directly may have a minor improvement on performance.</li>
|
578
578
|
</ul>
|
579
579
|
|
580
580
|
|
@@ -360,14 +360,14 @@ Phusion Passenger supports out-of-band garbage collection for Ruby apps. With th
|
|
360
360
|
|
361
361
|
In certain situations, using the builtin HTTP engine in Passenger Standalone may yield some performance benefits because it skips a layer of processing.
|
362
362
|
|
363
|
-
Passenger normally works by integrating into Nginx or Apache. As described in the [Design & Architecture](Design%20and%
|
363
|
+
Passenger normally works by integrating into Nginx or Apache. As described in the [Design & Architecture](Design%20and%20Architecture.html) document, requests are first handled by Nginx or Apache, and then forwarded to the Passenger core process (the Passenger core) and the application process. This architecture provides various benefits, such as security benefits (Nginx and Apache's HTTP connection handling routines are thoroughly battle-tested and secure) and feature benefits (e.g. Gzip compression, superb static file handling).
|
364
364
|
|
365
365
|
This is even true if you use the Standalone mode. Although it acts standalone, it is implemented under the hood by running Passenger in a builtin Nginx engine.
|
366
366
|
|
367
367
|
However, the fact that all requests go through Nginx or Apache means that there is a slight overhead, which can be avoided. This overhead is small (much smaller than typical application and network overhead), and using Nginx or Apache is very useful, but in certain special situations it may be beneficial to skip this layer.
|
368
368
|
|
369
|
-
* In **microbenchmarks**, the overhead of Nginx and Apache are very noticeable. Removing Nginx and Apache from the setup, and benchmarking against the Passenger
|
370
|
-
* In some **multi-server setups**, Nginx and Apache may be redundant. Recall that in typical multi-server setups there is a load balancer which forwards requests to one of the many web servers. Each web server in this setup runs Passenger. But the load balancer is sometimes already responsible for many of the tasks that Nginx and Apache perform, e.g. the secure handling of HTTP connections, buffering, slow client protection or even static file serving. In these cases, removing Nginx and Apache from the web servers and load balancing to the Passenger
|
369
|
+
* In **microbenchmarks**, the overhead of Nginx and Apache are very noticeable. Removing Nginx and Apache from the setup, and benchmarking against the Passenger core directly, will yield much better results.
|
370
|
+
* In some **multi-server setups**, Nginx and Apache may be redundant. Recall that in typical multi-server setups there is a load balancer which forwards requests to one of the many web servers. Each web server in this setup runs Passenger. But the load balancer is sometimes already responsible for many of the tasks that Nginx and Apache perform, e.g. the secure handling of HTTP connections, buffering, slow client protection or even static file serving. In these cases, removing Nginx and Apache from the web servers and load balancing to the Passenger core directly may have a minor improvement on performance.
|
371
371
|
|
372
372
|
Nginx and Apache can be removed by using Passenger's builtin HTTP engine. By using this engine, Passenger will listen directly on a socket for HTTP requests, without using Nginx or Apache.
|
373
373
|
|
data/doc/Users guide Apache.html
CHANGED
@@ -1441,7 +1441,7 @@ width:100%;
|
|
1441
1441
|
<td class="tableblock halign-left valign-top"><p class="tableblock">2.6</p></td>
|
1442
1442
|
</tr>
|
1443
1443
|
<tr>
|
1444
|
-
<td class="tableblock halign-left valign-top"><p class="tableblock">Node.js</p></td>
|
1444
|
+
<td class="tableblock halign-left valign-top"><p class="tableblock">Node.js/io.js</p></td>
|
1445
1445
|
<td class="tableblock halign-left valign-top"><p class="tableblock">0.10</p></td>
|
1446
1446
|
</tr>
|
1447
1447
|
<tr>
|
@@ -2048,7 +2048,7 @@ kill PID_OF_FLYING_PASSENGER</pre>
|
|
2048
2048
|
<pre>passenger-memory-stats</pre>
|
2049
2049
|
</div>
|
2050
2050
|
</div>
|
2051
|
-
<div class="paragraph"><p>You should see the web server processes as well as a number of Phusion Passenger processes (e.g.
|
2051
|
+
<div class="paragraph"><p>You should see the web server processes as well as a number of Phusion Passenger processes (e.g. PassengerAgent watchdog, PassengerAgent core). Congratulations, Phusion Passenger is now installed and running!</p></div>
|
2052
2052
|
<div class="paragraph"><p>If the output is not as expected, then please refer to the <a href="#troubleshooting">Troubleshooting</a> section.</p></div>
|
2053
2053
|
</div>
|
2054
2054
|
<div class="sect2">
|
@@ -2137,7 +2137,7 @@ configuration file. However, it doesn’t copy any files to outside the Phusion
|
|
2137
2137
|
<pre>./bin/passenger-memory-stats</pre>
|
2138
2138
|
</div>
|
2139
2139
|
</div>
|
2140
|
-
<div class="paragraph"><p>You should see the web server processes as well as a number of Phusion Passenger processes (e.g.
|
2140
|
+
<div class="paragraph"><p>You should see the web server processes as well as a number of Phusion Passenger processes (e.g. PassengerAgent watchdog, PassengerAgent core). Congratulations, Phusion Passenger is now installed and running!</p></div>
|
2141
2141
|
<div class="paragraph"><p>If the output is not as expected, then please refer to the <a href="#troubleshooting">Troubleshooting</a> section.</p></div>
|
2142
2142
|
</div>
|
2143
2143
|
<div class="sect2">
|
@@ -4078,7 +4078,7 @@ In a virtual host configuration block.
|
|
4078
4078
|
<a href="javascript:void(0)" class="comments empty" title="Add a comment"><span class="count"></span></a><span class="anchor_helper" id="PassengerLoadShellEnvvars"></span><h4 data-comment-topic="passengerloadshellenvvars-on-off--1290yz1" data-anchor="PassengerLoadShellEnvvars">7.4.14. PassengerLoadShellEnvvars <on|off></h4>
|
4079
4079
|
<div class="paragraph"><p><strong>Introduced in version 4.0.20.</strong></p></div>
|
4080
4080
|
<div class="paragraph"><p>Enables or disables the loading of shell environment variables before spawning the application.</p></div>
|
4081
|
-
<div class="paragraph"><p>If this option is turned on, and the user’s shell is <span class="monospaced">bash</span>, then applications are loaded by running them with <span class="monospaced">bash -l -c</span>. Otherwise, they are loaded by running them directly from the <span class="monospaced">
|
4081
|
+
<div class="paragraph"><p>If this option is turned on, and the user’s shell is <span class="monospaced">bash</span>, then applications are loaded by running them with <span class="monospaced">bash -l -c</span>. Otherwise, they are loaded by running them directly from the <span class="monospaced">PassengerAgent core</span> process.</p></div>
|
4082
4082
|
<div class="paragraph"><p>This option may occur in the following places:</p></div>
|
4083
4083
|
<div class="ulist"><ul>
|
4084
4084
|
<li>
|
@@ -4868,7 +4868,7 @@ In <em>.htaccess</em>, if <span class="monospaced">AllowOverride Limits</span> i
|
|
4868
4868
|
queries <span class="monospaced">/proc</span> to obtain additional memory usage information that’s
|
4869
4869
|
not obtainable through <span class="monospaced">ps</span>. You should ensure that the <span class="monospaced">ps</span> works
|
4870
4870
|
correctly and that the <span class="monospaced">/proc</span> filesystem is accessible by the
|
4871
|
-
<span class="monospaced">
|
4871
|
+
<span class="monospaced">PassengerAgent core</span> process.</p></div>
|
4872
4872
|
</td>
|
4873
4873
|
</tr></table>
|
4874
4874
|
</div>
|
@@ -7044,7 +7044,7 @@ Attached process 28303 for app /webapps/foobar.
|
|
7044
7044
|
<div class="sect3">
|
7045
7045
|
<a href="javascript:void(0)" class="comments empty" title="Add a comment"><span class="count"></span></a><span class="anchor_helper" id="_blocking_and_concurrency"></span><h4 data-comment-topic="blocking-and-concurrency-cxpbyu" data-anchor="_blocking_and_concurrency">10.9.3. Blocking and concurrency</h4>
|
7046
7046
|
<div class="paragraph"><p>Except when otherwise documented, all hooks block in the background. That is, while your hook command is running, Phusion Passenger can still handle web requests, but the background thread which is running your hook will be blocked and won’t be able to perform any further operations. For example, if you wrote a hook script for the <span class="monospaced">attached_process</span> event, then Phusion Passenger won’t be able to attach further processes until your hook script finishes. You should therefore be careful when writing hook scripts.</p></div>
|
7047
|
-
<div class="paragraph"><p>If you have a bug in your script and it blocks, then you will be able to see that using the command <span class="monospaced">passenger-status --show=backtraces</span> which prints the backtraces of all threads in the Phusion Passenger
|
7047
|
+
<div class="paragraph"><p>If you have a bug in your script and it blocks, then you will be able to see that using the command <span class="monospaced">passenger-status --show=backtraces</span> which prints the backtraces of all threads in the Phusion Passenger core. Look for the <span class="monospaced">runSingleHookScript</span> function in the backtrace. The following example shows at line 2 that Phusion Passenger is waiting for the hook script <span class="monospaced">/home/phusion/badscript.sh</span>.</p></div>
|
7048
7048
|
<div class="listingblock">
|
7049
7049
|
<div class="content monospaced">
|
7050
7050
|
<pre>Thread 'Group process spawner: /home/phusion/webapp.test#default' (0x1062d4000):
|
@@ -7071,7 +7071,7 @@ Attached process 28303 for app /webapps/foobar.
|
|
7071
7071
|
</dt>
|
7072
7072
|
<dd>
|
7073
7073
|
<p>
|
7074
|
-
Called at the very beginning of Phusion Passenger’s life cycle, during the start of the Watchdog process. The first hook is called before initialization is performed (before the
|
7074
|
+
Called at the very beginning of Phusion Passenger’s life cycle, during the start of the Watchdog process. The first hook is called before initialization is performed (before the Passenger core is started). Errors in the hook script cause Phusion Passenger to abort.
|
7075
7075
|
</p>
|
7076
7076
|
</dd>
|
7077
7077
|
<dt class="hdlist1">
|
@@ -7578,13 +7578,25 @@ Phusion Passenger’s installer, build system and administration tools are writt
|
|
7578
7578
|
<p>
|
7579
7579
|
Certain internally used tools, such as the crash handler (which generates a backtrace in case Phusion Passenger crash) and the prespawn script (used to implement
|
7580
7580
|
<a href="#PassengerPreStart">PassengerPreStart</a>)
|
7581
|
+
are written in Ruby as well.
|
7582
|
+
</p>
|
7583
|
+
</li>
|
7584
|
+
<li>
|
7585
|
+
<p>
|
7586
|
+
Ruby web application support is implemented in Ruby.
|
7587
|
+
</p>
|
7588
|
+
</li>
|
7589
|
+
<li>
|
7590
|
+
<p>
|
7591
|
+
If you use <a href="#flying_passenger">Flying Passenger</a>, then the Flying Passenger daemon is written in Ruby. The daemon is a small (less than 500 lines of code) and offloads most tasks to the C++ core.
|
7592
|
+
</p>
|
7593
|
+
</li>
|
7594
|
+
<li>
|
7595
|
+
<p>
|
7596
|
+
If you use <a href="Users%20guide%20Standalone.html">Phusion Passenger Standalone</a>, then the frontend (the <span class="monospaced">passenger</span> command) is written in Ruby. The frontend is small (less than 1500 lines of code) and offloads most tasks to the C++ core.
|
7581
7597
|
</p>
|
7582
7598
|
</li>
|
7583
7599
|
</ul></div>
|
7584
|
-
<div class="paragraph"><p>are written in Ruby as well.
|
7585
|
-
* Ruby web application support is implemented in Ruby.
|
7586
|
-
* If you use <a href="#flying_passenger">Flying Passenger</a>, then the Flying Passenger daemon is written in Ruby. The daemon is a small (less than 500 lines of code) and offloads most tasks to the C<span class="monospaced"> core.
|
7587
|
-
* If you use <a href="Users%20guide%20Standalone.html">Phusion Passenger Standalone</a>, then the frontend (the <span class="monospaced">passenger</span> command) is written in Ruby. The frontend is small (less than 1500 lines of code) and offloads most tasks to the C</span> core.</p></div>
|
7588
7600
|
<div class="paragraph"><p>Other than the aforementioned aspects, Phusion Passenger does not use Ruby during normal operation. For example, if you run Python WSGI web applications on Phusion Passenger, then there will be (almost) no Ruby code running on the system.</p></div>
|
7589
7601
|
</div>
|
7590
7602
|
<div class="sect3">
|
@@ -8380,7 +8392,7 @@ NOTE: Make sure your <span class="monospaced">~/.bashrc</span> is actually inclu
|
|
8380
8392
|
</div>
|
8381
8393
|
<div class="paragraph"><p>On Debian and Ubuntu, with an Apache installed through apt, Apache environment variables are defined in the file <span class="monospaced">/etc/apache2/envvars</span>. This is a shell script so environment variables must be specified with the shell syntax.</p></div>
|
8382
8394
|
<div class="paragraph"><p>On Red Hat, Fedora, CentOS and ScientificLinux, with an Apache installed through YUM, Apache environment variables are defined in <span class="monospaced">/etc/sysconfig/httpd</span>.</p></div>
|
8383
|
-
<div class="paragraph"><p>On OS X they are defined in <span class="monospaced">/System/Library/LaunchDaemons/org.apache.httpd.plist</span>, as explained <a href="/
|
8395
|
+
<div class="paragraph"><p>On OS X they are defined in <span class="monospaced">/System/Library/LaunchDaemons/org.apache.httpd.plist</span>, as explained <a href="http://stackoverflow.com/questions/6833939/path-environment-variable-for-apache2-on-mac">here on Stack Overflow</a>.</p></div>
|
8384
8396
|
<div class="paragraph"><p>On other systems, or if you did not install Apache through the system’s package manager, the configuration file for environment variables is specific to the vendor that supplied Apache. There may not even be such a configuration file. You should contact the vendor for support.</p></div>
|
8385
8397
|
</div>
|
8386
8398
|
<div class="sect3">
|