为什么是 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).Bodyif 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/apache/apisix-go-plugin-runner

把应用构建起来后(在示例里面是 make build),在运行时需要设置两个环境变量:

  1. APISIX_LISTEN_ADDRESS=unix:/tmp/runner.sock

  2. 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.7hello

可以看到接口返回 hello 而且没有访问到任何上游。

设置 Apache APISIX (运行)

这里以 go-runner 为例,只需把运行命令行配置在 ext-plugin 里就可以运行了:

ext-plugin:\# path_for_test: /tmp/runner.sockcmd: ["/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/apisix-go-plugin-runner

相关阅读

如何用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/docs/apisix/getting-started

Go 让 Apache APISIX 如虎添翼相关推荐

  1. Kong APIGW — v.s. Apache APISIX

    目录 文章目录 目录 Kong v.s. Apache APISIX Kong v.s. Apache APISIX Apache APISIX 和 Kong 都是开源的微服务 API 网关,那么在这 ...

  2. 国产微服务网关Apache APISIX安装

    一.需求环境 1.openresty 版本大于 1.15.8.1 2.etcd  -- yum安装即可 3.luarocks  --源码安装 4.nodejs 版本大于10 5.Apache APIS ...

  3. 网关 Apache APISIX 在 360 基础运维平台项目中的实践

    女主宣言 今天小编为大家分享一篇关于Apache APISIX的文章,文章从开发者的角度讲述了 Apache APISIX 网关在 360 基础运维平台的落地实践,希望能对大家有所帮助. PS:丰富的 ...

  4. Apache APISIX 社区成员助力 openEuler 发布第一个社区创新版

    来自 Apache APISIX 社区的罗泽轩和温铭在 openEuler 9 月 30 日发布的第一个社区创新版(21.09)中,为 OpenResty 迁移工作中做了非常多的贡献,让 OpenRe ...

  5. 开源之夏来啦,欢迎报名 Apache APISIX 项目!

    活动介绍 开源之夏(全称:开源软件供应链点亮计划--暑期 2021)是由中国科学院软件研究所与 OpenEuler 社区共同主办的一项面向高校学生的暑期活动,旨在鼓励在校学生积极参与开源软件的开发维护 ...

  6. 贝壳找房:如何基于 Apache APISIX 搭建网关

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试资料 我是王辉,在贝壳找房负责 API 网关系统的开发,我们使用 Apa ...

  7. 百万级 QPS 业务新宠,金山办公携手 Apache APISIX 打造网关实践新体验

    背景介绍 金山办公是目前国内最大的办公软件厂商,旗下产品涉及 WPS.金山文档.稻壳等.在业务层面上由数千个业务以容器化部署在内部云原生平台,目前 Apache APISIX 在金山办公主要负责为中台 ...

  8. Apache APISIX 玩转 Tongsuo 国密插件

    文|罗泽轩 Apache APISIX PMC 本文通过解读国密的相关内容与标准,呈现了当下国内技术环境中对于国密功能支持的现状.并从 API 网关 Apache APISIX 的角度,带来有关国密的 ...

  9. 中国首位 K8s ingress-nginx reviewer 同时提名成为 Apache APISIX committer

    近日,来自支流科技的工程师张晋涛被添加为 Kubernetes ingress-nginx 项目的 reviewer,这也是首位来自中国的 Kubernetes Ingress Controller ...

最新文章

  1. 翻译-高质量JavaScript代码书写基本要点(转载)
  2. 18香警告:一个女生勿近的邪恶开源项目...
  3. 蓝桥杯_算法训练_字串统计
  4. Oracle数据文件的备份与恢复
  5. OAuth 2.0初学者指南
  6. fedora7 常用软件安装
  7. SQL Server : 禁止在SQL Server中生成用户实例
  8. web项目上之深入理解Java国际化
  9. Python机器学习:PCA与梯度上升:008使用PCA对数据进行降噪
  10. 数据库设计中一个矛盾:数据库外键,用还是不用?你怎么看.?
  11. 基于redis和R语言构建并行计算平台(yiyou)
  12. 在PPAPI插件中创建本地窗口
  13. 一、Python数据挖掘(环境篇——Anaconda与Jupyter Notebook)
  14. php解密encrypteddata,PHP解密支付宝小程序的加密数据、手机号的示例代码
  15. 部分设计模式案例代码
  16. Mac To Win
  17. html5 在线签名,html5手写签名
  18. 数据文件检验坏块的利器-dbv
  19. django mezzanine添加多语言支持
  20. java调用ffmpeg把rtsp视频流保存为MP4文件

热门文章

  1. matlab数据归一化(补充),matlab数据归一化(补充)
  2. 专访架构师周爱民:谈企业软件架构设计 1
  3. 【Mybatis】mybatis如何实现分页
  4. Android Studio 使用Profiler时App崩溃闪退
  5. 辽宁移动数码S6_S805_RTL8188_线刷固件包
  6. 一分钟明白 VS manifest 原理
  7. Pygame - Python游戏编程入门(3)
  8. 数字逻辑电路(前三章简介)
  9. 恋前体检!您接受吗?
  10. PRD-产品需求说明文档