最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

nginx+lua+redis實現降級的示例代碼

 更新時間:2024年10月10日 10:56:34   作者:bingwoo.  
隨著用戶訪問量的激增,網站或電商平臺可能會面臨系統(tǒng)超負載的問題,導致注冊、下單、支付等功能出現問題,為保障核心服務的高可用性,可以采用降級策略,本文就來介紹一下nginx+lua+redis降級,感興趣的可以了解學習

前言

商城或web站點的用戶訪問量出乎意料地增加了很多,超出了系統(tǒng)的負載能力, 系統(tǒng)有些扛不住,繼而導致注
冊,下單,支付什么的全部在繞圈卡住,繼而導致公司業(yè)務損失了不少用戶和訂單。。

一、引子

面對一大波訪問量出乎意料地涌入,超出了系統(tǒng)正常的負載范圍,我們可以采用降級來應對,何謂降級?就是將不重要的服務和功能采用屏蔽,或降低實時性,或延遲處理,等等方式,最終目的是保證核心服務可用。

二、什么是降級, 為什么降級,降級的場景?

降級的最終目的是保證核心服務的高可用。過程就是丟卒保帥,有些服務是無法降級的,比如支付。
當我們的服務器壓力劇增為了保證核心功能的可用性 ,而選擇性的降低一些功能的可用性,或者直接關閉該功能。
這就是典型的丟車保帥了。 就比如貼吧類型的網站,當服務器吃不消的時候,可以選擇把發(fā)帖功能關閉,注冊功能關閉,改密碼,改頭像這些都關了,為了確保登錄和瀏覽帖子這種核心的功能。
降級的原理:就是降低次要功能的可用性實用性,增加核心功能的高可用性。
降級的實現原理是多樣多樣的。利用一個降級開關,以這個開關為判斷依據,切換數據的獲取方式,比如當mysql負載高的時候,可以從mysql切換到redis,比如從redis切換到靜態(tài)文件,比如從錯誤頻發(fā)的新版本切換到老版本等等。 這個開關是根據現狀來配置的,比如當新版本錯誤頻發(fā)的時候,我們可以配置這個開關為從老版本獲取數據。

三、降級的種類

  • 根據降級的開關位置:分為服務代碼降級和開關前置降級代碼降級就是利用代碼控制,這種方式比前置降級要low并不推薦
    前置降級是把降級開關放到http請求鏈路層的上游,降低鏈路層消耗。比如提升到nginx,甚至可以提升到前
    端,當提升到前端,后端訪問壓力接近于0

拓展:【如何提升到前端】
可以通過一個從服務器獲取的js腳本進行控制。

  • 根據讀寫:分為讀降級和寫降級。

讀降級,比如,讀取動態(tài)數據,降級為讀取靜態(tài)數據。 寫降級,
比如,寫入mysql,降級為寫入消息隊列, 等高峰期過后,在從隊列寫入mys

  • 根據降級的性質:分為返回內容降級,限流降級,限速降級。

返回內容降級,比如,返回實時數據,降級為返回兜底數據 限流降級,
比如,1000個請求,我只接受500個。 這么做也是無奈之下選擇,要不然系統(tǒng)崩了 誰都訪問不了 限速降級,
比如,對于那些訪問過于頻繁的ip進行限速

拓展:【限流限速】
nginx自帶限流限速,比如ngx_http_limit_req_module和ngx_http_limit_conn_module 。但是這類模塊只是提供了在nginx配置文件中進行簡單的參數配置。 如果想更加靈活和功能更多,可以編寫自己的lua代碼進行控制,而不是用現成的模塊進行配置文件修 改。
4.根據降級的維護特點:分為手動降級和自動降級手動降級,是人為看到系統(tǒng)負載異常后,手動調整降級
自動降級,是系統(tǒng)監(jiān)測到異常后,自動降級,自動降級雖然更加智能,但有時候自動腳本可能會干一些超乎預 料的事情。

四、 業(yè)務分析

