色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

nginx+lua+redis實現(xiàn)灰度發(fā)布

京東云 ? 來源:馬仁喜 ? 作者:馬仁喜 ? 2024-12-17 10:01 ? 次閱讀

作者:馬仁喜

前言:授人以魚不如授人以漁.先學會用,在學原理,在學創(chuàng)造,可能一輩子用不到這種能力,但是不能不具備這種能力。這篇文章主要是沉淀使用nginx+lua+redis實現(xiàn)灰度,當我們具備了這種能力,隨時可以基于這種能力和思想調(diào)整實現(xiàn)方案:比如nginx+lua+(其他數(shù)據(jù)源)、nginx+(其他腳本語言)

一、灰度方案:

常見的灰度實現(xiàn)方案:

1.請求路由:通過請求中的標識(如用戶ID、設(shè)備ID、請求頭等)來決定是否將請求路由到灰度環(huán)境。可以使用反向代理(如Nginx、Envoy)或API網(wǎng)關(guān)(如Kong、Apigee)來實現(xiàn)路由規(guī)則。

2.權(quán)重控制:將流量按照一定的權(quán)重比例分配到不同的環(huán)境中。可以通過負載均衡器(如HAProxy、Kubernetes Ingress)或代理服務(wù)器(如Nginx、Envoy)來實現(xiàn)權(quán)重控制。

3.特性開關(guān):通過在代碼中嵌入特性開關(guān)(Feature Flag)來控制功能的開啟與關(guān)閉。可以使用配置文件、數(shù)據(jù)庫、鍵值存儲或特性管理平臺(如LaunchDarkly、Unleash)來管理特性開關(guān)。

4.分階段發(fā)布:將功能的發(fā)布分為多個階段,從內(nèi)部測試到灰度環(huán)境再到全量發(fā)布。可以使用部署工具(如Jenkins、GitLab CI/CD)或云平臺(如AWS、Azure)來支持分階段發(fā)布。

5.A/B測試:將流量分為多個不同版本的應(yīng)用程序,比較它們的性能和用戶反饋。可以使用A/B測試平臺(如Optimizely、Google Optimize)來管理和監(jiān)控A/B測試。

6.金絲雀發(fā)布:將新版本的應(yīng)用程序逐步引入生產(chǎn)環(huán)境,僅將少量流量導(dǎo)向新版本,并根據(jù)其性能和穩(wěn)定性逐步增加流量。可以使用部署工具、容器編排平臺或云平臺來實現(xiàn)金絲雀發(fā)布。

?

常用的灰度發(fā)布方案:

1.基于用戶ID的灰度發(fā)布:基于用戶ID來劃分灰度用戶或百分比灰度,例如根據(jù)用戶ID的哈希值或隨機數(shù)來決定用戶是否路由到灰度環(huán)境。

2.基于IP地址的灰度發(fā)布:根據(jù)用戶的IP地址來劃分灰度用戶,例如將某一范圍的IP地址指定為灰度用戶,將請求從這些IP地址路由到灰度環(huán)境。

3.Cookie/Session的灰度發(fā)布:通過在用戶的Cookie或會話中設(shè)置特定的標識來劃分灰度用戶。例如,將特定的Cookie或會話變量設(shè)置為灰度標識,將具有該標識的請求路由到灰度環(huán)境。

4.請求頭的灰度發(fā)布:基于請求頭中的特定標識來劃分灰度用戶。例如,根據(jù)請求頭中的自定義標識或特定的HTTP Header來路由請求到灰度環(huán)境。

5.權(quán)重或百分比的灰度發(fā)布:將請求隨機分配給不同的環(huán)境,可以通過給不同環(huán)境設(shè)置不同的權(quán)重或百分比來控制流量的分配。

6.A/B測試:將流量分為多個不同版本的應(yīng)用程序,在實驗期間比較它們的性能和用戶反饋,最終選擇最佳版本進行全量發(fā)布。

?

二、nginx+lua+redis實現(xiàn)灰度

理論:

1、安裝并配置 Nginx 和 Redis。確保 Nginx 啟用 Lua 模塊,并可以訪問 Redis。

2、在 Nginx 配置中定義灰度規(guī)則。您可以使用 Lua 腳本來判斷用戶是否應(yīng)該被路由到灰度環(huán)境。示例配置如下:

server {
    listen 80;
    server_name example.com;
    location / {
        access_by_lua_block {
            local redis = require "resty.redis"
            local red = redis:new()
            -- 連接到 Redis
            local ok, err = red:connect("redis_host", redis_port)
            if not ok then
                ngx.log(ngx.ERR, "failed to connect to Redis: ", err)
                ngx.exit(500)
            end
            -- 使用 Redis 根據(jù)用戶 ID 判斷是否路由到灰度環(huán)境
            local user_id = ngx.req.get_headers()["X-User-ID"]
            local is_gray = red:get("gray:" .. user_id)
            if is_gray == "1" then
                ngx.var.upstream = "gray_backend"
            end
        }
        proxy_pass http://backend;
    }
    location /gray {
        # 灰度環(huán)境的配置
        proxy_pass http://gray_backend;
    }
    location /admin {
        # 管理后臺的配置
        proxy_pass http://admin_backend;
    }
}

在上面的示例中,我們連接到 Redis,并根據(jù)請求中的用戶 ID 判斷是否將請求路由到灰度環(huán)境。ngx.var.upstream 變量用于動態(tài)設(shè)置上游地址,從而實現(xiàn)灰度環(huán)境的路由。

3、在 Redis 中設(shè)置灰度用戶。您可以在 Redis 中維護一個鍵值對,其中鍵是用戶 ID,值表示是否是灰度用戶(例如,1 表示是灰度用戶,0 表示不是)。您可以使用 Redis 的 SET 和 GET 命令來操作這些值。

-- 設(shè)置用戶為灰度用戶
local ok, err = red:set("gray:" .. user_id, 1)
if not ok then
    ngx.log(ngx.ERR, "failed to set gray status for user: ", err)
    ngx.exit(500)
end

-- 設(shè)置用戶為非灰度用戶
local ok, err = red:set("gray:" .. user_id, 0)
if not ok then
    ngx.log(ngx.ERR, "failed to set gray status for user: ", err)
    ngx.exit(500)
end

通過在 Redis 中設(shè)置用戶的灰度狀態(tài),您可以動態(tài)地控制用戶是否應(yīng)該被路由到灰度環(huán)境。

