openresty健康检查lua-resty-upstream-healthcheck分析和拓展

    网关作为流量的入口,承上启下的中枢,对上游节点的健康状态监测是比不可少的;若上游节点异常,网关需要动态摘除此节点,避免流量转到异常节点去,保证服务的稳定。

    本文主要分析lua-resty-upstream-healthcheck源码,以及在实际工作的优化应用。

一、背景介绍

     目前本人负责的网关是基于orange二次开发的,health_check健康检查功能是基于插件的形式嵌套在网关中。在lua-resty-upstream-healthcheck的基础上根据业务增加了tcp/http检测、异常节点自动摘除、告警等功能。

二、health_check分析

2.1 分析之前

     health_check运行在init_worker阶段,也是一个定时任务。在实际项目中,我们用一个nginx work进程来进行健康检查,比如ngx.worker.id() == 0。这种处理方式的好处就是,就算异常情况下当前处理健康检查的nginx进程因为某些原因crash掉了,新fork出来的nginx worker也会集成这个worker id的,只要nginx master进程不挂掉,健康检查都会正常运行。并且最大限度的减少健康检查对网关整体性能的影响,让网关注重做该做的事情。

2.2 代码分析

     基本流程图:

     spawn_checker:在health_check模块中,spawn_checker供外部调用,也是代码的入口。这里面主要做了两件事情:初始化健康检查参数和开启定时任务进行check。结合业务需求,增加告警通知配置。同时健康检查

