前言:
熟悉 Apache APISIX
的小伙伴都知道,之前在社區中我們已經支持了 Java 和 Go 語言的 Runner
,今天 Apache APISIX Python Runner
也來了,社區中的小伙伴們在開發 Apache APISIX
插件時又多了一種新選擇。
Python
語言作為一個解釋型的高級編程語言,它語法簡潔易上手、代碼可讀性好 ,在跨平臺 、可移植性 、開發效率上都有很好的表現,同時作為一個高級編程語言它的封裝抽象程度比較高屏蔽了很多底層細節(例如:GC )讓我們在開發的過程中可以更專注應用邏輯的開發。
同時作為一個有 30 年歷史的老牌開發語言,它的生態以及各種模塊已經非常完善,我們大部分的開發和應用場景都可以從社區中找到很成熟的模塊或解決方案。
Python
其他的優點就不再一一贅述,當然它的缺點也比較明顯:Python 作為一門解釋性語言,相較于 C++ 和 Go 這樣的編譯型語言,在性能上的差距還是比較大的。
一、了解:項目架構
apache-apisix-python-runner
這個項目可以理解為 Apache APISIX
和 Python
之間的一道橋梁,通過 Python Runner
可以把 Python
直接應用到 Apache APISIX
的插件開發中,最重要的還是希望讓更多對 Apache APISIX
和 API 網關感興趣的 Python 開發者通過這個項目,更多地了解和使用 Apache APISIX
,以下為 Apache APISIX
多語言支持的架構圖。
上圖左邊是 Apache APISIX
的工作流程,右邊的 Plugin Runner
是各語言的插件運行器,本文介紹的 apisix-python-plugin-runner
就是支持 Python
語言的 Plugin Runner
。
在 Apache APISIX
中配置一個 Plugin Runner
時,Apache APISIX 會啟動一個子進程運行 Plugin Runner
,該子進程與 Apache APISIX
進程屬于同一個用戶,當我們重啟或重新加載 Apache APISIX
時,Plugin Runner
也將被重啟。
如果你為一個給定的路由配置了 ext-plugin-*
插件,請求命中該路由時將觸發 Apache APISIX
通過 Unix Socket
向 Plugin Runner
發起 RPC 調用。調用分為兩個階段:
-
ext-plugin-pre-req :在執行
Apache APISIX
內置插件(Lua 語言插件)之前 -
ext-plugin-post-req :在執行
Apache APISIX
內置插件(Lua 語言插件)之后
大家可以根據需要選擇并配置 Plugin Runner
的執行時機。Plugin Runner
會處理 RPC 調用,在其內部創建一個模擬請求,然后運行多語言編寫的插件,并將結果返回給 Apache APISIX
。
多語言插件的執行順序是在 ext-plugin-*
插件配置項中定義的,像其他插件一樣,它們可以被啟用并在運行中重新定義。
二、安裝:部署測試
基礎運行環境:Apache APISIX 2.7、Python 3.6+
Apache APISIX 的安裝部署可參考 Apache APISIX 官方文檔:如何構建 Apache APISIX (https://github.com/apache/api...)進行部署。
1. 下載安裝 Python Runner
1
2
3
|
$ git clone https://github.com/apache/apisix-python-plugin-runner.git $ cd apisix-python-plugin-runner $ make install |
2. 配置 Python Runner
- 開發模式配置
運行 Python Runner:
1
2
3
4
5
6
7
8
9
10
11
|
$ cd / path / to / apisix - python - plugin - runner $ APISIX_LISTEN_ADDRESS = unix: / tmp / runner.sock python3 apisix / main.py start 修改 Apache APISIX 配置文件 $ vim / path / to / apisix / conf / config.yaml apisix: admin_key: - name: "admin" key: edd1c9f034335f136f87ad84b625c8f1 role: admin ext - plugin: path_for_test: / tmp / runner.sock |
- 生產模式配置
修改 Apache APISIX 配置文件
1
2
3
4
5
6
7
8
|
$ vim / path / to / apisix / conf / config.yaml apisix: admin_key: - name: "admin" key: edd1c9f034335f136f87ad84b625c8f1 role: admin ext - plugin: cmd: [ "python3" , "/path/to/apisix-python-plugin-runner/apisix/main.py" , "start" ] |
- Python Runner 配置(可選)
如果需要對 Log Level
或 Unix Domain Socket
環境變量調整可以修改 Runner
的配置文件
1
2
3
4
5
6
|
$ vim / path / to / apisix - python - plugin - runner / apisix / config.yaml socket: file : $env.APISIX_LISTEN_ADDRESS # Environment variable or absolute path logging: level: debug # error warn info debug |
3. 啟動 Python Runner
1
2
3
|
$ cd / path / to / apisix # Start or Restart $ . / bin / apisix [ start | restart ] |
啟動或重啟 Apache APISIX
即可,此時 Apache APISIX
和 Python Runner
已經完成配置并啟動。
4. 測試 Python Runner
配置 Apache APISIX 路由及插件信息:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
# 使用默認demo插件進行測試 $ curl http: / / 127.0 . 0.1 : 9080 / apisix / admin / routes / 1 - H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' - X PUT - d ' { "uri" : "/get" , "plugins" : { "ext-plugin-pre-req" : { "conf" : [ { "name" : "stop" , "value" : "{\"body\":\"hello\"}" } ] } }, "upstream" : { "type" : "roundrobin" , "nodes" : { "127.0.0.1:1980" : 1 } } }' |
-
plugins.ext-plugin-pre-req.conf
為Runner
插件配置,conf
為數組格式可以同時設置多個插件。 -
插件配置對象中
name
為插件名稱,該名稱需要與插件代碼文件和對象名稱一致。 -
插件配置對象中
value
為插件配置,可以為JSON
字符串。
訪問驗證:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
$ curl http: / / 127.0 . 0.1 : 9080 / get - i HTTP / 1.1 200 OK Date: Fri, 13 Aug 2021 13 : 39 : 18 GMT Content - Type : text / plain; charset = utf - 8 Transfer - Encoding: chunked Connection: keep - alive host: 127.0 . 0.1 : 9080 accept: * / * user - agent: curl / 7.64 . 1 X - Resp - A6 - Runner: Python Server: APISIX / 2.7 Hello, Python Runner of APISIX |
三、實踐:插件開發
1. 插件目錄
1
|
/ path / to / apisix - python - plugin - runner / apisix / plugins |
此目錄中的 .py 文件將會被自動加載。
2. 插件示例
1
2
|
/ path / to / apisix - python - plugin - runner / apisix / plugins / stop.py / path / to / apisix - python - plugin - runner / apisix / plugins / rewrite.py |
3. 插件格式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
from apisix.runner.plugin.base import Base from apisix.runner.http.request import Request from apisix.runner.http.response import Response class Stop(Base): def __init__( self ): """ Example of `stop` type plugin, features: This type of plugin can customize response `body`, `header`, `http_code` This type of plugin will interrupt the request """ super (Stop, self ).__init__( self .__class__.__name__) def filter ( self , request: Request, response: Response): """ The plugin executes the main function :param request: request parameters and information :param response: response parameters and information :return: """ # 在插件中可以通過 `self.config` 獲取配置信息,如果插件配置為JSON將自動轉換為字典結構 # print(self.config) # 設置響應頭信息 headers = request.headers headers[ "X-Resp-A6-Runner" ] = "Python" response.headers = headers # 設置響應體信息 response.body = "Hello, Python Runner of APISIX" # 設置響應狀態碼 response.status_code = 201 # 通過調用 `self.stop()` 中斷請求流程,此時將立即響應請求給客戶端 # 如果未顯示調用 `self.stop()` 或 顯示調用 `self.rewrite()`將繼續將請求 # 默認為 `self.rewrite()` self .stop() |
4. 插件規范及注意事項
-
實現插件對象必須繼承
Base
類 - 插件必須實現 filter 函數
-
filter
函數參數只能包含Request
和Response
類對象作為參數 -
Request
對象參數可以獲取請求信息 -
Response
對象參數可以設置響應信息 -
self.config
可以獲取插件配置信息 -
filter
函數中調用self.stop()
時將馬上中斷請求,響應數據。 -
filter
函數中調用self.rewrite()
時,將會繼續請求。
到此這篇關于Python 帶你快速上手 Apache APISIX 插件開發的文章就介紹到這了,更多相關Python Apache APISIX 插件開發內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!
原文鏈接:https://segmentfault.com/a/1190000040697299