JIYIK CN >

Current Location:Home > Learning > NETWORK >

In-depth understanding of Nginx Location block matching algorithm

Author:JIYIK Last Updated:2025/03/17 Views:

Similar to the process that Nginx uses to select the Server block that will handle a request  , Nginx also has an established algorithm to decide which Location block within a Server block to use to handle a request.

location block syntax

Before we discuss how Nginx decides which location block to use to handle a request, let's review some of the syntax you might see in a location block definition. A location block is located within a server block (or other location blocks) and is used to decide how to handle the request URI (the portion of the request that comes after the domain name or IP address/port).

A location block typically takes the following form:

location optional_modifier location_match {

    . . .

}

The above location_matchdefines the object that Nginx should check for the request URI. The presence or absence of the modifiers in the above example affects the way Nginx tries to match the location block.

  • (none) : If no modifier is present, the location is interpreted as a prefix match. This means that the given location will be matched against the beginning of the request URI to determine a match.
  • = : Using the equal sign, if the request URI exactly matches the given location, this block will be considered a match.
  • ~ : If the tilde modifier is present, this location is interpreted as a case-sensitive regular expression match.
  • ~* : If the tilde and asterisk modifiers are used, the location block is interpreted as a case-insensitive regular expression match.
  • ^~ : If both the ^ and tilde (~) modifiers are present, and if the block is selected as the best non-regular expression match, no regular expression matching is done.

Location Block Syntax Examples

As an example of prefix matching, the following location block might be selected in response to a request URI like /site, /site/page1/index.html, or /site/index.html:

location /site {

    . . .

}

To demonstrate exact request URI matching, this block will always be used in response to a request URI that looks like /page1. It will not be used in response to a request URI like /page1/index.html. Remember, if this block is selected and a request is fulfilled with the index page, an internal redirect will jump to another location, which will be the actual handler for the request:

location = /page1 {

    . . .

}

As an example of where a regular expression should be interpreted as case-sensitive , this block would work for a request for /tortoise.jpg but not for /FLOWER.PNG:

location ~ \.(jpe?g|png|gif|ico)$ {

    . . .

}

The following shows a block that allows case-insensitive matching similar to the above. Here, both /tortoise.jpg and /FLOWER.PNG can be handled by this block:

location ~* \.(jpe?g|png|gif|ico)$ {

    . . .

}

Finally, this block will not do a regular expression match if a non-regular expression match is determined to be the best. It can handle a request for /costumes/ninja.html:

location ^~ /costumes {

    . . .

}

As you can see, the modifiers indicate how the location block should be parsed. However, this does not tell us the algorithm that Nginx uses to decide which location block to send the request to. We will discuss this next.

How does Nginx choose which location to use to handle a request?

Nginx selects the location block that it will use to serve a request in a similar manner to how it selects a server block. It has a process for determining the best location block for any given request. Understanding this process is a key requirement for being able to reliably and accurately configure Nginx.

Remembering the types of location declarations we described above, Nginx evaluates possible contexts by comparing the request URI to each location block. It does this using the following algorithm:

  • Nginx first checks all prefix-based location matches (all location types that do not involve regular expressions). It checks each location against the full request URI.
  • First, Nginx looks for an exact match. If a location block using the = modifier is found that exactly matches the request URI, this block is immediately selected to serve the request.
  • If no exact (using the = modifier) ​​location block match is found, Nginx then proceeds to evaluate inexact prefixes. It finds the longest matching prefix block for the given request URI and then checks as follows:
  • If the longest matching prefix location has ^~a modifier, Nginx will end the search immediately and select that location block to serve the request.
  • If the longest matching prefix position is not used with ^~the modifier, the match is temporarily stored by Nginx so that the focus of the search can be shifted.
  • After determining and storing the longest matching prefix location, Nginx proceeds to check regular expression locations (both case-sensitive and case-insensitive). If there are any regular expression locations in the longest matching prefix block, Nginx moves those to the top of its regular expression location list for checking. Nginx then tries to match regular expression locations in order. The first regular expression location that matches the request URI is immediately selected to serve the request.
  • If no regular expression location matching the request URI is found, a previously stored prefix location is selected to serve the request.