Lua-Resty-Checkups是一个基于luaupstream管理健康检查模块,由又拍云开源。特点:支持周期性upstream服务管理操作支持管理健康检查支持upstream动态更新有利于加权轮询或哈希平衡支持 Nginx C upstream同步操作可使用级别键值实现集群使用简介:-- config.lua _M = {} _M.global = {     checkup_timer_interval = 15,     checkup_shd_sync_enable = true,     shd_config_timer_interval = 1, } _M.ups1 = {     cluster = {         {             servers = {                 {host="127.0.0.1", port=4444, weight=10, max_fails=3, fail_timeout=10},             }         },     }, }lua_package_path "/path/to/lua-resty-checkups/lib/checkups/?.lua;/path/to/config.lua;;"; lua_shared_dict state 10m; lua_shared_dict mutex 1m; lua_shared_dict locks 1m; lua_shared_dict config 10m; server {     listen 12350;     return 200 12350; } server {     listen 12351;     return 200 12351; } init_worker_by_lua_block {     local config = require "config"     local checkups = require "resty.checkups.api"     checkups.prepare_checker(config)     checkups.create_checker() } server {     location = /12350 {         proxy_pass http://127.0.0.1:12350/;     }     location = /12351 {         proxy_pass http://127.0.0.1:12351/;     }     location = /t {         content_by_lua_block {             local checkups = require "resty.checkups.api"             local callback = function(host, port)                 local res = ngx.location.capture("/" .. port)                 ngx.say(res.body)                 return 1             end             local ok, err             -- connect to a dead server, no upstream available             ok, err = checkups.ready_ok("ups1", callback)             if err then ngx.say(err) end             -- add server to ups1             ok, err = checkups.update_upstream("ups1", {                     {                         servers = {                             {host="127.0.0.1", port=12350, weight=10, max_fails=3, fail_timeout=10},                         }                     },                 })             if err then ngx.say(err) end             ngx.sleep(1)             ok, err = checkups.ready_ok("ups1", callback)             if err then ngx.say(err) end             ok, err = checkups.ready_ok("ups1", callback)             if err then ngx.say(err) end             -- add server to new upstream             ok, err = checkups.update_upstream("ups2", {                     {                         servers = {                             {host="127.0.0.1", port=12351},                         }                     },                 })             if err then ngx.say(err) end             ngx.sleep(1)             ok, err = checkups.ready_ok("ups2", callback)             if err then ngx.say(err) end             -- add server to ups2, reset rr state             ok, err = checkups.update_upstream("ups2", {                     {                         servers = {                             {host="127.0.0.1", port=12350, weight=10, max_fails=3, fail_timeout=10},                             {host="127.0.0.1", port=12351, weight=10, max_fails=3, fail_timeout=10},                         }                     },                 })             if err then ngx.say(err) end             ngx.sleep(1)             ok, err = checkups.ready_ok("ups2", callback)             if err then ngx.say(err) end             ok, err = checkups.ready_ok("ups2", callback)             if err then ngx.say(err) end     } }Lua 配置示例:_M = {} -- Here is the global part _M.global = {     checkup_timer_interval = 15,     checkup_timer_overtime = 60,     default_heartbeat_enable = true,     checkup_shd_sync_enable = true,     shd_config_timer_interval = 1, } -- The rests parts are cluster configurations _M.redis = {     enable = true,     typ = "redis",     timeout = 2,     read_timeout = 15,     send_timeout = 15,     protected = true,     cluster = {         {   -- level 1             try = 2,             servers = {                 { host = "192.168.0.1", port = 6379, weight=10, max_fails=3, fail_timeout=10 },                 { host = "192.168.0.2", port = 6379, weight=10, max_fails=3, fail_timeout=10 },             }         },         {   -- level 2             servers = {                 { host = "192.168.0.3", port = 6379, weight=10, max_fails=3, fail_timeout=10 },             }         },     }, } _M.api = {     enable = false,     typ = "http",     http_opts = {         query = "GET /status HTTP/1.1\r\nHost: localhost\r\n\r\n",         statuses = {             [500] = false,             [502] = false,             [503] = false,             [504] = false,         },     },     mode = "hash",     cluster = {         dc1 = {             servers = {                 { host = "192.168.1.1", port = 1234, weight=10, max_fails=3, fail_timeout=10 },             }         },         dc2 = {             servers = {                 { host = "192.168.1.2", port = 1234, weight=10, max_fails=3, fail_timeout=10 },             }         }     } } _M.ups_from_nginx = {     timeout = 2,     cluster = {         {   -- level 1             upstream = "api.com",         },         {   -- level 2             upstream = "api.com",             upstream_only_backup = true,         },     }, } return _M
<think>嗯,用户想了解如何配置使用resty.upstream.healthcheck。首先,我需要回忆一下OpenResty的相关文档。这个模块是用于上游服务器的健康检查的,属于lua-resty-upstream-healthcheck这个库。用户可能是在配置Nginx的时候遇到了问题,需要设置健康检查来确保后端服务器的可用性。首先,我应该介绍基本概念,说明这个模块的作用,比如主动被动检查模式。然后给出一个配置示例,这样用户可以直接参考。需要确保代码块正确,使用LuaNginx配置的语法。同时,要提到需要加载的Lua模块,比如lua_shared_dict,这是共享内存必需的。 接下来,配置参数部分需要详细说明每个指令的作用,比如shm、type、interval等。用户可能不太清楚这些参数的具体含义如何调整,所以需要解释清楚。比如interval是检查间隔,timeout是超时时间,checks是连续成功或失败的次数。 然后,动态控制部分很重要,用户可能需要在不重启Nginx的情况下启用或禁用健康检查,所以需要给出对应的Lua代码示例,比如使用healthcheck.enable()healthcheck.disable()。日志分析部分可以帮助用户验证配置是否生效,需要说明如何查看日志中的健康检查记录,比如HTTP状态码响应时间,以及节点状态的变化。这里可以引用用户提供的日志示例,说明不同的状态码对应的结果。可能用户还会关心性能优化,比如调整检查频率超时时间,或者如何处理被动检查模式下的节点状态。需要提前预见到这些问题,并在回答中给出建议,比如根据业务需求选择合适的参数,避免过高的负载。 最后,生成的相关问题需要覆盖用户可能进一步询问的方向,比如与Nginx原生健康检查的区别、动态增减节点、自定义检查条件等。这些都有助于用户深入理解并解决实际应用中的问题。需要确保整个回答结构清晰,步骤明确,代码示例正确,并且引用用户提供的日志例子来增强说服力。同时,注意使用中文,避免术语混淆,让用户能够轻松跟随配置步骤进行操作。</think>### resty.upstream.healthcheck 使用与配置指南 #### 一、基本概念 `resty.upstream.healthcheck`是OpenResty提供的Lua模块,用于实现动态上游节点的健康检查机制,支持**主动探测****被动检查**两种模式。其核心原理是通过定时发送探测请求或分析实际请求响应状态,动态标记节点健康状态[^1]。 #### 二、配置步骤 1. **Nginx配置初始化** ```nginx http { lua_shared_dict healthcheck 10m; init_worker_by_lua_block { local healthcheck = require "resty.upstream.healthcheck" healthcheck.spawn_checker{ shm = "healthcheck", upstream = "backend", # 对应upstream块名称 type = "http", http_req = "GET /healthcheck HTTP/1.0\r\nHost: backend\r\n\r\n", interval = 2000, # 检查间隔(ms) timeout = 1000, # 超时时间 valid_statuses = {200, 302}, concurrency = 10 # 并发检查数 } } } ``` 2. **健康检查参数说明** | 参数 | 作用 | 示例值 | |------|------|--------| | `shm` | 共享内存区名称 | `healthcheck` | | `checks` | 连续成功/失败判定阈值 | `5` | | `interval` | 主动检查间隔 | `3000` | | `fall` | 标记节点失效的失败次数 | `3` | | `rise` | 恢复节点所需的成功次数 | `2` | #### 三、动态控制 在Lua代码中可动态操作检查器: ```lua -- 启用检查器 local hc = require "resty.upstream.healthcheck" hc.enable() -- 临时禁用检查 hc.disable() ``` #### 四、日志分析 配置成功后,在Nginx error.log中可见: ``` 2024/05/20 10:00:00 [notice] 12345#0: *15 [lua] healthcheck.lua:567: log(), upstream:backend, unhealthy: 503 2.001 0.004 node1:443, healthy: 200 0.003 node2:443 ``` 其中`503`表示探测失败,`200`为有效响应,时间单位为秒[^2]。 #### 五、性能优化建议 1. 通过调整`interval`平衡检查频率与资源消耗 2. 被动检查模式下可设置`proxy_next_upstream`实现快速故障转移 3. 使用`lua_socket_log_errors off`避免重复日志记录
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值