4、根據(jù)需要,配置其他路徑或功能的灰度規(guī)則。您可以根據(jù)需要在 Nginx 配置中添加其他路徑或功能的灰度規(guī)則,以實現(xiàn)更復(fù)雜的灰度發(fā)布策略。

實踐:

這里主要使用OpenResty

nginx+lua 實現(xiàn)灰度----主要使用OpenResty

OpenResty(又稱:ngx_openresty) 是一個基于 NGINX 的可伸縮的 Web 平臺,OpenResty 是一個強大的 Web 應(yīng)用服務(wù)器,Web 開發(fā)人員可以使用 Lua 腳本語言調(diào)動 Nginx 支持的各種 C 以及 Lua 模塊

openresty的api文檔: https://www.kancloud.cn/qq13867685/openresty-api-cn/159190

1、根據(jù)post請求url參數(shù)匹配進行路由

nginx配置如下:

#user  nobody;
worker_processes  1;
#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;
#pid        logs/nginx.pid;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    #log_format  main '$time_local 客戶端地址:$remote_addr–$remote_port 請求的URI和HTTP協(xié)議:$request 請求地址:$http_host HTTP請求狀態(tài):$status upstream狀態(tài):$upstream_status 負載地址:$upstream_addr url跳轉(zhuǎn)來源:$http_referer $body_bytes_sent $http_user_agent $request_uri';
    log_format  logFormat '$group $time_local 客戶端:$remote_addr–$remote_port 請求的URI和HTTP協(xié)議:$request 請求:$http_host HTTP狀態(tài):$status upstream狀態(tài):$upstream_status 負載:$upstream_addr 
                          url跳轉(zhuǎn):$http_referer $body_bytes_sent $http_user_agent $request_uri 請求參數(shù) $query_string $args $document_root $uri
                          -----$request_uri $request_filename $http_cookie';
    access_log  logs/access.log  logFormat;
    sendfile        on;
    #tcp_nopush     on;
    #keepalive_timeout  0;
    keepalive_timeout  65;
    server{
        listen       80;   #監(jiān)聽端口
        server_name  域名; #監(jiān)聽地址 
        access_log  logs/xx.com.access.log  logFormat;
              location /hello {
                default_type 'text/plain';
                content_by_lua 'ngx.say("hello ,lua scripts")';
        }
        location /myip {
                default_type 'text/plain';
                content_by_lua '
                        clientIP = ngx.req.get_headers()["x_forwarded_for"]
                        ngx.say("Forwarded_IP:",clientIP)
                        if clientIP == nli then
                                clientIP = ngx.var.remote_addr
                                ngx.say("Remote_IP:",clientIP)
                        end
                        ';
        }
        location / {
                default_type 'text/plain';
                lua_need_request_body on;
                #content_by_lua_file /etc/nginx/lua/dep.lua;
                #content_by_lua_file D:/sortware/openresty/openresty-1.17.8.2-win64/conf/dep.lua; # 指定由lua文件處理http請求
                content_by_lua_file D:/user/Downloads/openresty-1.19.9.1-win64/conf/dep.lua; # 指定由lua文件處理http請求
        }
        location @default_version {
            proxy_pass http://default; 
            proxy_set_header  Host  $http_host;
            proxy_set_header  X-Real-IP  $remote_addr;
            proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
        }
        location @new_version {
            proxy_pass http://new_version;
            proxy_set_header Host $http_host;
            #proxy_redirect default;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
        location @old_version {
            proxy_pass http://old_version; 
            proxy_set_header Host $http_host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;    
        }
    }
	#標準預(yù)發(fā)環(huán)境
	upstream default {
		 server ip:port;
	}
    #預(yù)發(fā)2
	upstream new_version {
		 server ip:port;
	}
    #預(yù)發(fā)3
	upstream old_version {
		server ip:port;
	}
}

lua腳本如下:

--get請求uri參數(shù)

function SaveTableContent(file, obj)
      local szType = type(obj);
      print(szType);
      if szType == "number" then
            file:write(obj);
      elseif szType == "string" then
            file:write(string.format("%q", obj));
      elseif szType == "table" then
            --把table的內(nèi)容格式化寫入文件
            --file:write("{n");
            for i, v in pairs(obj) do
                  SaveTableContent(file, i);
                  file:write(":");
                  SaveTableContent(file, v);
                  file:write(",");
			end
            --file:write("}n");
      else
			error("can't serialize a "..szType);
      end
end

function SaveTable(obj)

      local file = io.open("D:\user\Downloads\openresty-1.19.9.1-win64\logs\parmas.txt", "a");
      assert(file);
      SaveTableContent(file,obj);
      file:close();
end

local request_method = ngx.var.request_method
local getargs = nil
local args = nil
local read_body = nil
local body_data = nil
local thirdPolicystatus = nil
if "GET" == request_method then
	args = ngx.req.get_uri_args()
elseif "POST"== request_method then
	getargs = ngx.req.get_uri_args()
	args  	  = ngx.req.get_post_args()
	read_body = ngx.req.read_body()
	body_data = ngx.req.get_body_data()
end
if getargs ~= nil then
	SaveTable(getargs);
	thirdPolicystatus= getargs["thirdPolicystatus"];
	if thirdPolicystatus ~= nil then
		SaveTable(thirdPolicystatus);
	end
end

if args ~= nil then
	SaveTable(args);
end

if read_body ~= nil then
	SaveTable(read_body);
end

if body_data ~= nil then
	SaveTable(body_data);
end

if getargs ~= nil then
	thirdPolicystatus = getargs["thirdPolicystatus"]
	if thirdPolicystatus ~= nil and thirdPolicystatus == "1" then
		SaveTable("new_version-getargs");
		ngx.exec('@new_version')
	elseif thirdPolicystatus ~= nil and thirdPolicystatus == "2" then
		SaveTable("old_version-getargs");
		ngx.exec('@old_version')
	else
		SaveTable("default_version-getargs");
		ngx.exec('@default_version')
	end
end

if args ~= nil then
	if type(args) == "table" then
		thirdPolicystatus = tostring(args["thirdPolicystatus"])
		if thirdPolicystatus ~= nil and thirdPolicystatus == 1 then
			SaveTable("new_version-args-table");
			ngx.exec('@new_version')
		elseif thirdPolicystatus ~= nil and thirdPolicystatus == 2 then
			SaveTable("old_version-args-table");
			ngx.exec('@old_version')
		else
			SaveTable("default_version-args-table");
			ngx.exec('@default_version')
		end
	elseif type(args) == "string" then
		local json = require("cjson")
		local jsonObj = json.decode(args)
			thirdPolicystatus = jsonObj['thirdPolicystatus']
		if thirdPolicystatus ~= nil and thirdPolicystatus == 1 then
			SaveTable("new_version-args-string");
			ngx.exec('@new_version')
		elseif thirdPolicystatus ~= nil and thirdPolicystatus == 2 then
			SaveTable("old_version-args-string");
			ngx.exec('@old_version')
		else
			SaveTable("default_version-args-string");
			ngx.exec('@default_version')
		end
	end
