为什么是 Go
Apache APISIX 容许用户通过插件的形式来拓展性能,如鉴权、限流、申请改写等外围性能都是通过插件的形式实现的。尽管 Apache APISIX 外围代码是应用 Lua 编写的,然而 Apache APISIX 反对多语言开发插件,比方 Go、Java。
这篇文章将具体解说如何用 Go 来开发 Apache APISIX 插件。通过拥抱 Go 的生态圈,为 Apache APISIX 创始一片新天地,心愿 Go 能让 Apache APISIX 锦上添花!
装置
采纳库的形式来应用 Go Runner,apisix-go-plugin-runner 中的 cmd/go-runner
官网给出的例子,展现该如何应用 Go Runner SDK。将来也会反对通过 Go Plugin 的机制加载事后编译好的插件。
开发
应用 Go Runner SDK 进行开发
$ tree cmd/go-runner
cmd/go-runner
├── main.go
├── main_test.go
├── plugins
│ ├── say.go
│ └── say_test.go
└── version.go
下面是官网示例的目录构造。main.go
是入口,其中最要害的局部在于:
cfg := runner.RunnerConfig{}
...
runner.Run(cfg)
RunnerConfig
能够用来管制日志等级和日志输入地位。
runner.Run
会让利用监听指标地位,接管申请并执行注册好的插件。利用会始终处于这一状态直到退出。
关上 plugins/say.go
:
func init() {err := plugin.RegisterPlugin(&Say{})
if err != nil {log.Fatalf("failed to register plugin say: %s", err)
}
}
因为 main.go
导入了 plugins 包,
import (
...
_ "github.com/apache/apisix-go-plugin-runner/cmd/go-runner/plugins"
...
)
这样就在执行 runner.Run
之前通过 plugin.RegisterPlugin
注册了 Say
。
Say
须要实现以下办法:
Name
办法返回插件名。
func (p *Say) Name() string {return "say"}
ParseConf
会在插件配置变动的时候调用,解析配置并返回插件特定的配置上下文。
func (p *Say) ParseConf(in []byte) (interface{}, error) {conf := SayConf{}
err := json.Unmarshal(in, &conf)
return conf, err
}
该插件的上下文是这样的:
type SayConf struct {Body string `json:"body"`}
Filter
会在每个配置了 say 插件的申请中执行。
func (p *Say) Filter(conf interface{}, w http.ResponseWriter, r pkgHTTP.Request) {body := conf.(SayConf).Body
if len(body) == 0 {return}
w.Header().Add("X-Resp-A6-Runner", "Go")
_, err := w.Write([]byte(body))
if err != nil {log.Errorf("failed to write: %s", err)
}
}
能够看到Filter
把配置外面的Filter
的值作为响应体。如果在插件中间接进行响应,就会中断请求。
Go Runner SDK API 文档:https://pkg.go.dev/github.com…
把利用构建起来后(在示例外面是 make build
),在运行时须要设置两个环境变量:
APISIX_LISTEN_ADDRESS=unix:/tmp/runner.sock
APISIX_CONF_EXPIRE_TIME=3600
像这样:
APISIX_LISTEN_ADDRESS=unix:/tmp/runner.sock APISIX_CONF_EXPIRE_TIME=3600 ./go-runner run
利用运行时会去监听 /tmp/runner.sock
。
设置 Apache APISIX(开发)
首先要装置 Apache APISIX,须要和 Go Runner 位于同一实例上。
上图右边是 Apache APISIX 的工作流程,左边的 plugin runner 负责运行不同语言编写的内部插件。apisix-go-plugin-runner 就是这样反对 Go 语言的 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-* 插件配置项中定义的。像其余插件一样,它们能够被启用并在运行中从新定义。
为了展现如何开发 Go 插件,咱们先设置 Apache APISIX 进入开发模式。在 config.yaml 中减少以下配置:
ext-plugin:
path_for_test: /tmp/runner.sock
这个配置的意思是,命中路由规定后,Apache APISIX 会向 /tmp/runner.sock 发动 RPC 申请。
接下来设置路由规定:
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":"say", "value":"{\"body\":\"hello\"}"}
]
}
},
"upstream": {
"type": "roundrobin",
"nodes": {"127.0.0.1:1980": 1}
}
}
'
留神插件名称配置在 name
外面,插件配置(经 JSON 序列化后)放在 value
外面。
如果在开发过程中看到 Apache APISIX 端有 refresh cache and try again
的 warning 和 Runner 端有 key not found
的 warning,这是因为配置缓存不统一导致的。因为开发状态下,Runner 不是由 Apache APISIX 治理的,所以外部状态会有可能不统一。不必放心,Apache APISIX 会重试。
而后咱们申请一下:curl 127.0.0.1:9080/get
$ curl http://127.0.0.1:9080/get
HTTP/1.1 200 OK
Date: Mon, 26 Jul 2021 11:16:11 GMT
Content-Type: text/plain; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
X-Resp-A6-Runner: Go
Server: APISIX/2.7
hello
能够看到接口返回 hello 而且没有拜访到任何上游。
设置 Apache APISIX(运行)
这里以 go-runner 为例,只需把运行命令行配置在 ext-plugin 里就能够运行了:
ext-plugin:
\# path_for_test: /tmp/runner.sock
cmd: ["/path/to/apisix-go-plugin-runner/go-runner", "run"]
Apache APISIX 会把 plugin runner 作为本人的一个子过程,治理它的整个生命周期。
留神:这时就不要配置 path\_for\_test 了。Apache APISIX 在启动 runner 时会主动调配一个 unix socket 地址供 runner 监听。APISIX\_LISTEN\_ADDRESS 和 APISIX\_CONF\_EXPIRE\_TIME 这两个环境变量也不必手动设置。
总结
目前 Go Plugin Runner 还处于晚期开发阶段,咱们会陆续欠缺其性能。胜利的开源我的项目离不开大家的奉献,欢送各位参加到 apisix-go-plugin-runner 的开发中来,让咱们一起共建 Apache APISIX 和 Go 的桥梁!
apisix-go-plugin-runner 的我的项目地址:https://github.com/apache/api…
相干浏览
如何用 Java 编写 Apache APISIX 插件。
对于 Apache APISIX
Apache APISIX 是一个动静、实时、高性能的开源 API 网关,提供负载平衡、动静上游、灰度公布、服务熔断、身份认证、可观测性等丰盛的流量治理性能。Apache APISIX 能够帮忙企业疾速、平安的解决 API 和微服务流量,包含网关、Kubernetes Ingress 和服务网格等。
寰球已有数百家企业应用 Apache APISIX 解决要害业务流量,涵盖金融、互联网、制作、批发、运营商等等,比方美国航空航天局(NASA)、欧盟的数字工厂、中国航信、中国移动、腾讯、华为、微博、网易、贝壳找房、360、泰康、奈雪的茶等。
200 余位贡献者,一起缔造了 Apache APISIX 这个世界上最沉闷的开源网关我的项目。聪慧的开发者们!快来退出这个沉闷而多样化的社区,一起来给这个世界带来更多美妙的货色吧!
- Apache APISIX GitHub:https://github.com/apache/apisix
- Apache APISIX 官网:https://apisix.apache.org/
- Apache APISIX 文档:https://apisix.apache.org/zh/…