中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么用lua語言開發一個kong插件

發布時間:2021-06-18 16:01:07 來源:億速云 閱讀:552 作者:chen 欄目:編程語言

這篇文章主要講解了“怎么用lua語言開發一個kong插件”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“怎么用lua語言開發一個kong插件”吧!

需求:
 插件1: 把一個請求的 header、request、response 這些數據傳輸到后臺,通過http接口、或者mq。
 插件2: 根據 header 以及 request的信息,判斷用戶的權限,無權訪問或者訪問被限制,則直接網關層攔截返回response,不去調用后端服務。
lua版本:5.1
kong的版本:2.1.4
kong的架構圖:
怎么用lua語言開發一個kong插件
    從Kong的架構圖中,可以看到Nginx和OpenResty的存在。OpenResty是以 Nginx 為核心的 Web 開發平臺,內部包含lua-nginx-module,集成了大量精良的 Lua 庫,開發人員可以使用 Lua 腳本調動各類C和Lua 模塊。OpenResty目標是讓Web服務直接跑在 Nginx 服務內部,利用 Nginx 的非阻塞I/O模型實現高性能響應。而Kong 是OpenResty的一個應用程序。
kong的插件開發基礎知識
 從基礎知識可以看出,我們的要開發插件主要是重寫kong提供的一些基礎方法,這些基礎方法對應了網絡請求的生命周期的不同階段,實際上對應了OpenResty 的不同執行階段。所以在不同的生命周期,我們能拿到的數據是不同的,在不同的生命周期,有些函數和方法是不能使用的。
 如下報錯表示你的API放錯了生命周期:

function cannot be called in access phase (only in: header_filter, body_filter, log)

比如:Handler:access(請求被代理到上游服務之前執行)階段調用獲取response的信息 kong.response.get_header()

API disabled in the context of log_by_lua*

比如:你在生命周期里直接調用http.new()去創建網絡請求。在NGINX的執行階段使用某些函數,會影響客戶端的響應時長。
 所以可以通過一個非常強大的方法 ngx.timer.at 在請求的生命周期中處理一些高延遲的業務邏輯。定時調用是在后臺運行,并且他們的執行不會增加任何客戶端的響應時長。

local timer_at = ngx.timer.at
local ok, err = timer_at(0, send_payload, conf, cjson.encode(json_str))
if not ok then
    kong.log.err("failed to create timer: ", err)
end
---timer_at(0, send_payload, conf, cjson.encode(json_str)) 0表示零延遲,send_payload表示要調用的方法,后面的參數表示send_payload該方法需要的入參。

以上解決了一些插件編寫的基本規則層面的問題。

那么生命周期的不同階段如何共享數據呢?

比如:在 handler:log()階段獲取請求的reponse結果,在該階段可以獲取到

json_str['header'] = cjson_encode(kong.request.get_headers())
 json_str['request'] = cjson_encode(basic_serializer.serialize(ngx))
但是response是不能直接過去到的。所以我們可以在body_filter階段獲取到response 然后通過kong.ctx.shared or kong.ctx.plugin

kong.ctx.shared

一個 table 結構的數據,它用于在給定請求的多個插件之間共享數據,由于它只與請求的上下文相關,所有無法從 Lua 模塊的頂級塊訪問此表,只能在請求段中訪問,對應插件的 rewriteaccessheader_filterbody_filterlog 接口
所有插件都可以看到單個插件在此 table 中插入的值命名時必須謹慎,因為命名沖突會導致數據被覆蓋。

kong.ctx.plugin

一個 table 結構的數據,與 kong.ctx.shared 不同,此 table 不在插件之間共享,相反,它僅對當前插件實例可見,也就是說,如果配置了多個限流插件實例(在不同的服務上),每個實例對于每個請求都有自己的 table
由于它自帶命名空間,所以它比 kong.ctx.shared 更安全,因為它避免了潛在的命名沖突,這可能導致多個插件在不知不覺中覆蓋了彼此的數據

擴展部分:

在開發過程中,如果你像我一樣不太了解OpenResty的運行原理,那么可能會產生這樣的疑問:
 在高并發的情況下,會出現類似多線程的問題嗎?不同的請求在同一個插件下數據獲取會出錯嗎?
 解釋:
   Nginx采用多進程模型,單Master進程—多Worker進程(一般跟CPU的核數相同)由Master處理外部信號、配置文件的讀取及Worker的初始化,Worker進程采用單線程、非阻塞的事件模型(Event Loop,事件循環)來實現端口的監聽及客戶端請求的處理和響應,同時Worker還要處理來自Master的信號。由于Worker使用單線程處理各種事件,所以一定要保證主循環是非阻塞的,否則會大大降低Worker的響應能力。
每個請求都有一個協程進行處理。

協程類似一種多線程,與多線程的區別有:

  1. 協程并非os線程,所以創建、切換開銷比線程相對要小。

  2. 協程與線程一樣有自己的棧、局部變量等,但是協程的棧是在用戶進程空間模擬的,所以創建、切換開銷很小。

  3. 多線程程序是多個線程并發執行,也就是說在一瞬間有多個控制流在執行。而協程強調的是一種多個協程間協作的關系,只有當一個協程主動放棄執行權,另一個協程才能獲得執行權,所以在某一瞬間,多個協程間只有一個在運行。

  4. 由于多個協程時只有一個在運行,所以對于臨界區的訪問不需要加鎖,而多線程的情況則必須加鎖。

  5. 多線程程序由于有多個控制流,所以程序的行為不可控,而多個協程的執行是由開發者定義的所以是可控的。
    Nginx的每個Worker進程都是在epoll或kqueue這樣的事件模型之上,封裝成協程,每個請求都有一個協程進行處理。這正好與Lua內建協程的模型是一致的,所以即使ngx_lua需要執行Lua,相對C有一定的開銷,但依然能保證高并發能力。

openresty/lua-nginx-module(官方介紹)
Kong的日志記錄(log)自定義插件
Kong插件開發工具包
OpenResty原理和緩存的實現
nginx+lua的基本原理概念介紹


 

感謝各位的閱讀,以上就是“怎么用lua語言開發一個kong插件”的內容了,經過本文的學習后,相信大家對怎么用lua語言開發一個kong插件這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

lua
AI

桂东县| 蓬莱市| 成都市| 喀喇沁旗| 夏津县| 洪湖市| 福清市| 东兴市| 洪江市| 沂南县| 云阳县| 焦作市| 华容县| 库尔勒市| 黄龙县| 邳州市| 江阴市| 九龙城区| 舒城县| 新化县| 福鼎市| 南乐县| 彭水| 陈巴尔虎旗| 仁寿县| 特克斯县| 芒康县| 仁怀市| 北川| 四川省| 和龙市| 高密市| 乐清市| 兴和县| 望都县| 申扎县| 长汀县| 页游| 惠安县| 正安县| 丰县|