在NGINX上配置加权轮询时,通过参数weight来设置后端各服务器的权重,如下:
...
upstream backend{
server 192.168.122.1:80 weight=3;
server 192.168.122.2:80 weight=10;
}
...
那么问题来了,参数`weight`的范围是多少呢?NGINX官方文档对该参数的描述是:
weight
=number
sets the weight of the server, by default, 1.
虽然没有提到该参数的范围,但由此可知,weight的默认值是1,实际上当我们将weight设置为0并重新加载配置文件时,会报错如下:
nginx: [emerg] invalid parameter "weight=0" in /usr/local/nginx/conf/nginx.conf:38
所以weight的最小值是1,那么最大值如何确定?我们可以慢慢将该值调大去尝试,但太耗费时间,直接查看源码是最直接、准确的方法。
根据关键词“invalid parameter”和“weight”可以确定在在ngx_http_upstream.c文件中会判断weight是否有效并输出相关信息。
if (ngx_strncmp(value[i].data, "weight=", 7) == 0) {
if (!(uscf->flags & NGX_HTTP_UPSTREAM_WEIGHT)) {
goto not_supported;
}
//使用该函数判断weight的值是否有效
weight = ngx_atoi(&value[i].data[7], value[i].len - 7);
//如果weight无效,则输出错误信息并结束程序
if (weight == NGX_ERROR || weight == 0) {
goto invalid;
}
continue;
}
...
invalid:
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"invalid parameter \"%V\"", &value[i]);
//配置错误
return NGX_CONF_ERROR;
以上可以分析出函数ngx_atoi()会将配置文件中参数weight的值由字符串转换为整型值并赋值给变量weight,之后判断变量weight是否有效。跳转到函数ngx_atoi(),分析如下:
ngx_int_t
ngx_atoi(u_char *line, size_t n)
{
ngx_int_t value, cutoff, cutlim;
if (n == 0) {
return NGX_ERROR;
}
cutoff = NGX_MAX_INT_T_VALUE / 10;
cutlim = NGX_MAX_INT_T_VALUE % 10;
for (value = 0; n--; line++) {
//可以分析出weight不能为负数或0
if (*line < '0' || *line > '9') {
return NGX_ERROR;
}
//该判断可以看出weight的最大值是NGX_MAX_INT_T_VALUE
if (value >= cutoff && (value > cutoff || *line - '0' > cutlim)) {
return NGX_ERROR;
}
value = value * 10 + (*line - '0');
}
return value;
}
以上可以分析出,weight不能为负数或0,其最大值是NGX_MAX_INT_T_VALUE,跳转到该宏定义:
#if (NGX_PTR_SIZE == 4)//NGX_PTR_SIZE为指针的长度
#define NGX_INT_T_LEN NGX_INT32_LEN
#define NGX_MAX_INT_T_VALUE 2147483647//当指针长度为4时,该值为2^31-1
#else
#define NGX_INT_T_LEN NGX_INT64_LEN
#define NGX_MAX_INT_T_VALUE 9223372036854775807//当指针长度为8时,该值为2^63-1
#endif
可以看到,NGX_MAX_INT_T_VALUE的值取决于指针的长度(即CPU的字长)。
综上所述,可以确定参数weight的取值范围如下:
指针长度 | weight取值范围 |
32位 | 1~2147483647(2^31-1) |
64位 | 1~9223372036854775807(2^63-1) |