大家知道,廣告推薦模塊的特點:
1 .是要經過對數據模型進行大量分析,并結合用戶剛剛的瀏覽記錄,計算出用戶喜歡喜歡什么商品,然后給他打什么
廣告,運算量相當大。
2 .是廣告推薦模塊不是商城的核心模塊,沒有了這個模塊, 買家照樣可以完成商品的購買。
總結上面兩點, 我們可以在商城負載過高時,對廣告推薦模塊進行降級,讓它只從緩存或靜態(tài)文件中讀取數據,或
者干脆nginx不返回任何數據給它。

五、 設計分析

第一種:從數據
第二種:從微服務
第三種:從緩存
第四種:從文件
第五種:從前端返回
第六種:直接返回空
前5種獲取廣告推薦數據的方式,從上而下,對系統(tǒng)帶來的性能的損耗逐漸降低,最底下的第5種,幾乎對系統(tǒng)沒有損耗,但是數據實時性也是自上而下逐漸降低的,從需求上講,我們更喜歡實時從數據庫讀取,但為了降低性能損耗,在系統(tǒng)負載重的時候, 我們可能不得不降級為從文件或者從緩存中讀取。這個降級是通過一個開關可以控制的。

六、 降級的線路圖

1 降級配置中心, 用于統(tǒng)一管理所有的微服務的降級開關, 該中心是單獨的服務器,和微服務服務器集群是分 開的 2
每個微服務都有一個降級開關。

這個降級開關是個什么東西,結構如何呢?實際上是一條條的redis數據, 每條數據就是一個開關。

這條開關數據的結構是這么設計的:

key:url鏈接中的請求地址。
value:記錄這個請求從哪里讀取數據,也就是配置從哪里查詢數據。

七、實現降級

1. 配置中心

配置中心是一個后臺,這個配置中心大家根據各自需求自己去實現,這里我們采用手工操作redis的方式,實際上是
通過后臺操作的redis。

2. nginx+lua+redis實現降級

nginx配置文件/etc/nginx/nginx.conf

user nobody;
worker_processes  1;
events {
lua降級代碼:/etc/nginx/lua/goods_list_advert.lua
 worker_connections  1024;
}
http {
 lua_package_path "/usr/share/lua/5.1/lua-resty-redis/lib/?.lua;;/usr/share/lua/5.1/lua-
resty-redis-cluster/lib/resty‘7/?.lua;;";
 lua_package_cpath "/usr/share/lua/5.1/lua-resty-redis-cluster/lib/libredis_slot.so;;";
 include    mime.types;
 default_type application/octet-stream;
 sendfile    on;
 keepalive_timeout  65;
 server {
   listen    80;
   server_name  127.0.0.1;
   server_name  192.168.232.100;
    #獲取廣告推薦數據
 location /goods_list_advert {
   default_type 'application/x-javascript;charset=utf-8';
     content_by_lua_file /etc/nginx/lua/goods_list_advert.lua;
   }
    #從服務層+mysql獲取數據
   location /goods_list_advert_from_data {
     default_type 'application/x-javascript;charset=utf-8';
     content_by_lua '
       ngx.say("從服務層+mysql獲取數據")
      ';
   }
 }
}

lua降級代碼:/etc/nginx/lua/goods_list_advert.lua

--獲取get或post參數--------------------

local request_method = ngx.var.request_method
local args = nil
local param = nil
--獲取參數的值
if "GET" == request_method then
    args = ngx.req.get_uri_args()
elseif "POST" == request_method then
    ngx.req.read_body()
    args = ngx.req.get_post_args()
end
sku_id = args["sku_id"]


--關閉redis的函數--------------------

local function close_redis(redis_instance)
    if not redis_instance then
        return
    end
    local ok,err = redis_instance:close();
    if not ok then
        ngx.say("close redis error : ",err);
    end
end


--連接redis--------------------

local redis = require("resty.redis");
--local redis = require "redis"
-- 創(chuàng)建一個redis對象實例。在失敗,返回nil和描述錯誤的字符串的情況下
local redis_instance = redis:new();
--設置后續(xù)操作的超時(以毫秒為單位)保護,包括connect方法
redis_instance:set_timeout(1000)
--建立連接
local ip = '127.0.0.1'
local port = 6379
--嘗試連接到redis服務器正在偵聽的遠程主機和端口
local ok,err = redis_instance:connect(ip,port)
if not ok then
    ngx.say("connect redis error : ",err)
    return close_redis(redis_instance);
