apisix源碼下載, 並打開
克隆到自己項目文件夾下
git clone https://github.com/apache/apisix.git
git clone git@github.com:apache/apisix.git
源碼找到echo, example-plugin兩個插件進行參考
- 參考echo, example-plugin插件
- 復制example-plugin插件, 起一個名字, plugin-test
- 清除多余的內容
local ngx = ngx
local core = require("apisix.core")
local plugin = require("apisix.plugin")
local upstream = require("apisix.upstream")
local schema = {
type = "object",
}
local plugin_name = "plugin-test"
local _M = {
version = 0.1,
priority = 11111,
name = plugin_name,
schema = schema,
}
function _M.check_schema(conf, schema_type)
return core.schema.check(schema, conf)
end
function _M.init()
end
function _M.destroy()
end
function _M.rewrite(conf, ctx)
end
function _M.access(conf, ctx)
end
function _M.log(conf, ctx)
end
return _M
開始開發
這里先介紹使用apisix默認使用的lua語言進行開發
后續會提供其他語言的插件開發
了解插件的執行階段
確認好需求, 根據需求, 確認需要在插件的哪個階段進行開發
- rewrite
- 可以拿到請求url, 請求頭, 請求體
- 可以修改響應狀態碼, 響應體
- access
- 同rewrite
- header_filter
- 不可以獲得響應體
- 不可以修改響應體
- 可以獲得、修改(響應頭、響應狀態碼)
- body_filter
- 可以獲得響應體
- 可以修改響應體
- 可以獲得響應頭、響應狀態碼
- 不可以修改響應頭、響應狀態碼
參考文章
apisix插件開發
https://apisix.apache.org/zh/docs/apisix/plugin-develop
https://apisix.apache.org/zh/blog/2022/02/16/file-logger-api-gateway/
lua語言語法
https://www.runoob.com/lua/lua-tutorial.html
注意
開發插件目錄, /apisix/apisix/plugins/
如果只開發一個lua文件, 則直接放在此目錄即可
如果有文件夾的添加, 需要修改 Makefile 文件, 編譯一下
參考: https://apisix.apache.org/zh/docs/apisix/plugin-develop/#插件命名,優先級和其他
實戰
我想在把所有的請求添加一個請求頭plugin-header, 值為hello
第一步, 修改基本屬性
修改插件基本屬性, 名稱, 版本, 優先級(數字越高越先執行)
local schema = {
type = "object",
}
local plugin_name = "plugin-test"
local _M = {
version = 0.1,
priority = 11111,
name = plugin_name,
schema = schema,
}
第二步, 開發
添加請求頭, 可以在rewrite階段就可以完成, 所以代碼如下
log階段打印所有的請求頭
function _M.rewrite(conf, ctx)
core.request.set_header(ctx, "plugin-header", "hello")
end
function _M.log(conf, ctx)
local headers = ngx.req.get_headers()
core.log.warn("headers: ", core.json.encode(headers))
end
第三步, 放入插件
注意: 我這里是docker啟動, 所以需要先啟動docker, 然后再放入插件, 修改配置, 然后重啟
對於直接部署在機器上的apisix, 可以放入插件, 修改配置, 然后再啟動
本地docker啟動apisix, 參考: https://www.cnblogs.com/loseself/p/16147243.html
# 放入插件
# 獲取docker 容器id
docker ps -a
# 移動插件
docker cp 根目錄/apisix/apisix/plugins/plugin-test.lua 容器id:/usr/local/apisix/apisix/plugins
第四步, 修改apisix配置並重新啟動
# 有docker的進入docker
vi /usr/local/apisix/conf/config-default.yaml
# 搜索 plugins, 填入插件
- plugin-test
# 重新啟動
apisix restart
# 或者使用docker重新啟動即可
第五步, 綁定路由測試
這里使用apisix的docker提供的web1上游
# 記得替換自己的機器ip
IP=xxx
# 訪問原有的web1服務
curl -i -X GET http://$IP:9081/hello
# 綁定路由
curl http://$IP:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
"plugins": {
"plugin-test": {
}
},
"upstream": {
"nodes": {
"192.168.63.49:9081": 1
},
"type": "roundrobin"
},
"uri": "/hello"
}'
# 訪問代理后的web1
curl -i -X GET http://$IP:9080/hello
# 查看apisix日志
cd /usr/local/apisix/logs && tail -f error.log
變量介紹
ctx(類似於netty的ChannelHandlerContext ctx)
這個 Lua 表可以用來存儲基於請求的 Lua 環境數據,其生存周期與當前請求相同 (類似 Nginx 變量)。
方法介紹
請注意方法的使用階段
獲取所有的請求頭, table數據類型
local headers = ngx.req.get_headers()
添加請求頭
core.request.set_header(ctx, "key", "value")
獲取單獨請求頭
local time = core.request.header(ctx, key)
獲取請求體
core.request.get_body()
獲取響應頭
local value = ngx.header[key]
添加響應頭
ngx.header[key] = value
獲取響應體
local body = ngx.arg[1]