end
return

host如下:

127.0.0.1  域名

訪問地址:

域名

菜單運營數(shù)據(jù)---保單數(shù)據(jù),默認走default集群,保單狀態(tài)承保成功走new_version集群,保單狀態(tài)終止走old_version集群

2、根據(jù)請求參數(shù)或ip等進行匹配redis緩存數(shù)據(jù)進行路由,靈活性更高。

redis下載地址:https://github.com/tporadowski/redis/releases

nginx配置如下:

#user  nobody;
worker_processes  1;
#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;
#pid        logs/nginx.pid;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    #log_format  main '$time_local 客戶端地址:$remote_addr–$remote_port 請求的URI和HTTP協(xié)議:$request 請求地址:$http_host HTTP請求狀態(tài):$status upstream狀態(tài):$upstream_status 負載地址:$upstream_addr url跳轉(zhuǎn)來源:$http_referer $body_bytes_sent $http_user_agent $request_uri';
    log_format  logFormat '$group $time_local 客戶端:$remote_addr–$remote_port 請求的URI和HTTP協(xié)議:$request 請求:$http_host HTTP狀態(tài):$status upstream狀態(tài):$upstream_status 負載:$upstream_addr 
                          url跳轉(zhuǎn):$http_referer $body_bytes_sent $http_user_agent $request_uri 請求參數(shù) $query_string $args $document_root $uri
                          -----$request_uri $request_filename $http_cookie';
    access_log  logs/access.log  logFormat;
    sendfile        on;
    #tcp_nopush     on;
    #keepalive_timeout  0;
    keepalive_timeout  65;
   server{
        listen       80;   #監(jiān)聽端口
        server_name  域名; #監(jiān)聽地址 
        access_log  logs/xx.com.access.log  logFormat;
              location /redis {
                default_type 'text/plain';
                content_by_lua 'ngx.say("hello ,lua scripts redis")';
        }
        location / {
                default_type 'text/plain';
                lua_need_request_body on;
                content_by_lua_file D:/user/Downloads/openresty-1.19.9.1-win64/conf/redis.lua; # 指定由lua文件處理http請求
        }
        location @pre-prd {
            proxy_pass http://pre-prd;
            proxy_set_header Host $http_host;
            #proxy_redirect default;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
        location @prd {
            proxy_pass http://prd; 
            proxy_set_header Host $http_host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;    
        }
    }
    #預(yù)發(fā)2演示線上
	upstream prd {
		 server ip:port;
	}
    #預(yù)發(fā)演示預(yù)發(fā)線上
	upstream pre-prd {
		 server ip:port;
	}
}

lua腳本如下:

--get請求uri參數(shù)
function SaveTableContent(file, obj)
      local szType = type(obj);
      print(szType);
      if szType == "number" then
            file:write(obj);
      elseif szType == "string" then
            file:write(string.format("%q", obj));
      elseif szType == "table" then
            --把table的內(nèi)容格式化寫入文件
            --file:write("{n");
            for i, v in pairs(obj) do
                  SaveTableContent(file, i);
                  file:write(":");
                  SaveTableContent(file, v);
                  file:write(",");
			end
            --file:write("}n");
      else
			error("can't serialize a "..szType);
      end
end

function SaveTable(obj)
      --local file = io.open("D:\user\Downloads\openresty-1.19.9.1-win64\logs\parmas.txt", "a");
      local file = io.open("D:\user\Downloads\openresty-1.19.9.1-win64\logs\redis.txt", "a");
      assert(file);
      SaveTableContent(file,obj);
      file:close();
end


local request_method = ngx.var.request_method
local getargs = nil
local args = nil
local read_body = nil
local body_data = nil
local thirdPolicystatus = nil
if "GET" == request_method then
	args = ngx.req.get_uri_args()
elseif "POST"== request_method then
	getargs = ngx.req.get_uri_args()
	args  	  = ngx.req.get_post_args()
	read_body = ngx.req.read_body()
	body_data = ngx.req.get_body_data()
end

if getargs ~= nil then
	SaveTable("getargs");
	SaveTable(getargs);
	thirdPolicystatus= getargs["thirdPolicystatus"];
	if thirdPolicystatus ~= nil then
		SaveTable("thirdPolicystatus");
		SaveTable(thirdPolicystatus);
	end
end

if args ~= nil then
	SaveTable("args");
	SaveTable(args);
end

if read_body ~= nil then
	SaveTable("read_body");
	SaveTable(read_body);
end

if body_data ~= nil then
	SaveTable("body_data");
	SaveTable(body_data);
end


local redis = require "resty.redis"
local cache = redis.new()
cache:set_timeout(60000)

local ok, err = cache.connect(cache, '127.0.0.1', 6379)
if not ok then
	SaveTable("not ok");
	ngx.exec("@prd")
	return
end

local local_ip = ngx.req.get_headers()["X-Real-IP"]
if local_ip == nil then
        local_ip = ngx.req.get_headers()["x_forwarded_for"]
		SaveTable("local_ip1");
		if local_id ~= nil then
		SaveTable(local_id);
		end
end

if local_ip == nil then
	local_ip = ngx.var.remote_addr
	SaveTable("local_ip2");
	if local_id ~= nil then
	SaveTable(local_id);
	end
end

-- 在 redis 中根據(jù)客戶端 ip 獲取是否存在值
local res, err = cache:get(local_ip)
-- 如果存在則轉(zhuǎn)發(fā)到 @pre-prd
if res == "1" then
		SaveTable(res);
		SaveTable("pre-prd");
        ngx.exec("@pre-prd")
        return
else
	SaveTable("-------");
	SaveTable(local_ip);
	SaveTable(res);
	cache:set(local_ip)
end

-- 如果不存在,則轉(zhuǎn)發(fā)到 @prd
SaveTable("prd");
ngx.exec("@prd")

local ok, err = cache:close()
if not ok then
    ngx.say("failed to close:", err)
    return
end
return

使用時這里根據(jù)redis緩里緩存的ip地址進行負載路由。

?

三、相關(guān)配置與語法

1、Nginx配置文件詳解

源碼:https://trac.nginx.org/nginx/browser

