In front of (b) We have learned that the lifetime of the variable value container is bound to the request, but I was deliberately avoiding the formal definition of "request". Everyone should have been by default the "request" here refers to the HTTP request initiated by the client. There are actually two types of "requests" in the Nginx world, one called "Master Request" and the other called "Subrequest". Let's introduce them first.
The so-called "master Request" is a request initiated by an HTTP client from the Nginx external. All of the examples we see earlier involve only "master requests", including (ii) the two examples of "internal jumps" that were initiated using the echo_exec and rewrite directives.
A "sub-request" is a cascade request that is initiated within Nginx by the request that Nginx is processing. A "sub-request" looks like an HTTP request, but it doesn't have anything to do with the HTTP protocol or even network traffic. It is an abstract call inside Nginx, in order to facilitate the user to break down the task of "master request" into several smaller granular "internal requests", to access multiple interfaces concurrently or serially, location
and then location
work together to complete the whole "master request" by these interfaces. Of course, the concept of "sub-request" is relative, and any "sub-request" can also initiate more "sub-sub-requests", and even can play recursive calls (that is, they call themselves). When a request initiates a "sub-request", it is customary to refer to the former as the "parent request" of the latter, according to Nginx's terminology. It is worth mentioning that the Apache server actually has the concept of "sub-request", so readers from the Apache world should not be unfamiliar with this.
Here's an example that uses a "sub-request":
Location/main {
Echo_location/foo;
Echo_location/bar;
}
Location/foo {
echo foo;
}
Location/bar {
Echo Bar;
}
Here location /main
, the echo_location instruction of the third-party Ngx_echo module is initiated to /foo
the /bar
GET
"sub-request" of the type of the two interfaces respectively. A "sub-request" initiated by Echo_location, whose execution is serially processed in the order in which the configuration is written, that the request is processed only after the request has been /foo
processed /bar
. The output of these two "sub-requests" is stitched together in order of execution as /main
the final output of the interface:
$ Curl ' Http://localhost:8080/main '
Foo
Bar
We see that the "sub-request" mode of communication is carried out within the same virtual host, so the Nginx core in the implementation of "sub-request", only a number of C functions are called, completely do not involve any network or UNIX sockets (socket) communication. From this we can see that "sub-request" Execution efficiency is very high.
Back to the previous discussion of the lifetime of the Nginx variable value container, we can still say that their lifetimes are associated with the current request. Each request has a separate copy of all the variable value containers, except that the current request can be either a "master request" or a "child request". Even between parent and child requests, variables of the same name do not interfere with each other generally. Let's go through a little experiment to prove the idea:
location /main {
set $var main;
echo_location /foo;
echo_location /bar;
echo "main: $var";
}
location /foo {
set $var foo;
echo "foo: $var";
}
location /bar {
set $var bar;
echo "bar: $var";
}
In this example, we separately set the /main
/foo
/bar
location
different values and output the same name variables in the three configuration blocks $var
. In particular, in the /main
interface, we deliberately after the invocation /foo
and the /bar
two "sub-requests", and then output its own $var
value of the variable. The /main
result of the request interface is this:
$ Curl ' Http://localhost:8080/main '
Foo:foo
Bar:bar
Main:main
Obviously, /foo
and the /bar
two "sub-requests" in the processing of the variables of $var
each of the changes did not affect the "master request /main
." This success confirms that the "master request" and each "sub-request" have different variables of the $var
value of the container copy.
Unfortunately, some Nginx module-initiated "Sub-request" will automatically share its "parent request" variable value container, such as third-party module NGX_AUTH_REQUEST. Here is an example:
Location/main {
Set $var main;
Auth_request/sub;
echo "main: $var";
}
location/sub {
Set $var sub;
echo "Sub: $var";
}
Here we first assign the initial value to the variable in the /main
interface, $var
main
then use the configuration instruction provided by the Ngx_auth_request module auth_request
, initiate a /sub
"sub-request" to the interface, and finally use the echo instruction to output $var
the value of the variable. And we /sub
deliberately rewrite the value of the variable in the interface $var
sub
. /main
The result of the access interface is as follows:
$ Curl ' Http://localhost:8080/main '
Main:sub
We see that the interface's modification of the /sub
$var
value of the variable affects the master request /main
. So the "sub-request" initiated by the Ngx_auth_request module is indeed a value container that shares a set of Nginx variables with its parent request.
For this example, it is believed that a reader would ask, "why is the output of ' sub-request ' /sub
not appearing in the final output?" The answer is simple, because the auth_request
instruction automatically ignores the response body of the sub-request, and only checks the response status code of the sub-request. When the status code is 2XX
, the auth_request
instruction ignores the "sub-request" and lets Nginx continue processing the current request, otherwise it will immediately interrupt the execution of the current (master) request, and return the corresponding error page. In our example, /sub
the "sub-request" Simply uses the echo command to make some output, so it implicitly returns the status code that indicates the normal 200
.
such as the Ngx_auth_request module, the parent-child request to share a set of Nginx variable behavior, although the parent-child request between the two-way transfer of data is extremely easy, but for enough complex configuration, but also often lead to many difficult to debug the strange bug. Because the user often does not know the "parent request" the value of an Nginx variable, in fact, it has been accidentally modified in one of its "sub-request". The bad "side effects" caused by sharing, and many third-party modules, including Ngx_echo,ngx_lua, and Ngx_srcache, have chosen to disable variable sharing between parent-child requests.
Discussion on Nginx variable (v)