Apache APISIX 是 Apache 软件基金会下的顶级项目。它是一个具有动态、实时、高性能等特点的云原生 API 网关。它构建于 NGINX + ngx_lua 的技术基础之上,充分利用了 LuaJIT 所提供的强大性能。
APISIX 主要分为两个部分:
APISIX 核心:包括 Lua 插件、多语言插件运行时(Plugin Runner)、Wasm 插件运行时等;
功能丰富的各种内置插件:包括可观测性、安全、流量控制等。
APISIX 在其核心中,提供了路由匹配、负载均衡、服务发现、API 管理等重要功能,以及配置管理等基础性模块。除此之外,APISIX 插件运行时也包含其中,提供原生 Lua 插件的运行框架和多语言插件的运行框架,以及实验性的 Wasm 插件运行时等。APISIX 多语言插件运行时提供多种开发语言的支持,比如 Golang、Java、Python、JS 等。
APISIX 目前也内置了各类插件,覆盖了 API 网关的各种领域,如认证鉴权、安全、可观测性、流量管理、多协议接入等。当前 APISIX 内置的插件使用原生 Lua 实现
此次使用golang开发一个ApiSix的插件。
一、git clone apisix golang 运行环境SDK
git clone https://github.com/apache/apisix-go-plugin-runner.git
插件目录位于:cmd/go-runner/plugins 文件夹中,直接在此文件夹中创建插件文件即可;
plugins目录中有示例插件代码,可以全部删除;
二、开发流程
1、定义一个结构体,包含 plugin.DefaultPlugin,并实现plugin.Plugin接口,如:
// 定义一个包含DefaultPlugin的结构体 type MyResponseRewrite struct { plugin.DefaultPlugin } // 实现Plugin接口的Name func (m *MyResponseRewrite) Name() string { return "my-response-rewrite" } // 实现Plugin接口的ParseConf func (m *MyResponseRewrite) ParseConf(in []byte) (interface{}, error) { conf := MyRewriteResponseConf{} err := json.Unmarshal(in, &conf) return conf, err }
2、注册插件
通过init方法注册插件
func init() { err := plugin.RegisterPlugin(&MyResponseRewrite{}) if err != nil { log.Fatalf("failed to register plugin my-response-rewrite: %s", err) } }
3、根据业务需求重写 plugin.DefaultPlugin的方法;DefaultPlugin 只有两个方法:
// 请求时处理,Request是请求参数,只读;ResponseWriter是响应参数,读写, conf 是自定义的插件配置 func (*DefaultPlugin) RequestFilter(conf interface{},w http.ResponseWriter,r pkgHTTP.Request) {} // 响应时处理,响应时只有Response和conf func (*DefaultPlugin) ResponseFilter(conf interface{},w pkgHTTP.Response) {}
4、make build 的方式生成插件
在根目录执行make build生成插件;
windows如未安装 make 工具链,可下载 minGW 安装,minGW安装后加入到环境变量,minGW安装的 make 工具被命名为:mingw-make.exe ,可复制后修改为make.exe ;
注:最好是在liunx环境中编译,windows系统可以 wls 中进行编译;
5、把生成的 go-runner 插件保存到apisix运行的服务器,且 apisix对插件必须具有访问执行权限;
比如:把go-runner 复制到 apisix服务器的 /usr/local/apisix-go-plugin-runner/ 目录
如果是docker运行的apisix可以把插件目录映射到宿主机;
6、配置apisix_conf/config.yaml文件
设置环境变量
SET APISIX_LISTEN_ADDRESS=unix:/tmp/runner.sock SET APISIX_CONF_EXPIRE_TIME=3600
添加ext-plugin
ext-plugin: # path_for_test: /tmp/runner.sock ## 没有设置APISIX_LISTEN_ADDRESS环境变量的情况下,生产环境官方建议设置APISIX_LISTEN_ADDRESS变量 cmd: ["/path/to/apisix-go-plugin-runner/go-runner", "run"] ## /path/to/apisix-go-plugin-runner/go-runner 为插件的路径
重启APISIX,检查插件是否随APISIX启动:
ps -elf | grep apisix 4 S root 1 0 0 80 0 - 90038 sigsus 08:38 ? 00:00:00 nginx: master process /usr/local/openresty/bin/openresty -p /usr/local/apisix -g daemon off; 0 S root 107 57 0 80 0 - 78161 futex_ 08:38 ? 00:00:00 /usr/local/apisix-go-plugin-runner/go-runner run 0 S root 129 115 0 80 0 - 2275 pipe_w 08:50 pts/0 00:00:00 grep apisix ## 如果有显示插件的进程即已启动,如果没有可以手动启动插件
7、配置插件
插件注册及启动后,只是在后台运行,要使用插件还需要在APISIX路由中配置插件(在服务中配置插件无效,不知道是不是我配置的问题)
配置go-runner插件需要使用到 ext-plugin-* 插件中的一个指定外部插件的运行时
ext-plugin-pre-req
ext-plugin-pre-req 插件用于在执行内置 Lua 插件之前和在 Plugin Runner 内运行特定的 External Plugin。
ext-plugin-post-req
ext-plugin-post-req 插件的功能与 ext-plugin-pre-req 插件的不同之处在于:ext-plugin-post-req 插件是在内置 Lua 插件执行之后且在请求到达上游之前工作。
ext-plugin-post-resp
ext-plugin-post-resp 插件用于在执行内置 Lua 插件之前和在 Plugin Runner 内运行特定的 External Plugin。
ext-plugin-post-resp 插件将在请求获取到上游的响应之后执行。
启用本插件之后,APISIX 将使用 lua-resty-http 库向上游发起请求,这会导致:
proxy-control 插件不可用
proxy-mirror 插件不可用
proxy-cache 插件不可用
APISIX 与上游间的双向认证 功能尚不可用
如配置在ext-plugin-post-resp 运行:
{ "uri": "/api/*", "name": "api", "methods": [ "GET", "POST" ], "plugins": { "ext-plugin-post-resp": { "_meta": { "disable": false }, "conf": [ { "name": "my-response-rewrite", "value": "{\"tag\":\"hello my-rewrite-response\"}" } ] } } }
注意ext-plugin-*插件默认不在APISIX Dashboard上显示,需要到dashboard_conf/conf.yaml配置文件中添加,后更新schema.json;
注:更新 schema.json,在apisix服务器上(如果是部署在docker,需要在容器中执行)执行:
curl 127.0.0.1:9092/v1/schema > schema.json ## 9092端口是 control_api 的默认端口,有时这个端口会被修改,可能查看apisix_conf/conf.yaml 中的control设置的是什么端口 ## docker 把 schema.json 导出到宿主机: docker cp 容器名称:schema.json schema.json ## 把schema.json导入到apisix-dashboard 的conf目录:/usr/local/apisix-dashboard/conf docker cp scheam.json 容器名称:/usr/local/apisix-dashboard/conf