Analysis of nginx round_robin Module

Source: Internet
Author: User
Basic information module name: round_robin File Location: src/HTTP/ngx_http_upstream_round_assist.c, src/HTTP/upstream code line: 844 running stage: content_phase upstream call: ngx_http_upstream.c prepare function: when nginx is used as a reverse proxy server, there are two kinds of shunting policies for backend servers: weighted shunting and IP hash. This module mainly implements the weighted shunting function. For machines with higher weights, the selected machine has a high probability. For machines with the same weights, the round robin method is used. Highlights: 1. Set the single field in the data structure to check whether there is only one backend server. If yes, you do not need to use the shunting policy module to directly return; 2. You have set the maximum number of failures and the maximum failure time. If the maximum number of failures is reached, the server does not participate in traffic delivery within a period of time. 3. Use the backup server. The backup server is requested only when the existing Server is invalid. Data Structure
Typedef struct {// basic socket information struct sockaddr * sockaddr; socklen_t socklen; ngx_str_t name; // The current weight value and the set weight value ngx_int_t current_weight; ngx_int_t weight; // number of failures and access time ngx_uint_t fails; time_t accessed; // upper limit of failure times and failure time threshold ngx_uint_t max_fails; time_t fail_timeout; // whether the server participates in the ngx_uint_t down policy; /* unsigned down: 1; * // SSL related # If (ngx_http_ssl) ngx_ssl_session_t * ssl_session;/* local to a process */# endif} ngx_http_upstream_rr_peer_t; // round robin backend server information typedef struct into role; struct ngx_http_upstream_rr_peers_s {ngx_uint_t single; // whether there is only one server ngx_uint_t number; // Number of backend servers ngx_uint_t last_cach; /* ngx_mutex_t * mutex; */ngx_connection_t ** cached; ngx_str_t * Name; ngx_http_upstream_rr_peers_t * Next; // The next upstream node uploads peer [1]; // server information }; typedef struct {ngx_http_upstream_rr_peers_t * peers; // All Server Information ngx_uint_t current; // The current server uintptr_t * tried; // The server bitmap pointer that records the current server status uintptr_t data; // actual storage location of the tried bitmap} ngx_http_upstream_rr_peer_data_t;

The above is the data structure design. Two of them are worth noting:

1. The author separately considers the situation of a single server. If there is only one backend server, you can directly use it without having to consider policy issues. Setting this flag helps improve performance. 2. The tried field implements a bitmap. When the number of backend servers is less than 32, a 32-bit int is used to identify whether each server has tried to connect. When the number of backend servers is greater than 32, a new request for memory in the memory pool will be applied to store the bitmap. Data is the location where the field is actually stored. Current is the server to which the current attempt is made. Function Design
ngx_int_t ngx_http_upstream_init_round_robin(ngx_conf_t *cf,    ngx_http_upstream_srv_conf_t *us);ngx_int_t ngx_http_upstream_init_round_robin_peer(ngx_http_request_t *r,    ngx_http_upstream_srv_conf_t *us);ngx_int_t ngx_http_upstream_create_round_robin_peer(ngx_http_request_t *r,    ngx_http_upstream_resolved_t *ur);ngx_int_t ngx_http_upstream_get_round_robin_peer(ngx_peer_connection_t *pc,    void *data);void ngx_http_upstream_free_round_robin_peer(ngx_peer_connection_t *pc,    void *data, ngx_uint_t state);#if (NGX_HTTP_SSL)ngx_int_t    ngx_http_upstream_set_round_robin_peer_session(ngx_peer_connection_t *pc,    void *data);void ngx_http_upstream_save_round_robin_peer_session(ngx_peer_connection_t *pc,    void *data);#endif
The idea of function design is very clear, and the main implementation of the function can be guessed from the name. It will be detailed later. There are also two static functions. The CMP function completes the server weight comparison and is used to sort servers by weight. Get_peer completes and selects the server with the highest weight from all servers. If the current weight of all servers is 0, the current weight of all servers is restored to the set weight value.
static ngx_int_t ngx_http_upstream_cmp_servers(const void *one,    const void *two);static ngx_uint_tngx_http_upstream_get_peer(ngx_http_upstream_rr_peers_t *peers);
The core implementation of the ngx_http_upstream_init_round_robin function mainly completes the initialization of the specified server in the configuration: 1. Obtain the server attribute. Including socket, set weight, failure count, and failure time limit; 2. differentiate a single server. Prepare for separate processing. 3. If the domain name is specified in the configuration, the IP address needs to be obtained first. 4. The normal server and backup server need to be processed separately.

Ngx_http_upstream_init_round_assist_peer initializes the server. Some difficult points in the Code are mainly the use of tried variable values. Tried records whether the server has been connected. It is a bitmap. If the number of servers is less than 32, you only need to record the status of all servers in one Int. If the number of servers is greater than 32, you need to apply for memory in the memory pool for storage. The implementation is as follows:

// Creation process if (RRP-> peers-> Number <= 8 * sizeof (uintptr_t) {RRP-> tried = & RRP-> data; RRP-> DATA = 0;} else {n = (RRP-> peers-> Number + (8 * sizeof (uintptr_t)-1 )) /(8 * sizeof (uintptr_t); RRP-> tried = ngx_pcalloc (R-> pool, N * sizeof (uintptr_t); If (RRP-> tried = NULL) {return ngx_error ;}}

// Example n = RRP-> current/(8 * sizeof (uintptr_t); M = (uintptr_t) 1 <RRP-> current % (8 * sizeof (uintptr_t); If (! (RRP-> tried [N] & M) {peer = & RRP-> peers-> peer [RRP-> current];
Ngx_http_upstream_create_round_assist_peer is used to create the default server information. The default weight is 1, the maximum number of failures is 1, and the maximum failure time is 10 s. This function can be considered as an auxiliary function of the initialization function, but its upstream call is in ngx_http_upstream.c. The ngx_http_upstream_get_round_assist_peer function completes the function of obtaining backend servers. Its code is mainly for logic processing and there is no difficulty in understanding it, but the code is redundant. You can read from the Code the specific policy of Round Robin: 1) sort the server by weight from high to low; 2) Take the server with the largest weight and subtract the weight by one; 3) if the weights are the same, the backend server is given priority. In addition, it should be noted that there is a last backup server processing: when normal servers fail, it will fall into the backup group. The ngx_http_upstream_free_round_assist_peer function restores all the Flag Fields of the server to the initial state for later use.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.