preface
Recently, Nginx has been used in my work, but the routing configuration is special and the business scenarios are complex. Here are a few examples: How to configure multiple services on one machine, using the same port and different domain names? What about the same server molecule domain name? So how do you determine which location it matches? Redirection and proxy can both jump to a specific address, so which one to use? With these problems in mind, I focused on the configuration of nginx jump, which is convenient for technology selection and decision making. In this article, we’ve sorted out four ways to do it, and we believe that one of them will meet your needs.
1. Configure the domain name corresponding to the server
Server name indicates the identification path of the virtual server. Therefore, different domain names are matched to specific server blocks through the HOST field in the request header and forwarded to the corresponding application server. Server_name Matching rule: Multiple domain names can be followed. The first one is the primary domain name
1.1. Accurate matching
The nginx configuration is as follows
listen 8080; server_name test1.com; location / { return 200 "I am test1! \n"; } } server { listen 8080; server_name my.test.com; location / { return 200 "I am mytest! \n"; }}Copy the code
Request the results
Curl http://my.test.com:8080 return: I am mytest! Curl http://test1.com:8080 return: I am test1!Copy the code
1.2. Regular expressions
- The longest string starting with * is shown in the following example
server {
listen 8080;
server_name test1.*;
location / {
return 200 "I am test1!\n";
}
}
Copy the code
- The longest string ending with * wildcard
listen 8080;
server_name *.test.com;
location / {
return 200 "I am mytest!\n";
}
}
Copy the code
- Wildcard names may contain only an asterisk at the beginning or end of the name, separated from other characters by dots. So, “my.*.com” is illegal.
For example, server_name my.*.com; The following error is reported:
Nginx: [emerg] invalid server name or wildcard "my.*.com" on 0.0.0.0:8080Copy the code
- Matching regular expressions
server {
listen 8080;
server_name ~^my(?<serno>.+).mydomain.com$;
location / {
return 200 $serno;
}
}
Copy the code
explain
- ~: indicates a case-sensitive re;
- ^: matches the beginning of the string;
- {.+}: any self-reading repetition outside the newline more times;
- () : grouping and value;
- : indicates escape;
- Serno: Sets the extracted variable;
- $: the end of the matching string;
Request the results
Curl http://my02.mydomain.com:8080 return: 02% curl http://my03.mydomain.com:8080 return: 03%Copy the code
- What is the configuration order of server_name?
Match in the following order: Match order -> -> Exact match -> first domain name -> next domain name -> Match in the order in the file -> Default server: first, listen specifies default
Configure location
2.1. Location Matching rule: Only URIs are matched, and parameters are ignored
The location [= | | | ~ ~ * ^ ~] / uri / {... }Copy the code
The matching re symbol is as follows:
- = strict match. If the request matches this location, the search is stopped and the request is processed immediately
- ~ Case-sensitive matching (regular expression available)
- ~* Case insensitive matching (regular expression available)
- ! ~ Case sensitive mismatch
- ! ~* Is case insensitive and does not match
- ^~ If you use this prefix for a regular string, then tell Nginx not to test the regular expression if the path matches
2.2, for example,
1, match any request location [= | | | ~ ~ * ^ ~] / uri / {... } 2, case-insensitive matching end with js, PHP, request the location ~ *. (js) | PHP ${... } location ~ ^.+\.txt$Copy the code
2.3. The matching sequence is shown below
The following location is configured according to the above rules
location = /documents {
return 200 'configuration A'
}
location /documents {
return 200 'configuration B'
}
location /documents/txt1 {
return 200 'configuration C'
}
location ^~ /documents/ {
return 200 'configuration D'
}
location ~* /documents/(\w+)$ {
return 200 'configuration E'
}
location ~ /documents/$ {
return 200 'configuration F'
}
Copy the code
- Curl Test1.com :8080/ Documents A
- Curl test1.com: 8080 / documents/on ^ ~ match after match, returns the configuration D
- The curl test1.com: 8080 / documents/t… Return to Configuration E if/Documents/TXT1 does not go to the re match
- The curl test1.com: 8080 / documents/t… C, because the re doesn’t match
2.4. How to debug re?
Compile with a –with-debug option, such as./configure –with-debug conf file with a host to debug, and debug_Connection for the connection to debug.
events {
worker_connections 1024;
debug_connection 192.168.1.3;
debug_connection 127.0.0.1;
}
Copy the code
Error. log Displays debug logs. In the figure, the test location is the matching process
Rewrite
The syntax is as follows:
Syntax: rewrite regex replacement[flag]; Default: None Position: server, location, if Rewrite is an important directive to implement URL redirects. It jumps to replacement based on regex(regular expressions) matching content, ending with flag flags.Copy the code
Flag tag | instructions |
---|---|
last | After this rule is matched, continue to match new location URI rules |
break | This rule is terminated after the match is complete. Task rules are no longer matched |
redirect | Returns 302 temporary redirection |
permanent | Returns a 301 permanent redirect |
3.1 redirection
Return Three types of code: code URL and URL. Return status code: 444 indicates closed connection. 301 indicates HTTP1. 0 for permanent redirection, 302 for temporary redirection, base cache. After http1.1, 303 indicates temporary redirection, which allows method change, base cache, 307 indicates temporary redirection, which does not allow method change, which does not allow caching, 308 indicates permanent redirection, which does not allow method change.
- Return code
location / {
return 301 https://www.xxxx.com$request_uri;
}
Copy the code
- Matches all URIs with the $request_URI variable.
rewrite ^ https://www.xxxx.com$request_uri? permanent;
Copy the code
- After matching all urIs with the re, remove the leading /(backslash).
rewrite ^/(.*)$ https://www.xxxx.com/$1;
Copy the code
- Combined with the if instruction
server {
listen 80;
server_name test1.net test2.net;
if ($host != 'test1.net' ) {
rewrite ^/(.*)$ http://www.baidu.net/$1 permanent;
}
}
Copy the code
3.2. How to view the rewrite log
Enable the log function rewrite_log on. Can be configured to the HTTP server, the location and the if the context example: curl test1.com: 8080 / first / 2. TXT
location /first {
rewrite_log on;
rewrite /first(.*) /second$1 last;
}
Copy the code
The renderings are as follows
4. Configure proxy
Reverse proxy is implemented for upstream services using HTTP or HTTPS. Proxy_pass is followed by a URL that can mimic location, if in location, and limit_except contexts. This feature is compiled into Nginx by default. This article focuses on HTTP proxies.
Url parameter rules
- The URL must start with HTTP or HTTPS, followed by the domain name, IP, Unix socket or upstream, all of which can be ports. This is followed by the optional URI
HTTP example proxy_pass http://localhost:8000/uri/; UNIX domain socket path to define sample proxy_pass http://unix:/tmp/backend.socket:/uri/;
- Nginx will not partially proxy the path matching proxy_pass, if/is added to the url after proxy_pass, which equals the absolute root path. If there is no /, part of the matching path is given to the agent.
The directory structure is as follows
├─ first │ ├─ index.html ├─ second │ ├─ index.htmlCopy the code
The nginx configuration is as follows
server { listen 8081; server_name my.test.com; } server { listen 8082; Location /first {proxy_pass http://my.test.com:8081; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } # location /first {proxy_pass http://my.test.com:8081/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; }}Copy the code
Don’t take /, then curl http://127.0.0.1:8082/first/index.html return index HTML
Take /, then curl http://127.0.0.1:8082/first/index.html return first index
-
Url parameters can carry variables proxy_pass http://$host$uri;
-
Rewrite break statement can be used
location /nameb/ { rewrite /nameb/([^/]+) /test? nameb=$1 break; Proxy_pass http://127.0.0.1:8801/; }Copy the code
Five, the summary
Nginx routing can be configured using server_name, location, or rewrite. There is also the configuration of proxy proxy, forwarding ID in the proxy. Server_name = server_name = server_name = server_name = server_name = server_name = server_name The matching order of location can be referred to the flow chart in the article; In the case of redirect, the client will request the resource specified by 302 and URL, but proxy does not. Therefore, in the scenario of Nginx + Tomcat, Proxy is more suitable.