Address: Http://wiki.nginx.org/HttpUpstreamConsistentHash
First declare a command:
Static ngx_command_t ngx_http_upstream_consistent_hash_commands[] = {
{ngx_string ("Consistent_hash"),
Ngx_http_ups_conf| Ngx_conf_take1,
Ngx_http_upstream_consistent_hash,
0,
0,
NULL},
Ngx_null_command
};
Look at the processing function of the command: Ngx_http_upstream_consistent_hash
ngx_str_t *value;
ngx_http_script_compile_t SC;
ngx_http_upstream_srv_conf_t *USCF;
ngx_http_upstream_consistent_hash_srv_conf_t *UCHSCF;
Value = cf->args->elts;
USCF = ngx_http_conf_get_module_srv_conf (cf, Ngx_http_upstream_module);
UCHSCF = ngx_http_conf_upstream_srv_conf (USCF,
Ngx_http_upstream_consistent_hash_module);
Ngx_memzero (&SC, sizeof (ngx_http_script_compile_t));
SC.CF = CF;
Sc.source = &value[1];
Sc.lengths = &uchscf->lengths;
Sc.values = &uchscf->values;
Sc.complete_lengths = 1;
Sc.complete_values = 1;
if (Ngx_http_script_compile (&SC)! = NGX_OK) {
return ngx_conf_error;
}
uscf->peer.init_upstream = Ngx_http_upstream_init_consistent_hash;
Uscf->flags = Ngx_http_upstream_create
| Ngx_http_upstream_weight;
This module obtains the configuration of the upstream module, sets the Peer.init_upstream as the function Ngx_http_upstream_init_consistent_hash, which is used to initialize the upstream, ngx_http _upstream_init_consistent_hash (ngx_conf_t *CF,
The function computes a consistent hash based on the IP and port number of the server,
ngx_int_t
Ngx_http_upstream_init_consistent_hash (ngx_conf_t *CF,
ngx_http_upstream_srv_conf_t *us)
{
......
Us->peer.init = Ngx_http_upstream_init_consistent_hash_peer;
......
for (i = 0; i < us->servers->nelts; i++) {
for (j = 0; J < Server[i].naddrs; J + +) {
for (k = 0; k < ((mmc_consistent_points * server[i].weight)/Server[i].naddrs); k++) {
ngx_snprintf (Hash_data, Hash_data_length, "%v-%ui%z", &server[i].addrs[j].name, K);
CONTINUUM->NODES[CONTINUUM->NNODES].SOCKADDR = server[i].addrs[j].sockaddr;
Continuum->nodes[continuum->nnodes].socklen = Server[i].addrs[j].socklen;
Continuum->nodes[continuum->nnodes].name = Server[i].addrs[j].name;
Continuum->nodes[continuum->nnodes].name.data[server[i].addrs[j].name.len] = 0;
continuum->nodes[continuum->nnodes].point = Ngx_crc32_long (Hash_data, Ngx_strlen (Hash_data));
continuum->nnodes++;
}
}
}
Sort
Qsort (Continuum->nodes, Continuum->nnodes,
sizeof (Ngx_http_upstream_consistent_hash_node),
(const void*) ngx_http_upstream_consistent_hash_compare_continuum_nodes);
......
}
Can be seen, is based on the server's IP and port number and index to do ngx_crc32_long calculation;
This also specifies the init function of the Ngx_http_upstream_init_consistent_hash_peer function as peer, which executes every time the connection is made, and the function is to find the server based on key.
Static ngx_int_t
Ngx_http_upstream_init_consistent_hash_peer (ngx_http_request_t *r,
ngx_http_upstream_srv_conf_t *us)
{
......
UCHSCF = ngx_http_conf_upstream_srv_conf (US,
Ngx_http_upstream_consistent_hash_module);
UCHPD = Ngx_pcalloc (r->pool, sizeof (ngx_http_upstream_consistent_hash_peer_data_t));
R->upstream->peer.data = uchpd->peers;
Uchpd->peers = us->peer.data;
Compiling variables
if (Ngx_http_script_run (R, &evaluated_key_to_hash,
Uchscf->lengths->elts, 0, uchscf->values->elts) = = NULL)
{
return ngx_error;
}
Hash value based on key
Uchpd->point =
Ngx_crc32_long (Evaluated_key_to_hash.data, Evaluated_key_to_hash.len);
R->upstream->peer.free = Ngx_http_upstream_free_consistent_hash_peer;
Get which server as compute node
R->upstream->peer.get = Ngx_http_upstream_get_consistent_hash_peer;
......
}
Implementation of Nginx upstream consistent hash