end


--從redis里面讀取開關--------------------

local key = "level_goods_list_advert"
local switch, err = redis_instance:get(key)
if not switch then
    ngx.say("get msg error : ", err)
    return close_redis(redis_instance)
end


--得到的開關為空處理--------------------

if switch == ngx.null then
    switch = "FROM_DATA"  --比如默認值
end


--當開關是要從服務中獲取數據時--------------------
if "FROM_DATA" == switch then
    ngx.exec('/goods_list_advert_from_data');

--當開關是要從緩存中獲取數據時--------------------
elseif "FROM_CACHE" == switch then

    local resp, err = redis_instance:get("nihao")
    ngx.say(resp)

--當開關是要從靜態(tài)資源中獲取數據時--------------------
elseif "FROM_STATIC" == switch then

    ngx.header.content_type="application/x-javascript;charset=utf-8"
    local file = "/etc/nginx/html/goods_list_advert.json"
    local f = io.open(file, "rb")
    local content = f:read("*all")
    f:close()
    ngx.print(content)

--當開關是要停掉數據獲取時--------------------
elseif "SHUT_DOWN" == switch then

    ngx.say('no data')
end

八、驗證降級

驗證1 設置為從服務和數據庫讀取

[root@101 redis-5.0.8]# redis-cli
127.0.0.1:6379> set level_goods_list_advert FROM_DATA

發(fā)送請求,發(fā)現廣告推薦請求獲取到了微服務提供的數據

用postman:http://127.0.0.1:6379/get_goods_List

返回數據:[{“name”:[“bingwoo”]}]

驗證2 設置為從緩存讀取

127.0.0.1:6379> set level_goods_list_advert FROM_CACHE

發(fā)送請求,發(fā)現廣告推薦請求獲取到了微服務提供的數據

用postman:http://127.0.0.1:6379/get_goods_List

返回數據:redis_data

驗證3 設置為從靜態(tài)文件讀取

127.0.0.1:6379> set level_goods_list_advert FROM_STATIC

發(fā)送請求,發(fā)現廣告推薦請求獲取到了微服務提供的數據

用postman:http://127.0.0.1:6379/get_goods_List

返回數據:

[
{
“goods_id”:“1”,
“goods_name”:“測試1”,
},
{
“goods_id”:“2”,
“goods_name”:“測試2”,
}
]

驗證4 設置為從緩存讀取

127.0.0.1:6379> set level_goods_list_advert FROM_CACHE

發(fā)送請求,發(fā)現廣告推薦請求獲取到了微服務提供的數據

用postman:http://127.0.0.1:6379/get_goods_List

返回數據:null

九、自動降級

原理:

采用nginx+lua+redis對錯誤返回進行統(tǒng)計,當統(tǒng)計到的錯誤次數達到一定數值時,lua會判斷這個數值, 然后會在/etc/nginx/lua/goods_list_advert.lua中添加如下代碼:

--判斷錯誤的響應,并進行計數, 后續(xù)便可以參考這個數值進行降級
if tonumber(ngx.var.status) == 200 then
  ngx.say(ngx.var.status)
  ngx.log(ngx.ERR,"upstream reponse status is " .. ngx.var.status .. ",please notice it")
  local error_count, err = redis_instance:get("error_count_goods_list_advert")
  --得到的數據為空處理
  if error_count == ngx.null then
    error_count = 0
  end
  error_count = error_count + 1
  --統(tǒng)計錯誤次數到error_count_goods_list_advert
  local resp,err = redis_instance:set("error_count_goods_list_advert",error_count)
  if not resp then
    ngx.say("set msg error : ",err)
    return close_redis(redis_instance)
  end
end

當我們有意關掉一些服務讓狀態(tài)碼不為200時,
可以看到redis中error_count_goods_list_advert的值在加1:

127.0.0.1:6379> get error_count_goods_list_advert “1”