官網(wǎng):http://www.nginx.org/

windows 安裝包下載地址:https://nginx.org/en/download.html

nginx.conf

########### 每個指令必須有分號結(jié)束。#################
# 全局塊  比如工作進程數(shù),定義日志路徑;
#配置用戶或者組,默認為nobody nobody。
#user  nobody;
#user administrator administrators;

#允許生成的進程數(shù),默認為1,一般建議設(shè)成CPU核數(shù)1-2倍
worker_processes 1;
#worker_processes  8;


#指定nginx進程運行文件存放地址
#pid /nginx/pid/nginx.pid;

#制定日志路徑,級別。這個設(shè)置可以放入全局塊,http塊,server塊,級別依次為:#debug|info|notice|warn|error|crit|alert|emerg
error_log logs/error.log error;
#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#Events塊 設(shè)置處理輪詢事件模型,每個工作進程最大連接數(shù)及http層的keep-alive超時時間;
events {
   	#使用epoll的I/O 模型處理輪詢事件。
   	#可以不設(shè)置,nginx會根據(jù)操作系統(tǒng)選擇合適的模型
   	#事件驅(qū)動模型,select|poll|kqueue|epoll|resig|/dev/poll|eventport
   	#use epoll; 
   	#工作進程的最大連接數(shù)量, 默認1024個
   	worker_connections  2048;

    #設(shè)置網(wǎng)路連接序列化,防止驚群現(xiàn)象發(fā)生,默認為on
    accept_mutex on;  
    #設(shè)置一個進程是否同時接受多個網(wǎng)絡(luò)連接,默認為off   
    multi_accept on;  
}

