深入理解nginx一致性哈希负载均衡模块[下]

本文详细分析了nginx中ngx_http_upstream_hash_module模块实现的一致性哈希负载均衡,涵盖配置指令解析、负载均衡配置初始化、请求上下文准备及获取peer节点的全过程。通过源码解读,阐述了虚拟节点的分配、排序、去重以及在请求处理中的应用。
摘要由CSDN通过智能技术生成

上接 深入理解nginx一致性哈希负载均衡模块[上]

3. 源码分析

  nginx的一致性哈希功能是通过ngx_http_upstream_hash_module来提供的,下面来整体通过ngx_http_upstream_hash_module来学习一下一致性哈希算法的实现原理。

3.1 配置指令分析

  要启用Nginx的一致性哈希负载均衡算法,你需要使用ngx_http_upstream_hash_module模块。下面是一些配置指令的详细说明:

  1. upstream指令:
upstream指令用于定义一个负载均衡的后端服务器组。
语法: upstream group_name { ... }

示例:
	upstream backend_servers {
	    server backend1.example.com;
	    server backend2.example.com;
	    ...
	}
  1. hash指令:
hash指令用于启用一致性哈希负载均衡算法。
语法: hash key [consistent] [method=xx]

key: 指定用于计算哈希值的关键字,可以是变量或固定值。
consistent (可选): 使用一致性哈希算法。
method (可选): 指定哈希算法的方法,可选值为crc32, md5, sha1,默认为crc32。

示例:
	upstream backend_servers {
	    hash $request_uri consistent;
	    server backend1.example.com;
	    server backend2.example.com;
	    ...
	}

  在以上示例中开启了以reqeust_uri作为key的一致性哈希负载均衡算法。

  接下去看一下指令分析的源码,首先本模块定义了一个配置指令,如下:

static ngx_command_t  ngx_http_upstream_hash_commands[] = {
   

    {
    ngx_string("hash"),
      NGX_HTTP_UPS_CONF|NGX_CONF_TAKE12,
      ngx_http_upstream_hash,
      NGX_HTTP_SRV_CONF_OFFSET,
      0,
      NULL },

      ngx_null_command
};

  在nginx解析到upstream块中的hash指令的时候就回调ngx_http_upstream_hash进行指令解析,源码如下:


static char *
ngx_http_upstream_hash(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
   
    ngx_http_upstream_hash_srv_conf_t  *hcf = conf;

    ngx_str_t                         *value;
    ngx_http_upstream_srv_conf_t      *uscf;
    ngx_http_compile_complex_value_t   ccv;

    value = cf->args->elts;

	/* 第一个参数是包含动态变量的哈希key,通过ngx_http_compile_complex_value进行解析 */
    ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));

    ccv.cf = cf;
    ccv.value = &value[1];
    ccv.complex_value = &hcf->key;

    if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
   
        return NGX_CONF_ERROR;
    }

	/* 获取ngx_http_upstream_module的配置信息 */
    uscf = ngx_http_conf_get_module_srv_conf(cf, ngx_http_upstream_module);

	/* init_upstream如果已经设置,表示其他负载均衡算法已经设置过了 */
    if (uscf->peer.init_upstream) {
   
        ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
                           "load balancing method redefined");
    }

	/* 这里设置的flags中缺少了NGX_HTTP_UPSTREAM_BACKUP,所以如果开启hash负载均衡算法,
	   那么nginx就不能支持主备服务器模式了
	 */
    uscf->flags = NGX_HTTP_UPSTREAM_CREATE
                  |NGX_HTTP_UPSTREAM_WEIGHT
                  |NGX_HTTP_UPSTREAM_MAX_CONNS
                  |NGX_HTTP_UPSTREAM_MAX_FAILS
                  |NGX_HTTP_UPSTREAM_FAIL_TIMEOUT
                  |NGX_HTTP_UPSTREAM_DOWN;

    if (cf->args->nelts == 2) {
   
		/* 如果没有第三个参数consistent,则为普通的hash负载均衡算法 */
        uscf->peer.init_upstream = ngx_http_upstream_init_hash;

    } else if (ngx_strcmp(value[2].data, "consistent") == 0) {
   
	    /* 设置一致性哈希算法配置初始化的回调函数 */
        uscf->peer.init_upstream = ngx_http_upstream_init_chash;

    } else {
   
        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                           "invalid parameter \"%V\"", &value[2]);
        return NGX_CONF_ERROR;
    }

    return NGX_CONF_OK;
}

   上述代码最重要的步骤就是2个,一个是设置hash key,另外一个就是设置负载均衡算法配置初始化的回调函数,虽然本模块同时实现了普通哈希和一致性哈希两种负载均衡算法,由于本文的重点是一致性哈希算法,所以普通哈希负载均衡算法略过不讲了。

3.2 负载均衡配置初始化函数的实现

&esmp; 在3.1节中的配置指令解析完成后,如果开启了consistent负载均衡功能,那么就会将uscf->peer.init_upstream设置为ngx_http_upstream_init_chash。当nginx完成配置解析工作以后,因为已经加载到了upstrem中的所有server,后续还需要用这些server对启用的负载均衡算法进行初始化准备工作。

  1. 第一步是加载peer链:
    if (ngx_http_upstream_init_round_robin(cf, us) != NGX_OK) {
   
        return NGX_ERROR;
    }

  以上这段代码是用round-robin模块的ngx_http_upstream_init_round_robin函数加载server到peer链中,具体可以参考深入理解nginx负载均衡round-robin算法

  1. 第二步是设置负载均衡算法的上下文初始化回调函数
us->peer.init = ngx_http_upstream_init_chash_peer;

  1. 第三步是获取用ngx_http_upstream_init_round_robin加载到的peers链:
peers = us->peer.data;

  1. 第四步是分配一致性哈希算法的虚拟节点:
npoints =<
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码农心语

您的鼓励是我写作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值