Home  >  Article  >  Operation and Maintenance  >  How to handle nginx requests?

How to handle nginx requests?

(*-*)浩
(*-*)浩Original
2019-11-28 14:57:433216browse

How to handle nginx requests?

Today we are talking about request. In Nginx we refer to http request. The specific data structure in Nginx is ngx_http_request_t. ngx_http_request_t is an encapsulation of an http request. We know that an http request includes request line, request header, request body, response line, response header, and response body.

http request is a typical request-response type network protocol, and http is a text protocol, so we analyze the request line and request header, and output the response line and response header, often line by line. deal with. (Recommended learning: nginx use)

If we write an http server ourselves, usually after a connection is established, the client will send a request. Then we read a line of data and analyze the method, uri, and http_version information contained in the request line.

Then process the request headers line by line, and determine whether there is a request body and the length of the request body based on the request method and request header information, and then read the request body.

After getting the request, we process the request to generate the data that needs to be output, and then generate the response line, response header and response body.

After sending the response to the client, a complete request is processed. Of course, this is the simplest webserver processing method. In fact, Nginx also does this, with some minor differences. For example, when the request header is read, the request processing begins. Nginx uses ngx_http_request_t to save data related to parsing requests and output responses.

Next, let’s briefly talk about how Nginx handles a complete request. For Nginx, a request starts from ngx_http_init_request. In this function, the read event is set to ngx_http_process_request_line. That is to say, the next network event will be executed by ngx_http_process_request_line.

From the function name of ngx_http_process_request_line, we can see that this is to process the request line. As mentioned before, the first thing to process the request is to process the request line.

Read request data through ngx_http_read_request_header. The ngx_http_parse_request_line function is then called to parse the request line. In order to improve efficiency, Nginx uses a state machine to parse the request line. When comparing methods, it does not use string comparison directly. Instead, it converts four characters into an integer and then compares them once to reduce the number of CPU instructions. This has been said before.

Many people may know that a request line contains the request method, uri, and version, but they don’t know that the request line can also contain host. For example, a request such as GET http://www.taobao.com/uri HTTP/1.0 is also legal, and the host is www.taobao.com. At this time, Nginx will ignore the host field in the request header and use Use this in the request line to find the virtual host.

In addition, for http0.9 version, request headers are not supported, so special treatment is required here. Therefore, when parsing the request header later, the protocol version will be 1.0 or 1.1. The parameters parsed from the entire request line will be saved in the ngx_http_request_t structure.

After parsing the request line, Nginx will set the handler of the read event to ngx_http_process_request_headers, and then subsequent requests will be read and parsed in ngx_http_process_request_headers.

ngx_http_process_request_headers function is used to read request headers. Just like the request line, it still calls ngx_http_read_request_header to read the request headers, and calls ngx_http_parse_header_line to parse a line of request headers. The parsed request headers will be saved in the domain headers_in of ngx_http_request_t. , headers_in is a linked list structure that saves all request headers.

Some requests in HTTP require special processing. These request headers and request processing functions are stored in a mapping table, namely ngx_http_headers_in. During initialization, a hash table will be generated. When a request is parsed, After requesting the header, it will first search in the hash table. If found, the corresponding processing function will be called to process the request header. For example: the processing function of the Host header is ngx_http_process_host.

When Nginx parses two carriage returns and line feeds, it indicates the end of the request header, and ngx_http_process_request will be called to process the request.

ngx_http_process_request will set the current connection's read and write event processing function to ngx_http_request_handler, and then call ngx_http_handler to actually start processing a complete http request.

This may be strange. The read and write event processing functions are both ngx_http_request_handler. In fact, in this function, the read_event_handler or write_event_handler in ngx_http_request_t will be called respectively depending on whether the current event is a read event or a write event.

Because at this time, our request header has been read. As mentioned before, Nginx's approach is not to read the request body first, so here we set read_event_handler to ngx_http_block_reading, that is, no data is read. .

As mentioned just now, the real start of processing data is in the ngx_http_handler function. This function will set write_event_handler to ngx_http_core_run_phases and execute the ngx_http_core_run_phases function.

ngx_http_core_run_phases This function will perform multi-stage request processing. Nginx divides the processing of an http request into multiple stages, then this function will execute these stages to generate data.

Because ngx_http_core_run_phases will eventually generate data, it is easy for us to understand why the processing function of the write event is set to ngx_http_core_run_phases.

Here, I briefly explain the calling logic of the function. We need to understand that ngx_http_core_run_phases is ultimately called to process the request. The generated response header will be placed in the headers_out of ngx_http_request_t. I will put this part in Let’s talk about it in the request processing process. Various stages of Nginx will process the request, and finally call filter to filter the data and process the data, such as truncated transmission, gzip compression, etc.

The filter here includes header filter and body filter, which process the response header or response body. Filter is a linked list structure, with header filter and body filter respectively. All filters in header filter are executed first, and then all filters in body filter are executed.

The last filter in the header filter is ngx_http_header_filter. This filter will traverse all response headers. The final response header that needs to be output is in a continuous memory, and then calls ngx_http_write_filter for output.

ngx_http_write_filter is the last one in the body filter, so Nginx’s first body information, after going through a series of body filters, will finally call ngx_http_write_filter for output (there is a picture to illustrate).

What should be noted here is that Nginx will put the entire request header in a buffer. The size of this buffer is set through the configuration item client_header_buffer_size. If the user's request header is too large and this buffer cannot fit, then Nginx will reallocate a new larger buffer to hold the request header. This large buffer can be set through large_client_header_buffers. The large_buffer group of buffers, such as configuring 48k, means that four 8k buffers are available.

Note that in order to preserve the integrity of the request line or request header, a complete request line or request header needs to be placed in a continuous memory. Therefore, a complete request line or request header will only Saved in a buffer.

In this way, if the request line is larger than the size of a buffer, a 414 error will be returned. If the request header size is larger than a buffer size, a 400 error will be returned. After understanding the values ​​of these parameters and the actual practices of Nginx, in the application scenario, we need to adjust these parameters according to actual needs to optimize our program.

Processing flow chart:

How to handle nginx requests?

The above is the life cycle of an http request in Nginx.

The above is the detailed content of How to handle nginx requests?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Previous article:What is Nginx connection?Next article:What is Nginx connection?