天天看點

nginx+lua 限制接口通路次數

最近看了一些nginx+lua 的東西,嘗試實作了一下限流腳本,隻包含最根本的功能。

代碼如下

access_nginx_check.lua

-- 一個按照 url + 參數 進行 在固定時間内通路次數次數限制的lua 腳本,
--  此處僅僅實作 按照url 10s 内限制 2次通路,記錄每次通路次數(無用僅僅用于核對代碼邏輯可去除),擷取參數函數已有,後續需要完善

--package.path = package.path ..';..\\?.lua';
--dofile ("./log.lua")
--是否開啟檢測
local check = "on"    
--限制最大通路量
local count = 2
--限制時間範圍
local seconds = 10
--擷取參數的值 
function getParam()
	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
	return args
end
--寫入日志
function writerLog(str)
	local  time = os.time()
	local  date = os.date("%Y%m%d",time)

	local file = io.open("/var/www/lua/logTest/"..tostring(date).."_log.log","a")
	--ngx.say("/var/www/lua/log/"..tostring(date).."_log.log")
	--assert(file)
	file:write(str.."\n")
	file:close();

end
--對uri 進行限制主要邏輯
function access_user_uri_check()
	-- body
	if check=="on" then
		local access_uri = ngx.var.host..ngx.var.uri
		--local param = getParam()
		local key = access_uri
--提前在nginx中聲明的變量
		local limit = ngx.shared.limit
		local req 
		if limit then
			req ,_= limit:get(key)
		end
		if req then
			if req>=count then
--超過限制之後傳回錯誤
				ngx.say("您在最近:"..seconds.."秒,通路:"..access_uri.."次數超過:"..count.."次,已經觸發保護機制,請稍後通路")
				ngx.exit(403)
			end
--對key對應的資料進行累加
			limit:incr(key,1)
			
		else
--沒有值設定初始為1
			limit:set(key,1,seconds)
		end
--記錄log
		writerLog(key..":"..limit:get(key))

	end

end
--錯誤調試函數
function myerrorhandler( err )
   ngx.say( "ERROR:", err )
end
--測試代碼,可以自動執行
status = xpcall( access_user_uri_check, myerrorhandler )
--access_user_uri_check()
           

對應nginx 配置

#聲明變量 對應lua 腳本中 的ngx.shared.limit
lua_shared_dict limit 10m;
server{
    listen 80;
    server_name localhost.accesslua.com;
    root /var/www/html/test;
    charset utf-8;
    location ~\.php{
#為了調試lua腳本,直接将資訊抛出到浏覽器,否則會自動下載下傳
        default_type 'text/html';
#嵌入的lua腳本
        access_by_lua_file "/var/www/lua/access_nginx_check.lua";
#php 的正常調用
        fastcgi_pass 192.168.33.11:9000;
        fastcgi_index index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include        fastcgi_params;
    }
#記錄log
    access_log  /usr/local/var/log/lua.accesslua-php5.access.log  main;

}
           

示範效果

nginx+lua 限制接口通路次數

繼續閱讀