It is important to understand that, by default, Nginx will prioritize regular expression matching over prefix matching. However, it evaluates the prefix location first, allowing administrators to override this tendency by specifying the location using the =and modifiers.^~

It is also important to note that while the prefix location is usually chosen based on the longest, most specific match, regular expression matching stops when the first match is found. This means that the locations in the configuration have a large impact on the regular expression locations.

Finally, it is important to understand that when Nginx evaluates regular expressions, the regular expression matches within the longest prefix match will "jump the line." These will be evaluated in order before any other regular expression matches are considered.

When does the evaluation of a location block jump to another location?

只有选定的 location 和继承的指令确定如何处理请求,而不受兄弟 location 块的干扰。

尽管这是一条允许我们以可预测的方式设计location块的一般规则,但重要的是要意识到有时新的 location 搜索会由所选块内的某些指令触发。 “只有一个location块”规则的例外情况可能会影响请求的实际服务方式,并且可能与我们在设计location块时的期望不一致。

一些可能导致这种类型的内部重定向的指令是:

  • index
  • try_files
  • rewrite
  • error_page

如果 index 指令用于处理请求,它总是会导致内部重定向。 精确匹配通常用于通过立即结束算法的执行来加速选择过程。 但是,如果进行目录的精确匹配,则请求很有可能被重定向到不同的块来实际进行处理。

在这个例子中,第一个location由 /exact 的请求 URI 匹配,但为了处理请求,块继承的 index 指令会启动到第二个块的内部重定向:

index index.html;

location = /exact {

    . . .

}

location / {

    . . .

}

在上述情况下,如果确实需要执行停留在第一个块中,我们将不得不想出一种不同的方法来满足对目录的请求。 例如,可以为该块设置无效 index 并打开autoindex

location = /exact {
    index nothing_will_match;
    autoindex on;
}

location  / {

    . . .

}

这是防止索引切换上下文的一种方法,但它可能对大多数配置没有用。 大多数情况下,目录上的完全匹配可能有助于重写请求(这也会导致新的位置搜索)。

可以重新评估处理location的另一个实例是使用 try_files 指令。 该指令告诉 Nginx 检查是否存在命名的文件或目录集。 最后一个参数可以是 Nginx 将进行内部重定向的 URI。

看下面的配置

root /var/www/main;
location / {
    try_files $uri $uri.html $uri/ /fallback/index.html;
}

location /fallback {
    root /var/www/another;
}

在上面的示例中,如果对 /blahblah 发出请求,则第一个location最初会收到请求。 它将尝试在 /var/www/main 目录中找到一个名为 blahblah 的文件。 如果找不到,它将通过搜索名为 blahblah.html 的文件来跟进。 然后它将尝试查看 /var/www/main 目录中是否有一个名为 blahblah/ 的目录。 如果所有这些尝试都失败,它将重定向到 /fallback/index.html。 这将触发另一个location搜索,该搜索将被第二个块捕获。 这将提供文件 /var/www/another/fallback/index.html

另一个可能导致 location 块传递的指令是 rewrite 指令。 当使用 rewrite 指令的最后一个参数时,或者根本不使用参数时,Nginx 将根据 rewrite 的结果搜索新的匹配块。

例如,如果我们修改最后一个示例使其包含 rewrite,我们可以看到请求有时会直接传递到第二个location块,而不依赖于 try_files 指令:

root /var/www/main;
location / {
    rewrite ^/rewriteme/(.*)$ /$1 last;
    try_files $uri $uri.html $uri/ /fallback/index.html;
}

location /fallback {
    root /var/www/another;
}

在上面的示例中,对 /rewriteme/hello 的请求最初将由第一个 location 块处理。它将被重写为 /hello 并搜索一个块。在这种情况下,它将再次匹配第一个 location 并像往常一样由 try_files 处理,如果没有找到可能会返回到 /fallback/index.html(使用我们上面讨论的 try_files 内部重定向)。