接下來,你就可以在lua中添加判斷, 比如設置一個閾值為100, 當error_count_goods_list_advert的值達到100時(也就是錯誤返回達到100時),你就可以降級為請求另外一個版本(老版本程序)

到此這篇關于nginx+lua+redis實現降級的示例代碼的文章就介紹到這了,更多相關nginx+lua+redis降級內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • nginx使用rewrite報錯的解決

    nginx使用rewrite報錯的解決

    本文主要介紹了nginx使用rewrite報錯的解決,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-03-03
  • Nginx配置UDP代理的實現

    Nginx配置UDP代理的實現

    使用Nginx作為UDP代理可以幫助您實現數據包的轉發(fā)和負載均衡,本文就詳細的來介紹一下Nginx配置UDP代理,具有一定的參考價值,感興趣的可以了解一下
    2023-08-08
  • Nginx緩存清理實現方式

    Nginx緩存清理實現方式

    Nginx的緩存機制通過存儲響應數據來加速頁面響應,減少重復處理,合適的緩存清理策略(基于時間、空間、請求等)可以釋放磁盤空間,確保緩存數據的時效性,防止緩存穿透和數據過時等問題,結合Nginx的內置緩存機制與外部工具,可以更靈活地控制緩存清理的過程
    2025-12-12
  • 使用Nginx反向代理與proxy_cache緩存搭建CDN服務器的配置方法

    使用Nginx反向代理與proxy_cache緩存搭建CDN服務器的配置方法

    linux下通過Nginx反向代理和proxy_cache緩存搭建CDN服務器加快Web訪問速度的配置方法
    2013-06-06
  • Ubuntu16.04上為Nginx創(chuàng)建自簽名SSL證書

    Ubuntu16.04上為Nginx創(chuàng)建自簽名SSL證書

    SSL證書是實現HTTPS的關鍵組成部分,本文主要介紹了Ubuntu16.04上為Nginx創(chuàng)建自簽名SSL證書,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2024-05-05
  • Nginx的重寫Rewrite使用示例分析

    Nginx的重寫Rewrite使用示例分析

    這篇文章主要介紹了Nginx Rewrite功能使用,rewrite是Nginx服務器提供的一個重要基本功能,主要作用用來實現URL地址重寫,需要的朋友可以參考下
    2022-05-05
  • HTTP 499 狀態(tài)碼 nginx下 499錯誤的解決辦法

    HTTP 499 狀態(tài)碼 nginx下 499錯誤的解決辦法

    HTTP狀態(tài)碼出現499錯誤有多種情況,499錯誤是什么?Nginx 499錯誤的原因及解決方法,下面跟著腳本之家小編一起學習吧
    2016-06-06
  • Nginx解決vue項目服務器部署及跨域訪問后端詳解

    Nginx解決vue項目服務器部署及跨域訪問后端詳解

    跨域問題在前后端分離項目很常見,至于為什么會跨域,同源策略,百度各種博客都很詳細,這里不再介紹,這篇文章主要給大家介紹了關于Nginx解決vue項目服務器部署及跨域訪問后端的相關資料,需要的朋友可以參考下
    2022-11-11
  • 使用Nginx代理MySQL連接并限制可訪問IP配置

    使用Nginx代理MySQL連接并限制可訪問IP配置

    這篇文章主要為大家介紹了如何使用Nginx代理MySQL連接并限制可訪問IP配置示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-08-08
  • 基于Nginx實現限制某IP短時間訪問次數

    基于Nginx實現限制某IP短時間訪問次數

    這篇文章主要介紹了基于Nginx實現限制某IP短時間訪問次數,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-12-12

最新評論

邵武市| 饶平县| 新营市| 藁城市| 榕江县| 军事| 新昌县| 宁阳县| 都兰县| 崇信县| 凉城县| 桐庐县| 黑河市| 绍兴县| 安图县| 方正县| 和平区| 木里| 隆林| 威宁| 大新县| 郴州市| 建德市| 南汇区| 碌曲县| 措美县| 天门市| 和田县| 安化县| 达尔| 韩城市| 高唐县| 安多县| 龙口市| 大关县| 绿春县| 汾西县| 东兴市| 基隆市| 老河口市| 珲春市|