# http塊 路由匹配、靜態(tài)文件服務(wù)器、反向代理、負載均衡等
http {
 	# 導(dǎo)入文件擴展名與文件類型映射表 mime.types
    include       mime.types;
    #默認文件類型,默認為text/plain
    default_type  application/octet-stream;
    #取消服務(wù)日志 
    #access_log off; 
    #日志格式及access日志路徑 自定義格式
    log_format myFormat '$time_local 客戶端地址:$remote_addr–$remote_port 請求的URI和HTTP協(xié)議:$request 請求地址:$http_host HTTP請求狀態(tài):$status upstream狀態(tài):$upstream_status 負載地址:$upstream_addr url跳轉(zhuǎn)來源:$http_referer $upstream_addr $body_bytes_sent $http_user_agent';
    #combined為日志格式的默認值
    access_log logs/access.log myFormat;
    #允許sendfile方式傳輸文件,默認為off,可以在http塊,server塊,location塊。
    sendfile on; 
    #sendfile開啟時才開啟。
    tcp_nopush   on; 
	server_names_hash_bucket_size 64; 
    #每個進程每次調(diào)用傳輸數(shù)量不能大于設(shè)定的值,默認為0,即不設(shè)上限。
    sendfile_max_chunk 100k;
    #連接超時時間,默認為75s,可以在http,server,location塊。
    keepalive_timeout 65;

    #--------------------靜態(tài)文件壓縮-----------------------------#
    #Nginx可以對網(wǎng)站的css、js 、xml、html 文件在傳輸前進行壓縮,大幅提高頁面加載速度。經(jīng)過Gzip壓縮后頁面大小可以變?yōu)樵瓉淼?0%甚至更小。使用時僅需開啟Gzip壓縮功能即可。你可以在http全局塊或server塊增加這個配置。
    # 開啟gzip壓縮功能
    #gzip  on;
    gzip on;
     
    # 設(shè)置允許壓縮的頁面最小字節(jié)數(shù); 這里表示如果文件小于10k,壓縮沒有意義.
    gzip_min_length 10k; 
 
    # 設(shè)置壓縮比率,最小為1,處理速度快,傳輸速度慢;
    # 9為最大壓縮比,處理速度慢,傳輸速度快; 推薦6
    gzip_comp_level 6; 
     
    # 設(shè)置壓縮緩沖區(qū)大小,此處設(shè)置為16個8K內(nèi)存作為壓縮結(jié)果緩沖
    gzip_buffers 16 8k; 
     
    # 設(shè)置哪些文件需要壓縮,一般文本,css和js建議壓縮。圖片視需要要鎖。
    gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript; 
    #--------------------靜態(tài)文件壓縮-----------------------------#
	server {
		listen       80;
		server_name  localhost;
		location / {
            root   html;
            index  index.html index.htm;
        }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
    #http server塊
    server {
        keepalive_requests 120; #單連接請求上限次數(shù)。
        listen       8081;   #監(jiān)聽端口
        server_name  域名 #監(jiān)聽地址
        #ssi on;
		#autoindex on;
        charset utf-8;
        client_max_body_size 10M; # 限制用戶上傳文件大小,默認1M
        #access_log  logs/host.access.log  myFormat; #定義訪問日志,可以針對每一個server(即每一個站點)設(shè)置它們自己的訪問日志。

        # 轉(zhuǎn)發(fā)動態(tài)請求到web應(yīng)用服務(wù)器
        #location ^~ /api {
            #rewrite ^/api/(.*)$ /$1 break;
            #proxy_pass https://stream;
            #break;#終止匹配
        #}
		location / {
           # 使用proxy_pass轉(zhuǎn)發(fā)請求到通過upstream定義的一組應(yīng)用服務(wù)器
			proxy_pass      http://stream ;
			proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
			proxy_set_header Host $http_host;
			proxy_redirect off;
			proxy_set_header X-Real-IP  $remote_addr;
        }
		location  ~*^.+$ {       #請求的url過濾,正則匹配,~為區(qū)分大小寫,~*為不區(qū)分大小寫。  
			proxy_pass  	http://stream ;  #請求轉(zhuǎn)向stream 定義的服務(wù)器列表          
        } 
		
        #location / {
            #autoindex on;
            #try_files $uri $uri/ /index.html?$args;
        #}

        # 規(guī)則1:通用匹配
        #location / {
			#ssi on;
			#autoindex on;                 #自動顯示目錄
            #autoindex_exact_size off;     #人性化方式顯示文件大小否則以byte顯示
            #autoindex_localtime on;       #按服務(wù)器時間顯示,否則以gmt時間顯示
            #root   /root;                 #定義服務(wù)器的默認網(wǎng)站根目錄位置 
            #index index.html index.htm;   #定義首頁索引文件的名稱  設(shè)置默認頁
            # 使用proxy_pass轉(zhuǎn)發(fā)請求到通過upstream定義的一組應(yīng)用服務(wù)器
            #proxy_pass   http://mysvr;      #負載配置
            #proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            #proxy_set_header Host $http_host;
            #proxy_redirect off;
            #proxy_set_header X-Real-IP  $remote_addr; 
            #deny ip;  # 拒絕的ip
            #allow ip; # 允許的ip 
        #}

        # 規(guī)則2:處理以/static/開頭的url
        location ^~ /static {                         
            alias /usr/share/nginx/html/static; # 靜態(tài)資源路徑
        }
        #= 精確匹配 1
        #^~ 以某個字符串開頭 2
        #~ 區(qū)分大小寫的正則匹配 3
        #~* 不區(qū)分大小寫的正則匹配 4
        #!~ 區(qū)分大小寫的不匹配正則 5
        #!~* 不區(qū)分大小寫的不匹配正則 6
        #/ 通用匹配,任何請求都會匹配到 7
        #location  ~*^.+$ {       #請求的url過濾,正則匹配,~為區(qū)分大小寫,~*為不區(qū)分大小寫。  
            #root path;  #根目錄
            #index vv.txt;  #設(shè)置默認頁
			#proxy_pass  http://stream;  #請求轉(zhuǎn)向stream 定義的服務(wù)器列表
            #deny 127.0.0.1;  #拒絕的ip
            #allow ip; #允許的ip           
        #} 
        #-----------------------------靜態(tài)文件緩存--------------------#
        #緩存可以加快下次靜態(tài)文件加載速度。我們很多與網(wǎng)站樣式相關(guān)的文件比如css和js文件一般不怎么變化,緩存有效器可以通過expires選項設(shè)置得長一些。
        # 使用expires選項開啟靜態(tài)文件緩存,10天有效
        location ~ ^/(images|javascript|js|css|flash|media|static)/  {
             root    /var/www/big.server.com/static_files;
            expires 10d;
        }
		#-----------------------------靜態(tài)文件緩存--------------------#
        # 錯誤頁面
		error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }

    #-------------$符號的全局變量含義--------------#
    #$args, 請求中的參數(shù);
    #$content_length, HTTP請求信息里的"Content-Length";
    #$content_type, 請求信息里的"Content-Type";
    #$document_root, 針對當前請求的根路徑設(shè)置值;
    #$document_uri, 與$uri相同;
    #$host, 請求信息中的"Host",如果請求中沒有Host行,則等于設(shè)置的服務(wù)器名;
    #$limit_rate, 對連接速率的限制;
    #$request_method, 請求的方法,比如"GET"、"POST"等;
    #$remote_addr, 客戶端地址;
    #$remote_port, 客戶端端口號;
    #$remote_user, 客戶端用戶名,認證用;
    #$request_filename, 當前請求的文件路徑名
    #$request_body_file,當前請求的文件
    #$request_uri, 請求的URI,帶查詢字符串;
    #$query_string, 與$args相同;
    #$scheme, 所用的協(xié)議,比如http或者是https,比如rewrite ^(.+)$
    #$scheme://example.com$1 redirect;        
    #$server_protocol, 請求的協(xié)議版本,"HTTP/1.0"或"HTTP/1.1";
    #$server_addr, 服務(wù)器地址;
    #$server_name, 請求到達的服務(wù)器名;
    #$server_port, 請求到達的服務(wù)器端口號;
    #$uri, 請求的URI,可能和最初的值有不同,比如經(jīng)過重定向之類的。
    #-------------$符號的全局變量含義--------------#

    
    #錯誤頁面
    #error_page 404 https://www.baidu.com; #錯誤頁
    #error_page 404 500 502 503 504 403 /error.shtml;
    
    # 負載均衡
    upstream insurance-pre {   
      #weigth參數(shù)表示權(quán)值,權(quán)值越高被分配到的幾率越大
      #--------------------負載均衡方式------------------#
      #1.輪詢(默認)
      #2.權(quán)重,weight越大,承擔任務(wù)越多
      #server ip:port weight=5
      #3.ip_hash   
      #ip_hash;
      #4.url_hash
      #hash $request_uri;
      #5. fair(第三方)--按后端服務(wù)器的響應(yīng)時間來分配請求,響應(yīng)時間短的優(yōu)先分配。使用這個算法需要安裝nginx-upstream-fair這個庫。
      #fair;
      #--------------------負載均衡方式------------------#
      server ip:port   weight=5; # weight越高,權(quán)重越大
      server ip:port weight=1;
      server ip:port  weight=1;
      server ip:port backup; # 熱備
    }
	# 轉(zhuǎn)發(fā)動態(tài)請求
    #server {  
        #listen 80;                                                         
        #server_name  localhost;                                               
        #client_max_body_size 1024M;
        #location / {
            #proxy_pass http://localhost:8080;   
            #proxy_set_header Host $host:$server_port;
        #}
    #} 
    # http請求重定向到https請求
    #server {
        #listen 80;
        #server_name 域名;
        #return 301 https://$server_name$request_uri;
    #}
    server {
        keepalive_requests 120; #單連接請求上限次數(shù)。
        listen       80;   #監(jiān)聽端口
        server_name  域名 #監(jiān)聽地址
        #ssi on;
		#autoindex on;
        charset utf-8;
        client_max_body_size 10M; # 限制用戶上傳文件大小,默認1M
        #access_log  logs/host.access.log  myFormat; #定義訪問日志,可以針對每一個server(即每一個站點)設(shè)置它們自己的訪問日志。
        # 轉(zhuǎn)發(fā)動態(tài)請求到web應(yīng)用服務(wù)器
        #location ^~ /api {
            #rewrite ^/api/(.*)$ /$1 break;
            #proxy_pass https://域名;
            #break;#終止匹配
        #}
		location / {
           # 使用proxy_pass轉(zhuǎn)發(fā)請求到通過upstream定義的一組應(yīng)用服務(wù)器
			proxy_pass       http://tomcat_gray1;
			proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
			proxy_set_header Host $http_host;
			proxy_redirect off;
			proxy_set_header X-Real-IP  $remote_addr;
        }
		location  ~*^.+$ {       #請求的url過濾,正則匹配,~為區(qū)分大小寫,~*為不區(qū)分大小寫。  
			proxy_pass  	http://域名;  #請求轉(zhuǎn)向域名 定義的服務(wù)器列表          
        } 
    }
    #標準預(yù)發(fā)環(huán)境
	upstream tomcat_gray1 {
		server ip; 
		server 域名;
	}

	upstream tomcat_gray2 {
		server 域名;
	}
}

host 配置

127.0.0.1  域名

瀏覽器訪問 域名

可以通過觀察access.log發(fā)現(xiàn)請求接入日志。

2、lua基礎(chǔ)語法

教程:https://www.runoob.com/lua/if-else-statement-in-lua.html

lua的IDE編輯器:https://github.com/rjpcomputing/luaforwindows

3、nginx實現(xiàn)灰度

根據(jù)前端請求參數(shù)進行灰度到不同節(jié)點。

#user  nobody;
worker_processes  1;
#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;
#pid        logs/nginx.pid;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    #log_format  main '$time_local 客戶端地址:$remote_addr–$remote_port 請求的URI和HTTP協(xié)議:$request 請求地址:$http_host HTTP請求狀態(tài):$status upstream狀態(tài):$upstream_status 負載地址:$upstream_addr url跳轉(zhuǎn)來源:$http_referer $body_bytes_sent $http_user_agent $request_uri';
    log_format  logFormat '$group $time_local 客戶端:$remote_addr–$remote_port 請求的URI和HTTP協(xié)議:$request 請求:$http_host HTTP狀態(tài):$status upstream狀態(tài):$upstream_status 負載:$upstream_addr 
                          url跳轉(zhuǎn):$http_referer $body_bytes_sent $http_user_agent $request_uri 請求參數(shù) $query_string $args $document_root $uri
                          -----$request_uri $request_filename $http_cookie';
    access_log  logs/access.log  logFormat;
    sendfile        on;
    #tcp_nopush     on;
    #keepalive_timeout  0;
    keepalive_timeout  65;
    #gzip  on;
    server {
        listen       80;   #監(jiān)聽端口
        server_name  域名; #監(jiān)聽地址 
        access_log  logs/xx.com.access.log  logFormat;
        #方式二、nginx+lua實現(xiàn)灰度
        ## 1、將對localhost訪問由/opt/app/lua/dep.lua進行處理
        ## 2、根據(jù)邏輯處理后,決定回調(diào)如下兩個其中1個內(nèi)部跳轉(zhuǎn)
        #方式三根據(jù)請求參數(shù)值匹配進行路由
        #/policy/policyInfoList?thirdPolicystatus=2
        set $group "default";
        if ($query_string ~* "thirdPolicystatus=1"){ #動態(tài)控制路由
            set $group new_version;
        }
        if ($query_string ~* "thirdPolicystatus=2"){
            set $group old_version;
        }
        location / 
        {
            default_type "text/html"; 
            #content_by_lua_file D:/sortware/openresty/openresty-1.17.8.2-win64/conf/dep.lua; # 指定由lua文件處理http請求
            proxy_pass http://$group;
            proxy_set_header  Host       $host;
            proxy_set_header  X-Real-IP    $remote_addr;
            proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
            index index.html index.htm;
        }
    }
	#標準預(yù)發(fā)環(huán)境
	upstream default {
		server ip:port; 
	}
    #預(yù)發(fā)2
	upstream new_version {
		server ip:port;
	}
    #預(yù)發(fā)3
	upstream old_version {
		server ip:port;
	}
}

