简介

由于某些场景下服务提供方和调用方都无法做到可用性,当系统远程调用时,可能会因为某些接口变慢导致调用方大量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 gauge
    circuit_status{system="pdc",url="/marketing/get_info"} 2
    # HELP circuit_time 断路打开时间
    # TYPE circuit_time counter
    circuit_time{system="pdc",url="/marketing/get_info"} 10

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

RestyCircuitBreaker --- openresty断路器的更多相关文章

  1. 火焰图分析openresty性能瓶颈

    注:本文操作基于CentOS 系统 准备工作 用wget从https://sourceware.org/systemtap/ftp/releases/下载最新版的systemtap.tar.gz压缩包 ...

  2. openresty 前端开发入门五之Mysql篇

    openresty 前端开发入门五之Mysql篇 这章主要演示怎么通过lua连接mysql,并根据用户输入的name从mysql获取数据,并返回给用户 操作mysql主要用到了lua-resty-my ...

  3. openresty 前端开发入门六之调试篇

    大多数情况下,调试信息,都可以通过ngx.say打印出来,但是有的时候,我们希望打印调试日志,不影响到返回数据,所以系统打印到其它地方,比如日志文件,或者控制台 这里主要用到一个方法就是ngx.log ...

  4. openresty 前端开发序

    还记得第一次尝试前后端分离的时候,是使用nginx + react 构建的spa应用,后端是java,主要处理业务逻辑逻辑部分,返回json数据,在nginx里面配置好html + js纯静态文件,再 ...

  5. openresty 前端开发入门一

    OpenResty ™ 是一个基于 Nginx 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库.第三方模块以及大多数的依赖项.用于方便地搭建能够处理超高并发.扩展性极高的动态 ...

  6. mac下openresty安装

    //openresty安装 http://openresty.org/ brew updatebrew install pcre openssl ./configure --prefix=/usr/l ...

  7. 如何在openresty里解析域名

    转:原文:http://hambut.com/2016/09/09/how-to-resolve-the-domain-name-in-openresty/?utm_source=tuicool&am ...

  8. Circuit Breaker Pattern(断路器模式)

    Handle faults that may take a variable amount of time to rectify when connecting to a remote service ...

  9. 用Nginx+Lua(OpenResty)开发高性能Web应用

    在互联网公司,Nginx可以说是标配组件,但是主要场景还是负载均衡.反向代理.代理缓存.限流等场景:而把Nginx作为一个Web容器使用的还不是那么广泛.Nginx的高性能是大家公认的,而Nginx开 ...

随机推荐

  1. PCL-CMAKELIST书写格式

    cmake_minimum_required(VERSION 2.6 FATAL_ERROR)//cmake最小版本 find_package(PCL 1.3 REQUIRED COMPONENTS ...

  2. 前端面试题---vue部分

    1.vue的两大核心思想 组件化和数据驱动 2.如何理解vue中的MVVM模式 Model-View-ViewModel(简称为mvvm)是一种设计思想,model层代表数据模型,也可以再model中 ...

  3. P3047 [USACO12FEB]附近的牛Nearby Cows

    https://www.luogu.org/problemnew/show/P304 1 #include <bits/stdc++.h> 2 #define up(i,l,r) for( ...

  4. eclipse遇到启动报an error has occurred see the log file错

    错误: 修改eclipse安装目录下比如D:\eclipse\configuration\.settings\org.eclipse.ui.ide.prefs, 删除 RECENT_WORKSPACE ...

  5. (26)A delightful way to teach kids about computers

    https://www.ted.com/talks/linda_liukas_a_delightful_way_to_teach_kids_about_computers/transcript00:1 ...

  6. PEM证书加密方法(python)

    1. 常见网络登录现在都使用了rsa加密,一般而言客户会提供模(mo)和指数(e). 2. 通过模和指数获取到证书PEM(方法见:https://www.cnblogs.com/luo30zhao/p ...

  7. Xamarin常见问题

    1. Could not locate Java 6 or 7 SDK. (Download from http://www.oracle.com/technetwork/java/javase/do ...

  8. 【repost】让你一句话理解闭包(简单易懂)

    接触javascript很久了,每次理解闭包都似是而非,最近在找Web前端的工作,所以需要把基础夯实一下. 本文是参照了joy_lee的博客 闭包 在她这篇博客的基础上以批注的形式力争把我的理解阐述出 ...

  9. Spring Boot中Web应用的统一异常处理 转载来自翟永超

    我们在做Web应用的时候,请求处理过程中发生错误是非常常见的情况.Spring Boot提供了一个默认的映射:/error,当处理中抛出异常之后,会转到该请求中处理,并且该请求有一个全局的错误页面用来 ...

  10. js中创建对象的5种方法

    1.原始模式 var dog = { name: jack, length: 70, wang:function(){ console.log(this.name); } 2.工厂模式(批量) fun ...