但是,如果对 /rewriteme/fallback/hello 发出请求,第一个块将再次匹配。再次应用重写,这一次导致 /fallback/hello。然后将在第二个location块之外提供请求。

发送 301 或 302 状态代码时,return 指令会发生相关情况。这种情况下的不同之处在于,它会以外部可见重定向的形式产生一个全新的请求。在使用 redirectpermanent 标志时,rewrite 指令可能会发生同样的情况。然而,这些location 搜索不应该是意料之外的,因为外部可见的重定向总是会产生一个新的请求。

error_page 指令可以导致类似于 try_files 创建的内部重定向。该指令用于定义遇到某些状态代码时应该发生的情况。如果设置了 try_files,这可能永远不会执行,因为该指令处理请求的整个生命周期。

我们看下面的例子

root /var/www/main;

location / {
    error_page 404 /another/whoops.html;
}

location /another {
    root /var/www;
}

每个请求(除了那些以 /another 开头的请求)都将由第一个块处理,该块将提供来自 /var/www/main 的文件。 但是,如果未找到文件(404 状态),则会发生内部重定向到 /another/whoops.html,从而导致新的location搜索并最终会落在第二个块上。 该文件将从 /var/www/another/whoops.html 提供。

如我们所见,了解 Nginx 触发新location搜索的情况有助于预测在发出请求时会看到的行为。

总结

了解 Nginx 处理客户端请求的方式可以使我们作为管理员的工作更加轻松。 能够知道 Nginx 将根据每个客户端请求选择哪个Server 块。 还可以根据请求 URI 判断如何选择 location 块。 总体而言,了解 Nginx 选择不同块的方式将使我们能够跟踪 Nginx 上下文,应用这些更好的为每个请求提供服务。

For reprinting, please send an email to 1244347461@qq.com for approval. After obtaining the author's consent, kindly include the source as a link.

Article URL:

Related Articles

Nginx load balancing settings

Publish Date:2025/03/18 Views:198 Category:NETWORK

At this stage, load balancing is a widely used technology. Nginx, as a load balancing server for http, is being used more and more widely. There are three ways to set up Nginx load balancing: Round-robin - This method distributes access req

Nginx load balancing health_check analysis

Publish Date:2025/03/18 Views:54 Category:NETWORK

In Nginx load balancing, it is difficult to guarantee that every application server can run normally all the time. However, we can set Nginx to detect these application servers and detect which of them are inaccessible. There are two ways t

HTTP2 Tutorial - How to Configure HTTP2 with Nginx

Publish Date:2025/03/17 Views:195 Category:NETWORK

HTTP2 was officially released in 2015. If your website is still using HTTP/1.1, you may be out of date. Don't worry, here we will see how to use Nginx to upgrade your website to HTTP2. Install Nginx I feel that this column is redundant. Sin

Deep understanding of Nginx's server block selection algorithm

Publish Date:2025/03/17 Views:95 Category:NETWORK

Nginx is one of the most popular web servers in the world. It can successfully handle high loads with many concurrent client connections and can be used as a web server, mail server, or reverse proxy server. In this article, we will discuss

Nginx is running but not serving sites

Publish Date:2025/03/17 Views:86 Category:NETWORK

We recently installed nginx version 1.17 on a new machine. The configuration created in sites-available` was symlinked to `sites-enabled`, but nginx is not serving any domains.

How Nginx and uWISG servers work together

Publish Date:2025/03/17 Views:70 Category:NETWORK

Nginx and uWISG are two commonly used server software that can work together to provide more stable and efficient network services. This article will introduce in detail the working principle of Nginx and uWISG, and how to configure them to achieve op

Scan to Read All Tech Tutorials

Social Media
  • https://www.github.com/onmpw
  • qq:1244347461

Recommended

Tags

Scan the Code
Easier Access Tutorial