host如下:

127.0.0.1  域名

訪問地址:

域名

菜單運營數(shù)據(jù)---保單數(shù)據(jù),默認走default集群,保單狀態(tài)承保成功走new_version集群,保單狀態(tài)終止走old_version集群

根據(jù)cookie內(nèi)的參數(shù)進行負載


#user  nobody;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;
    #log_format  main '$time_local 客戶端地址:$remote_addr–$remote_port 請求的URI和HTTP協(xié)議:$request 請求地址:$http_host HTTP請求狀態(tài):$status upstream狀態(tài):$upstream_status 負載地址:$upstream_addr url跳轉(zhuǎn)來源:$http_referer $body_bytes_sent $http_user_agent $request_uri';
    log_format  logFormat '$http_cookie $group $time_local 客戶端:$remote_addr–$remote_port 請求的URI和HTTP協(xié)議:$request 請求:$http_host HTTP狀態(tài):$status upstream狀態(tài):$upstream_status 負載:$upstream_addr 
                          url跳轉(zhuǎn):$http_referer $body_bytes_sent $http_user_agent $request_uri 請求參數(shù) $query_string $args $document_root $uri
                          -----$request_uri $request_filename ';
    access_log  logs/access.log  logFormat;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;
    #gzip  on;
    server {
        listen       80;   #監(jiān)聽端口
        server_name  域名; #監(jiān)聽地址 
        access_log  logs/xx.com.access.log  logFormat;
        #方式二、nginx+lua實現(xiàn)灰度
        ## 1、將對localhost訪問由/opt/app/lua/dep.lua進行處理
        ## 2、根據(jù)邏輯處理后,決定回調(diào)如下兩個其中1個內(nèi)部跳轉(zhuǎn)
        #方式三根據(jù)請求參數(shù)值匹配進行路由
        #域名policy/policyInfoList?thirdPolicystatus=2
        set $group "default";
        if ($query_string ~* "thirdPolicystatus=1"){ #動態(tài)控制路由
            set $group new_version;
            }
        if ($query_string ~* "thirdPolicystatus=2"){
            set $group old_version;
            }
        if ($http_cookie ~* "sso.xx.com=BJ.E2C7D319112E7F6252BF010770269E235820211121073248"){
            set $group pro_version;
            }
        if ($http_cookie ~* "sso.xx.com!=BJ.E2C7D319112E7F6252BF010770269E235820211121073248"){
            set $group grey_version;
            }
        location / 
        {
            default_type "text/html"; 
            #content_by_lua_file D:/sortware/openresty/openresty-1.17.8.2-win64/conf/dep.lua; # 指定由lua文件處理http請求
            proxy_pass http://$group;
            proxy_set_header  Host       $host;
            proxy_set_header  X-Real-IP    $remote_addr;
            proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
            index index.html index.htm;
        }
    }
	#標準預(yù)發(fā)環(huán)境
	upstream default {
		server ip:port; 
	}
    #預(yù)發(fā)2
	upstream new_version {
		server ip:port;
	}
    #預(yù)發(fā)3
	upstream old_version {
		server ip:port;
	}
        #預(yù)發(fā)2
	upstream pro_version {
		server ip:port;
	}
    #預(yù)發(fā)3
	upstream grey_version {
		server ip:port;
	}
}

根據(jù)cookie內(nèi)容轉(zhuǎn)發(fā)到不同的集群

四、相關(guān)可操作和替換性

想法一:如果這個時候我門需要一個動態(tài)化配置控制臺則可以通過javaweb等工程進行操作redis實現(xiàn)實時更新redis數(shù)據(jù)從而控制灰度

