RestyCircuitBreaker --- openresty断路器 2019-06-03

简介

由于某些场景下服务提供方和调用方都无法做到可用性,当系统远程调用时,可能会因为某些接口变慢导致调用方大量HTTP连接被阻塞而引发雪崩。

解决思路如下:

服务提供方实现接口快速失败,当处理时间达到一定阈值时,直接返回失败。需要服务提供方配合改造。服务提供方在反向代理层增加proxy_timeout配置。如果配置了upstream max_fails,可能会导致所有的服务实例都被踢掉。而不配置max_fails则出问题的时间段内这个接口每次调用都会在proxy_timeout时间才能返回超时。服务接入方调用远程接口失败时触发熔断,一定时间内不在调用远程服务。需要服务接入方配合改造。

综上,这个问题服务提供方和接入方分别做到快速失败和熔断降级,就可以很好的决解。但是某些业务场景,服务提供方和接口方都无法改进时,我们只好在反向代理层想办法。

思路

在nginx中利用lua脚本实现断路器功能。

定义ngx.shared.DICT字典,用于记录每个接口的熔断状态和超时次数,超时次数和熔断状态2个字典,减少锁几率

在init_worker_by_lua阶段定义定时任务,用户清空超时次数和对已经打开一段时间的断路器设为半开

在access_by_lua阶段执行判断,判断当前请求是否熔断。已熔断则直接返回失败。

在log_by_lua阶段判断请求是否超时,如超时则记录超时次数并更新熔断器状态。

nginx 配置说明

RestyCircuitBreaker.lua 放至lua脚本文件夹

http段定义字典:

lua_shared_dict resty_circuit_breaker_dict 2M; lua_shared_dict resty_circuit_breake_timeout_dict 10M;

http段 执行init_by_lua脚本:

restyCircuitBreaker = require("RestyCircuitBreaker").init("pdc")

http段 执行init_worker_by_lua脚本:

restyCircuitBreaker:set_background()

server或者location段 执行access_by_lua脚本:

restyCircuitBreaker:run()

server或者location段 执行log_by_lua脚本:

restyCircuitBreaker:set_bucket()

通过prometheus查看断路器状态

# HELP circuit_status 断路器状态# TYPE circuit_status gaugecircuit_status{system="pdc",url="/marketing/get_info"} 2# HELP circuit_time 断路打开时间# TYPE circuit_time countercircuit_time{system="pdc",url="/marketing/get_info"} 10

github地址:https://github.com/lazio10000/RestyCircuitBreaker

Copyright © 2019 菲彩国际官wwwfc2688 All Rights Reserved
金上庆
地址:内蒙古自治省包头市昆区青年17号街坊广荟综合楼13号
全国统一热线:13958426394