Skip to content

模块组成及功能划分

chance edited this page Jun 14, 2020 · 1 revision

模块组成

这个针对nginx负载均衡后端的健康检查模块,其实内部由3个nginx module组成:

  • ngx_http_upstream_healthcheck_module
  • ngx_stream_upstream_check_module
  • ngx_upstream_check_status_module

其实从模块的config文件也能清楚的看出来:

else
  STREAM_MODULES="$STREAM_MODULES ngx_stream_upstream_check_module"
  HTTP_MODULES="$HTTP_MODULES ngx_http_upstream_check_module"
  HTTP_MODULES="$HTTP_MODULES ngx_upstream_check_status_module"

模块功能划分

为什么要分为三个模块呢? 首先按照nginx代码框架设计,模块是有类型的,要么是http,要么是stream,或者mail。

http和stream下的指令及功能实现完全是隔离的(如果你看nginx源码会发现http和stream目录是分开的,但代码是60%相似的)

ngx_http_upstream_healthcheck_module

所以1,要定义个http模块,新增一些check相关的指令,以及来实现7层服务后端的健康检查及后端UP/DOWN状态的管理:

同时我们会为nginx源码打上patch,这样当nginx收到请求后根据各种负载均衡算法选择后端的时候, 就能够通过此模块提供的函数接口直接基于健康后端列表进行后端选择。

#       modified:   src/http/modules/ngx_http_upstream_hash_module.c
#       modified:   src/http/modules/ngx_http_upstream_ip_hash_module.c
#       modified:   src/http/modules/ngx_http_upstream_least_conn_module.c
#       modified:   src/http/ngx_http_upstream_round_robin.c
#       modified:   src/http/ngx_http_upstream_round_robin.h

ngx_stream_upstream_check_module

所以2,类似的要定义一个stream模块完成4层后端服务的健康检查实现及check指令的定义。

同理对应stream模块也一样,我们为nginx源码中4层负载均衡处理的相关代码打上patch:

#       modified:   src/stream/ngx_stream_upstream_hash_module.c
#       modified:   src/stream/ngx_stream_upstream_least_conn_module.c
#       modified:   src/stream/ngx_stream_upstream_round_robin.c
#       modified:   src/stream/ngx_stream_upstream_round_robin.h

ngx_upstream_check_status_module

另外3,我们还需要一个能够查询当前后端健康状态的接口,方便我们运维人员查看: 比如当我们输入: curl localhost:80801/status,可以得到下面的输出:

{"servers": {
  "total": 8,
  "generation": 1,
  "http": [
    {"index": 0, "upstream": "http-cluster", "name": "127.0.0.1:8082", "status": "up", "rise": 1355, "fall": 0, "type": "http", "port": 0},
    {"index": 1, "upstream": "http-cluster", "name": "127.0.0.2:8082", "status": "up", "rise": 1357, "fall": 0, "type": "http", "port": 0}
  ],
  "stream": [
    {"index": 0, "upstream": "tcp-cluster", "name": "127.0.0.1:22", "status": "up", "rise": 1356, "fall": 0, "type": "tcp", "port": 0},
    {"index": 1, "upstream": "tcp-cluster", "name": "192.168.0.2:22", "status": "down", "rise": 0, "fall": 631, "type": "tcp", "port": 0},
    {"index": 2, "upstream": "udp-cluster", "name": "127.0.0.1:5432", "status": "down", "rise": 0, "fall": 1360, "type": "udp", "port": 0},
    {"index": 3, "upstream": "udp-cluster", "name": "8.8.8.8:5432", "status": "up", "rise": 454, "fall": 0, "type": "udp", "port": 0},
    {"index": 4, "upstream": "http-cluster2", "name": "127.0.0.1:8082", "status": "up", "rise": 1360, "fall": 0, "type": "http", "port": 0},
    {"index": 5, "upstream": "http-cluster2", "name": "127.0.0.2:8082", "status": "up", "rise": 1356, "fall": 0, "type": "http", "port": 0}
  ]