想法二:切換其他數(shù)據(jù)源比如

1.MySQL/MariaDB: 使用 Lua 的 lua-mysql 或 LuaSQL 庫,您可以在 Lua 中連接和查詢 MySQL 或 MariaDB 數(shù)據(jù)庫。

2.PostgreSQL: 使用 Lua 的 lua-postgres 或 LuaSQL 庫,您可以在 Lua 中連接和查詢 PostgreSQL 數(shù)據(jù)庫。

3.MongoDB: 使用 Lua 的 mongo-lua-driver 庫,您可以在 Lua 中連接和操作 MongoDB 數(shù)據(jù)庫。

4.HTTP API: 使用 Lua 的 LuaHTTP 庫,您可以在 Lua 中發(fā)起 HTTP 請求,并與遠程的 HTTP API 進行通信

5.Cassandra: 使用 Lua 的 lua-cassandra 庫,您可以在 Lua 中連接和查詢 Cassandra 數(shù)據(jù)庫。

想法三:切換其他腳本語言

1.JavaScript: 通過使用 Nginx 的 ngx_http_js_module,您可以在 Nginx 中使用 JavaScript。這可以讓您使用 JavaScript 腳本來實現(xiàn)一些灰度發(fā)布或其他功能。此外,JavaScript 也廣泛用于前端開發(fā),因此可以在前后端一體化的項目中更容易共享代碼邏輯。

2.LuaJIT: LuaJIT 是一個通過即時編譯實現(xiàn)高性能的 Lua 解釋器。它提供了與標準 Lua 解釋器兼容的 API,但是比標準 Lua 解釋器更快。使用 LuaJIT,您可以獲得更高的性能,同時保持與 Lua 的兼容性。

3.Python: 如果您已經(jīng)熟悉 Python,您可以使用 Python-NGINX-Module 在 Nginx 中嵌入 Python。這樣可以使用 Python 編寫 Nginx 的配置文件和處理請求的邏輯。

4.Java: 使用 nginx-jvm-clojure 或 nginx-jwt 等模塊,您可以在 Nginx 中嵌入 Java 或 Clojure。這些模塊提供了在 Nginx 上運行 Java 或 Clojure 代碼的功能,可以與其他 Java 或 Clojure 庫和框架進行集成。

想法四:切換其他web服務(wù)器或反向代理服務(wù)器

1.Apache HTTP Server: Apache 是一個廣泛使用的開源 Web 服務(wù)器和反向代理服務(wù)器,它支持多種模塊和擴展,提供了豐富的功能和配置選項。

2.Microsoft IIS: Internet Information Services (IIS) 是由 Microsoft 開發(fā)的 Web 服務(wù)器,專為 Windows 操作系統(tǒng)設(shè)計。它是 Windows Server 默認的 Web 服務(wù)器,提供了廣泛的功能和集成。

3.Caddy: Caddy 是一個用 Go 編寫的現(xiàn)代化的 Web 服務(wù)器和反向代理服務(wù)器。它具有簡單配置、自動 HTTPS、HTTP/2 支持等特性。

4.HAProxy: HAProxy 是一個高性能的負載均衡器和反向代理服務(wù)器,適用于高流量的 Web 應(yīng)用程序。它具有豐富的負載均衡和代理功能。

5.Envoy: Envoy 是一個輕量級的開源代理服務(wù)器和通信總線,適用于云原生和微服務(wù)架構(gòu)。它具有動態(tài)配置、負載平衡、流量管理等功能。

大家可以根據(jù)自己的想法或者興趣進行研究,本文不做過多介紹

五、其他相關(guān)優(yōu)秀文章傳送門

?一種簡單從端上進行服務(wù)端上線灰度驗證方案?

?功能級灰度開量工具?

?采購域灰度環(huán)境搭建策略?

?基于istio的灰度發(fā)布架構(gòu)方案實踐之路?

?【穩(wěn)定性】履約平臺組上線發(fā)布三板斧(可灰度、可驗證、可回滾)?

?代碼層面的灰度?

?幾年前寫的一個灰度工具(拿來即用)?

?【行云部署】小狗漫畫-指定ip的灰度部署?

審核編輯 黃宇

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • nginx
    +關(guān)注

    關(guān)注

    0

    文章

    151

    瀏覽量

    12189
  • Lua
    Lua
    +關(guān)注

    關(guān)注

    0

    文章

    81

    瀏覽量

    10570
  • Redis
    +關(guān)注

    關(guān)注

    0

    文章

    376

    瀏覽量

    10888
