RestyCircuitBreaker --- openresty斷路器

簡介

因爲某些場景下服務提供方和調用方都沒法作到可用性,當系統遠程調用時,可能會由於某些接口變慢致使調用方大量HTTP鏈接被阻塞而引起雪崩。nginx

解決思路以下:git

  • 服務提供方實現接口快速失敗,當處理時間達到必定閾值時,直接返回失敗。須要服務提供方配合改造。
  • 服務提供方在反向代理層增長proxy_timeout配置。若是配置了upstream max_fails,可能會致使全部的服務實例都被踢掉。而不配置max_fails則出問題的時間段內這個接口每次調用都會在proxy_timeout時間才能返回超時。
  • 服務接入方調用遠程接口失敗時觸發熔斷,必定時間內不在調用遠程服務。須要服務接入方配合改造。

綜上,這個問題服務提供方和接入方分別作到快速失敗和熔斷降級,就能夠很好的決解。可是某些業務場景,服務提供方和接口方都沒法改進時,咱們只好在反向代理層想辦法。github

思路

在nginx中利用lua腳本實現斷路器功能。ui

  • 定義ngx.shared.DICT字典,用於記錄每一個接口的熔斷狀態和超時次數,超時次數和熔斷狀態2個字典,減小鎖概率lua

  • 在init_worker_by_lua階段定義定時任務,用戶清空超時次數和對已經打開一段時間的斷路器設爲半開url

  • 在access_by_lua階段執行判斷,判斷當前請求是否熔斷。已熔斷則直接返回失敗。代理

  • 在log_by_lua階段判斷請求是否超時,如超時則記錄超時次數並更新熔斷器狀態。rest

nginx 配置說明

  • RestyCircuitBreaker.lua 放至lua腳本文件夾
  • http段定義字典:code

    lua_shared_dict resty_circuit_breaker_dict 2M;  
      lua_shared_dict resty_circuit_breake_timeout_dict 10M;
  • http段 執行init_by_lua腳本:server

    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

相關文章
相關標籤/搜索