In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-03-18 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Servers >
Share
Shulou(Shulou.com)06/01 Report--
This article mainly explains "Tengine how to find server blocks", the content of the explanation is simple and clear, easy to learn and understand, the following please follow the editor's ideas slowly in depth, together to study and learn "Tengine how to find server blocks" bar!
Overview
The target readers of this article are Tengine/Nginx R & D or OPS students. If you are very clear about this logic, you can skip it. If you have the following questions in the process of configuring or developing Tengine/Nginx, this article may be able to answer your questions for many years:
Which server block does the request arrive to match?
Why is it that the server block is configured, but it still doesn't work?
There is no server block for this domain name. Which server block is used in the request?
If you want to match server blocks yourself, where should I start?
……
Problems related to such server blocks may be encountered frequently when using Tengine. When configuring fewer server blocks, it is easier to identify them. However, in scenarios such as CDN or cloud platform access layer, there are generally a large number of configured server blocks, ranging from dozens to hundreds to thousands more, so understanding how Tengine looks up server blocks is very helpful for troubleshooting daily problems.
Configuration
Let's take a look at a few configurations:
Server {listen 10.101.192.91 default_server; listen 80 default_server; listen 8080 default_server; server_name www.aa.com; default_type text/plain; location / {return 200 "default-server: $server_name, host: $host";} server {listen 10.101.192.91 default_server; listen 80; server_name www.bb.com; default_type text/plain Location / {return 200 "80server: $server_name, host: $host";}} server {listen 10.101.192.91 8080server 8080; server_name * .bb.com; default_type text/plain; location / {return 200 "8080server: $server_name, host: $host";}} server {listen 10.101.192.91 80server 8080; server_name www.bb.com Default_type text/plain; location / {return 200 "8080server: $server_name, host: $host";}}
There are four server blocks configured above, and the configuration is also very simple. The first server block is configured with the default_server parameter, which indicates that this is the default server block (exactly, the default server block for requests coming in from the IP:Port of this listen), listens for two ports 80 and 8080, the matching domain name is www.aa.com, and the second listens for 10.101.192.91 server block with matching domain name www.bb.com. The third is the server block that listens to 10.101.192.91 server 8080 and matches the pan-domain name *. Bb.com, and the fourth is the server block that listens to 10.101.192.91 www.bb.com and matches the exact domain name. Let's verify this:
As can be seen:
The first server block is accessed by both 127.0.0.1 and 127.0.0.1
This is because the first server listens on ports 80 and: 8080, other server blocks do not listen on the corresponding port 127.0.0.1, and 127.0.0.1 access can only match the first server block.
10.101.192.91 server 80 access. The corresponding server block is used when the domain name is matched with the server block, and the first default server block is used when the domain name is mismatched.
If the IP:Port matches, then match to the server block where the domain name is located. If the domain name does not match with the server_name, the default server block is matched.
10.101.192.91 bb.com 8080 access, the domain name first accurately matches the server block of www.bb.com, and then matches the server block of pan-domain name * .bb.com. The third implicit default server block is used when there is a mismatch.
Here, the universal domain name and the implicit default server block are involved. The matching of the universal domain name is after the exact domain name, which is easy to understand. The implicit default server block is a server block that does not specify the default_server parameter after the listen. When Tengine/Nginx parses the configuration, each IP:Port has a default server block. If the default_server parameter is explicitly specified after the listen, the server in which the listen is located is the default server block of the IP:Port. If the default_server parameter is not explicitly specified, the first server block of the IP:Port is the implicit default server block.
The above configurations can derive some debug techniques:
If ($http_x_alicdn_debug_get_server = "on") {return 200 "$server_addr:$server_port, server_name: $server_name";}
As long as you take the request header X-Alicdn-Debug-Get-Server: on to know which server block the request hit, this configuration is very useful for the system debug where there are a lot of server blocks, it is important to note that this configuration needs to be put into a configuration file and loaded with server_auto_include, and then tengine will automatically take effect on all server blocks (nginx does not have similar configuration commands).
Data structure
Let's take a look at how the configuration of the http core module server block is related to the data structure, which is as follows:
Typedef struct {/ * array of the ngx_http_server_name_t, "server_name" directive * / ngx_array_t server_names; / * server ctx * / ngx_http_conf_ctx_t * ctx; u_char * file_name; ngx_uint_t line; ngx_str_t server_name # if (T_NGX_SERVER_INFO) ngx_str_t server_admin;#endif size_t connection_pool_size; size_t request_pool_size; size_t client_header_buffer_size; ngx_bufs_t large_client_header_buffers Ngx_msec_t client_header_timeout; ngx_flag_t ignore_invalid_headers; ngx_flag_t merge_slashes; ngx_flag_t underscores_in_headers; unsigned listen:1;#if (NGX_PCRE) unsigned captures:1 # endif ngx_http_core_loc_conf_t * * named_locations;} ngx_http_core_srv_conf_t
Let's not elaborate on what these fields are for. It mainly depends on how ngx_http_core_srv_conf_t is associated with other data structures. From the above configuration, we can see that server is associated with IP:Port. The relationship in tengine/nginx is as follows:
Typedef struct {ngx_http_listen_opt_t opt; ngx_hash_t hash; ngx_hash_wildcard_t * wc_head; ngx_hash_wildcard_t * wc_tail;#if (NGX_PCRE) ngx_uint_t nregex; ngx_http_server_name_t * regex # endif / * the default server configuration for this address:port * / ngx_http_core_srv_conf_t * default_server; ngx_array_t servers; / * array of ngx_http_core_srv_conf_t * /} ngx_http_conf_addr_t
As you can see, IP:Port 's core data structure, ngx_http_conf_addr_t, contains the default server block default_server and all the server block array servers associated with that IP:Port, and the other fields are not expanded in detail. Tengine splits all the IP:Port into Port and puts the ngx_http_conf_addr_t into the ngx_http_conf_port_t:
Typedef struct {ngx_int_t family; in_port_t port; ngx_array_t addrs; / * array of ngx_http_conf_addr_t * /} ngx_http_conf_port_t
Why split the IP:Port? this is because if the Port of listen does not specify IP, such as listen 80;, then the address of tengine/nginx when creating the listening socket is 0.0.0.0. If there are other configurations with listen with precise ip and port, such as listen 10.101.192.91 listen 80;, it is impossible to create this socket in the kernel. Several listen in Section 2 configuration listen in the kernel like this:
Although listen has 80 and 10.101.192.91 listen, it is 0.0.0.0 in the kernel, so tengine needs to use ngx_http_conf_port_t to record all the exact addresses of the port. But this structure is only used during the configuration phase and is converted to structures ngx_http_port_t and ngx_http_in_addr_t when listening to socket (this is because ip:port and server blocks are many-to-many and need to be reorganized and optimized):
Typedef struct {/ * ngx_http_in_addr_t or ngx_http_in6_addr_t * / void * addrs; ngx_uint_t naddrs;} ngx_http_port_t;typedef struct {in_addr_t addr; ngx_http_addr_conf_t conf;} ngx_http_in_addr_t Typdef ngx_http_addr_conf_s ngx_http_addr_conf_t;struct ngx_http_addr_conf_s {/ * the default server configuration for this address:port * / ngx_http_core_srv_conf_t * default_server; ngx_http_virtual_names_t * virtual_names; unsigned ssl:1; unsigned http2:1; unsigned proxy_protocol:1 }
Ngx_http_port_t records all the exact addresses of the port and the corresponding server blocks. Ngx_http_port_t is put into the listening socket core structure ngx_listening_t:
Typedef struct ngx_listening_s ngx_listening_t;struct ngx_listening_s {ngx_socket_t fd; struct sockaddr * sockaddr; socklen_t socklen; / * size of sockaddr * / size_t addr_text_max_len; ngx_str_t addr_text; / / omitted. / * handler of accepted connection * / ngx_connection_handler_pt handler; void * servers; / * array of ngx_http_in_addr_t, for example * / / omitted. }; struct ngx_connection_s {/ / omit. Ngx_listening_t * listening; / / omit. }
So a connection can find a matching server block from c-> listening- > servers.
The general relationship between ip:port and server in tengine is as follows:
(you can use this diagram to understand how tengine looks for server blocks.)
From request to server block
The above talked about some of the relationships and core data structures between ip:port and server, and this section talks about the logic of tengine from processing requests to matching server. Ngx_http_init_connection is a function that initializes a connection, and we see this logic in this function:
Voidngx_http_init_connection (ngx_connection_t * c) {/ / omitted. Ngx_http_port_t * port; ngx_http_in_addr_t * addr; ngx_http_connection_t * hc; / / omit. / * find the server configuration for the address:port * / port = c-> listening- > servers; if (port- > naddrs > 1) {/ / omitted. Sin = (struct sockaddr_in *) c-> local_sockaddr; addr = port- > addrs; / * the last address is "*" * / for (I = 0; I
< port->Naddrs-1; iTunes +) {if (addr [I] .addr = = sin- > sin_addr.s_addr) {break;}} hc- > addr_conf = & addr [I] .conf; / / omitted. } else {/ / omit. Addr = port- > addrs; hc- > addr_conf = & addr [0] .conf; / / omitted. } / * the default server configuration for the address:port * / hc- > conf_ctx = hc- > addr_conf- > default_server- > ctx; / / omitted. }
You can see that during initialization, the ip:port of socket matches the most appropriate configuration and is stored in the hc- > addr_conf pointer. This is the ngx_http_addr_conf_t pointer of the data structure mentioned above, in which all the core configurations of server blocks associated with the ip:port are stored. When you receive the HTTP request header to process the request line or process the Host header, go to hc- > addr_conf to match the real server block according to the domain name:
Static ngx_int_tngx_http_set_virtual_server (ngx_http_request_t * r, ngx_str_t * host) {/ / omitted. Ngx_http_connection_t * hc; ngx_http_core_srv_conf_t * cscf; / / omit. Hc = r-> http_connection; / / omit. Rc = ngx_http_find_virtual_server (r-> connection, hc- > addr_conf- > virtual_names, host, r, & cscf) / / when creating r, r-> srv_conf and r-> loc_conf are the default configurations of hc- > conf_ctx / / if no matching server block is found, there is no need to set r-> srv_conf and r-> loc_conf if (rc = = NGX_DECLINED) {return NGX_OK;} / / find matching server. Use the configuration of real server block r-> srv_conf = cscf- > ctx- > srv_conf R-> loc_conf = cscf- > ctx- > loc_conf; / / omit. }
The function ngx_http_find_virtual_server is to find the server block interface corresponding to the domain name. (another place where this function is called is when dealing with SSL handshake when it encounters SNI. This is because you also need to find the certificate configured in the matching server block when shaking hands.)
At this point, the lookup logic of the server block configuration is over, and the subsequent modules can look up the server/location block configuration of their own modules from r-> srv_conf and r-> loc_conf.
Thank you for your reading, the above is the content of "Tengine how to find server blocks", after the study of this article, I believe you have a deeper understanding of how to find server blocks in Tengine, and the specific use needs to be verified in practice. Here is, the editor will push for you more related knowledge points of the article, welcome to follow!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.