收藏 人收藏

    評論

    相關(guān)推薦

    華為云 Flexus X 輕松實現(xiàn) Redis 一主多從高效部署

    ,F(xiàn)lexus?X 預(yù)裝 Redis 加速鏡像,簡化了 Redis 的安裝和配置流程,降低了技術(shù)門檻,使開發(fā)者能夠更專注于業(yè)務(wù)邏輯的實現(xiàn)。 ????????本文將詳細介紹如何在華為云 Flexus?X 上
    的頭像 發(fā)表于 12-27 13:45 ?190次閱讀
    華為云 Flexus X 輕松<b class='flag-5'>實現(xiàn)</b> <b class='flag-5'>Redis</b> 一主多從高效部署

    Redis緩存與Memcached的比較

    Redis和Memcached都是廣泛使用的內(nèi)存數(shù)據(jù)存儲系統(tǒng),它們主要用于提高應(yīng)用程序的性能,通過減少對數(shù)據(jù)庫的直接訪問來加速數(shù)據(jù)檢索。以下是對Redis和Memcached的比較,涵蓋了它們的一些
    的頭像 發(fā)表于 12-18 09:33 ?168次閱讀

    Nginx日常運維方法Linux版

    1,安裝? 下載RPM:wget http://nginx.org/packages/centos/7/x86_64/RPMS/nginx
    的頭像 發(fā)表于 12-06 16:38 ?173次閱讀
    <b class='flag-5'>Nginx</b>日常運維方法Linux版

    詳解nginx中的正則表達式

    前言,我這里驗證的nginx-v1.23.2單機環(huán)境下的nginx中的正則表達式、location路徑匹配規(guī)則和優(yōu)先級。
    的頭像 發(fā)表于 12-03 09:59 ?219次閱讀
    詳解<b class='flag-5'>nginx</b>中的正則表達式

    確保網(wǎng)站無縫運行:Keepalived高可用與Nginx集成實戰(zhàn)

    目錄 keepalived高可用(nginx) keepalived簡介 keepalived的重要功能 keepalived高可用架構(gòu)圖 keepalived工作原理描述 keepalived實現(xiàn)
    的頭像 發(fā)表于 11-27 09:08 ?522次閱讀
    確保網(wǎng)站無縫運行:Keepalived高可用與<b class='flag-5'>Nginx</b>集成實戰(zhàn)

    nginx隱藏版本號與WEB服務(wù)器信息

    nginx不僅可以隱藏版本信息,還支持自定義web服務(wù)器信息 先看看最終的隱藏結(jié)果吧 具體怎么實現(xiàn)呢,其實也很簡單,請往下看 1 官網(wǎng)下載最新穩(wěn)定版 wget http://nginx
    的頭像 發(fā)表于 11-22 10:25 ?185次閱讀
    <b class='flag-5'>nginx</b>隱藏版本號與WEB服務(wù)器信息

    全志亮相灰度科技2024年新品發(fā)布

    近日,國內(nèi)商顯方案廠商灰度科技在深圳召開主題為【智啟·賦能】的2024年新品發(fā)布會,全志科技作為新品方案的主控芯片提供商受邀參會。會上,全志科技IEBU副總經(jīng)理皮杰勇進行了主題為《全志芯片在商顯行業(yè)的技術(shù)和產(chǎn)品應(yīng)用》的分享。
    的頭像 發(fā)表于 11-14 15:14 ?623次閱讀

    nginx負載均衡配置介紹

    目錄 nginx負載均衡 nginx負載均衡介紹 反向代理與負載均衡 nginx負載均衡配置 Keepalived高可用nginx負載均衡器 修改Web服務(wù)器的默認主頁 開啟
    的頭像 發(fā)表于 11-10 13:39 ?267次閱讀
    <b class='flag-5'>nginx</b>負載均衡配置介紹

    Lua語法基礎(chǔ)教程(上篇)

    今天我們來學習Lua語法基礎(chǔ)教程。由于篇幅過長,將分為上中下三篇進行講解,本篇為上篇。 一、初識Lua Lua 是一種輕量小巧的腳本語言,它用標準C語言編寫并以源代碼形式開放。這意味著什么呢?這
    的頭像 發(fā)表于 10-24 07:17 ?233次閱讀

    nginx重啟命令linux步驟是什么?

    ./nginx -s reload 即可   方法二:查找當前nginx進程號,然后輸入命令:kill -HUP 進程號 實現(xiàn)重啟nginx服務(wù)   
    發(fā)表于 07-11 17:13

    nginx重啟命令linux步驟是什么?

    ./nginx -s reload 即可   方法二:查找當前nginx進程號,然后輸入命令:kill -HUP 進程號 實現(xiàn)重啟nginx服務(wù)   
    發(fā)表于 07-10 16:40

    Redis開源版與Redis企業(yè)版,怎么選用?

    點擊“藍字”關(guān)注我們數(shù)以千計的企業(yè)和數(shù)以百萬計的開發(fā)人員Redis開源版來構(gòu)建應(yīng)用程序。但隨著用戶數(shù)量、數(shù)據(jù)量和地區(qū)性的增加,成本、可擴展性、運營和可用性等問題也隨之而來。Redis企業(yè)版
    的頭像 發(fā)表于 04-04 08:04 ?1107次閱讀
    <b class='flag-5'>Redis</b>開源版與<b class='flag-5'>Redis</b>企業(yè)版,怎么選用?

    新版 Redis 不再“開源”,對使用者都有哪些影響?

    2024 年 3 月 20 日,Redis Labs 宣布從 Redis 7.4 開始,將原先比較寬松的 BSD 源碼使用協(xié)議修改為 RSAv2和 SSPLv1協(xié)議。該變化意味著 Redis
    的頭像 發(fā)表于 03-27 22:30 ?513次閱讀
    新版 <b class='flag-5'>Redis</b> 不再“開源”,對使用者都有哪些影響?

    Redis實現(xiàn)分布式多規(guī)則限流的方式介紹

    市面上很多介紹 Redis 如何實現(xiàn)限流的,但是大部分都有一個缺點,就是只能實現(xiàn)單一的限流,比如 1 分鐘訪問 1 次或者 60 分鐘訪問 10 次這種,但是如果想一個接口兩種規(guī)則都需要滿足呢,我們的項目又是分布式項目,應(yīng)該如何
    的頭像 發(fā)表于 02-26 10:07 ?517次閱讀
    <b class='flag-5'>Redis</b><b class='flag-5'>實現(xiàn)</b>分布式多規(guī)則限流的方式介紹

    Redis可以實現(xiàn)消息中間件MQ的功能

    是一種通信模式:發(fā)送者(PUBLISH)發(fā)送消息,訂閱者(SUBSCRIBE)接收消息,可以實現(xiàn)進程間的消息傳遞   Redis可以實現(xiàn)消息中間件MQ的功能,通過發(fā)布訂閱
    的頭像 發(fā)表于 01-25 14:48 ?963次閱讀
    <b class='flag-5'>Redis</b>可以<b class='flag-5'>實現(xiàn)</b>消息中間件MQ的功能
    主站蜘蛛池模板: 校园纯肉H教室第一次| 人妻无码AV中文系统久久免费| 99视频精品国产免费观看| 一本道mw高清码二区三区| 性xxx免费| 校园纯肉H教室第一次| 午夜日本大胆裸艺术| 我与恶魔的h生活ova| 午夜AV国产欧美亚洲高清在线| 天天操天天干天天爽| 五月丁香啪啪.| 亚洲va久久久久| 亚洲免费观看| 一个人看的www视频动漫版| 伊人伊人影院| 中文字幕在线观看网站| 97公开超碰在线视频| se01国产短视频在线观看| poronovideos动物狗猪| 波多野结衣 熟女| 国产成人精品综合在线观看| 国产精品美女久久久网站动漫| 国产麻豆精品传媒AV国产在线| 国产午夜精品AV一区二区麻豆| 狠狠色狠色综合曰曰| 久久精品国产首叶| 蜜臀AV色欲A片无码一区| 欧美 日韩 亚洲 在线| 日本不卡免免费观看| 无码免费视频AAAAAA片草莓| 亚洲精品色情APP在线下载观看| 夜色资源站国产www在线视频| 中文字幕无码乱人伦蜜桃| 99热在线精品视频| 国产AV精品一区二区三区漫画| 国产午夜亚洲精品理论片八戒| 经典WC女厕所里TV| 免费国产成人高清在线看软件| 秋霞影院福利电影| 小寡妇水真多好紧| 在线成年av动漫电影|