• 如何Debug Apinto微服务网关

    前提

    操作系统:linux/mac

    Golang版本:1.17及其以上

    IDEA:Goland

    Linux

    1、安装最新的gops

    go install github.com/google/gops@latest

    2、编写启动配置

    上图红框处需要特别注意,需要和图中保持一致,此处设置了环境变量APINTO_DEBUG=true,开启Apinto的Debug模式。

    如果选择在命令行编译程序,则在编译需要携带-gcflags="all=-N -l"参数,如下

    go build -gcflags="all=-N -l" -o apinto

    此文不再说明命令行编译程序的debug方法。

    3、运行程序


    此处需要选择Debug的按钮

    4、Attach To Process

    在弹出的进程列表中选择需要Debug的进程即可

    注意 : Debug模式开启后,master进程名称为“apinto start”,当Debug模式关闭,master进程名称为“apinto: master”

    Windows

    由于Apinto 在实现restart、stop操作时,需要使用到linux系统的信号指令,Windows 上没有相关指令的支持,因此Apinto 不能直接在Windows 上编译运行。

    若想在Windows 上启动,则需要在Windows 上安装Ubuntu 子系统。

    安装ubuntu子系统

    1、安装部署WSL2:安装WSL(一定要升级到WSL2,否则会有些不兼容的问题)

    2、安装ubuntu可视化界面,具体教程请参考Ubuntu安装可视化界面

    3、Debug程序,Linux Debug方法一致

    MAC

    与Linux Debug方法一致,若在arm架构上attach失败,无法找到对应的apinto进程,可以先将gops删除,再重新安装。

    go install github.com/google/gops@latest

  • Apinto 七月归档

    事件一览

    一、发布Apinto 0.6.4版本

    0.6.4版本修复了0.6.3版本的一系列问题,详情如下:

    • 修改额外参数插件value类型

    • 修复cli命令操作失败无日志输出的问题

    • 修复output拓展缺少CheckSkill方法,导致apinto dashboard不能联动的问题

    二、发布Apinto V0.7版本

    • 升级raft算法,将kv存储替换成etcd内置的kv实现
      注意:由于raft算法升级,旧配置不兼容,若之前使用的 apinto为0.6.x及更老的版本,需要使用apinto-import进行升级

    • 修复文件日志驱动配置错误时,删除操作阻塞的问题

    • 新增proxy_rewrite_v2插件

    • 服务发现忽略scheme字段

    关闭的Issue

    在七月我们解决并关闭了Github 上的四个Issue,感谢 Github 用户 nonzzz 、Dot-Liu 、chen2eric 、strawcarb 的支持

    一、端口占用失败,程序未提示

    • 原因:Apinto在cli命令执行时未指定日志输出位置,导致日志输出失败。
    • 解决方案:新增初始化cli日志方法,并在程序启动时进行调用

    二、快速部署教程访问失败

    • 原因:apinto-dashboard教程上线,Readme文档中相关的链接未及时修改
    • 解决方案:修改Readme文档中的教程链接

    三、支持配置导入导出

    • 解决方案:官方提供导入工具apinto-import ,支持网关配置通过文件方式导入导出,具体可访问仓库https://github.com/eolinker/apinto-import

    四、安装包下载链接固定

    • 解决方案:不处理。文件的版本名可以有效减少信息差异,让使用者知道当前下载的版本号、适用的系统和架构。我们了解了其他相关项目,如NSQ和Nacos,他们也是这么做的。

    常见问题整理

    一、openApi的代码入口在哪?

    • 代码目录:github.com/eolinker/eosc/process-admin

    二、Apinto转发代码的入口

    • 代码目录:github.com/eolinker/apinto/router/router.go. 55行

    三、apinto和eosc的关系

    eosc是apinto依赖的底层框架,apinto更像是一个有多个拓展组装而成的程序,eosc实现了下述特性:

    • 多进程模型,使各个进程各司其职

    • cli命令实现

    • 可插拔的插件框架

    • raft集群同步机制

    • 定义程序的执行流程

    • 端口监听与流量通信机制

    • 环境变量机制

    • 日志模块底层实现

    • ......

    四、如何开启Debug模式

    Debug模式描述:

    • Apinto执行时只会输出error等级的日志,一般的使用已经满足

    • 对于开发调试来说,往往需要了解程序执行各个阶段的交互信息,此时可以开启Debug模式,输出更详细的执行信息

    • 由于Debug模式会输出较多日志,除了开发调试、排查程序执行失败等情况,其余时候不建议开启

    • Debug模式默认关闭

    开启步骤

    (1)在执行程序的服务器/系统设置环境变量

    export APINTO_DEBUG=true

    (2)启动程序(默认程序已停止运行)

    ./apinto start
    关闭步骤

    (1)在执行程序的服务器/系统设置环境变量

    export APINTO_DEBUG=false

    (2)启动程序(默认程序已停止运行)

    ./apinto start

    写在最后

    目前Apinto 及其周边项目已经开源,我们希望通过Apinto强大的插件拓展能力,用户可像乐高积木一样根据需要自行拓展Apinto的插件,以满足不同的业务市场需求。

    Apinto 目前属于萌芽阶段,我们希望集合广大开源爱好者的力量,与大家一起讨论方案,接受大家的批评指正,一起将产品打磨完善,做下一个端与端间的Traffic Middleware。

    这是一个开放和积极的项目,我们诚挚地邀请您一起参与到我们的项目开源工作中。每一个贡献都是有意义的,包括但不限于:

    • 查找bugs,取得性能上的提升

    • 帮助完善文档,提供用户操作体验

    • 提交你们的issue,让我们知道您的奇思妙想

    • 参与自定义插件的开发,丰富apinto的能力

    • ...

    欢迎各位开源爱好者参与到Apinto 项目中,和我们一起为开源事业贡献自己的力量。

    联系我们


  • 升级指南 | 如何从Apinto v0.6升级到v0.7

    前言

    Apinto v0.7版本已经发布,由于该版本主要是针对Raft协议的实现进行了一次升级,使用etcd的kv实现替换了eosc自研的kv实现,导致新旧版本数据不兼容,若直接使用0.7版本替换旧版本,会导致数据加载失败。

    Raft协议升级考虑

    • 由于早期选型时对etcd的源码调研不够完整,旧版本只使用了etcd的raft协议实现,eosc重新实现了kv的处理,该实现的可靠性、性能未经证明
    • 本次升级抛弃了eosc自己实现的kv,使用etcd内置的kv实现,该模型及代码经历过海量用户长时间、大规模的使用,可靠性、性能方面具有一定保证,并且方便以后同步升级到etcd的新版本

    为了确保前后数据可以正常迁移备份,官方提供工具库apinto-import进行数据的导入操作,确保数据正常迁移。升级操作分为单节点升级和集群升级两种情况,详细操作如下

    单节点升级

    1、将旧数据导出,浏览器访问接口:{ip}:{port}/export

    2、关闭旧节点

    ./apinto stop

    3、下载并解压新版本节点

    cd {存放目录} && wget https://github.com/eolinker/apinto/releases/download/v0.7.0/apinto-v0.7.0.linux.x64.tar.gz && tar -zxvf apinto-v0.7.0.linux.x64.tar.gz && cd apinto

    4、启动新节点

    ./apinto start

    5、下载并解压导入程序

    wget https://github.com/eolinker/apinto-import/releases/download/v1.0.0/apinto-import-v1.0.0.linux.x64.tar.gz && tar -zxvf apinto-import-v1.0.0.linux.x64.tar.gz && cd apinto-import

    6、导入配置数据(当前版本只支持zip类型文件)

    ./apinto-import import -path "{压缩包名称}" --apinto-address {apinto访问地址}

    示例:

    ./apinto-import import "export_2022-07-29 161215.zip" --apinto-address http://127.0.0.1:9400

    集群节点升级

    1、下载并解压导入程序

    wget https://github.com/eolinker/apinto-import/releases/download/v1.0.0/apinto-import-v1.0.0.linux.x64.tar.gz && tar -zxvf apinto-import-v1.0.0.linux.x64.tar.gz && cd apinto-import

    2、将旧数据导出,浏览器访问接口:{ip}:{port}/export

    3、进入任意节点服务器(下述描述为节点A),让该节点离开集群

    ./apinto leave

    4、关闭节点A

    ./apinto stop

    5、下载并解压新版本节点

    cd {存放目录} && wget https://github.com/eolinker/apinto/releases/download/v0.7.0/apinto-v0.7.0.linux.x64.tar.gz && tar -zxvf apinto-v0.7.0.linux.x64.tar.gz && cd apinto

    6、启动新节点A

    ./apinto start

    7、导入配置数据

    ./apinto-import import -path "{压缩包名称}" -apinto-address {apinto访问地址}

    示例:

    ./apinto-import import -path "export_2022-07-29 161215.zip" -apinto-address http://127.0.0.1:9400

    8、进入到剩余的其他节点,依次执行步骤3、4、5、6

    9、新节点加入节点A所在集群

    ./apinto join --ip {新节点广播ip} --addr={节点A请求地址}

    示例:

    ./apinto join --ip 10.18.0.1 --addr=10.18.0.2:9400

    写在最后

    目前Apinto 及其周边项目已经开源,我们希望通过Apinto强大的插件拓展能力,用户可像乐高积木一样根据需要自行拓展Apinto的插件,以满足不同的业务市场需求。
    Apinto 目前属于萌芽阶段,我们希望集合广大开源爱好者的力量,与大家一起讨论方案,接受大家的批评指正,一起将产品打磨完善,做下一个端与端间的Traffic Middleware。
    这是一个开放和积极的项目,我们诚挚地邀请您一起参与到我们的项目开源工作中。每一个贡献都是有意义的,包括但不限于:

    • 查找bugs,取得性能上的提升

    • 帮助完善文档,提供用户操作体验

    • 提交你们的issue,让我们知道您的奇思妙想

    • 参与自定义插件的开发,丰富apinto的能力

    • ...

    欢迎各位开源爱好者参与到Apinto 项目中,和我们一起为开源事业贡献自己的力量。

    联系我们


  • 更新|Apinto V0.7.版本发布

    更新说明

    1、该版本主要涉及到raft协议的升级,kv实现部分替换成etcd内置的kv实现

    • 升级原因:
      • 由于早期选型时对etcd的源码调研不够完整,旧版本只使用了etcd的raft协议实现,eosc重新实现了kv的处理,该实现的可靠性、性能未经证明
      • 本次升级抛弃了eosc自己实现的kv,使用etcd内置的kv实现,该模型及代码经历过海量用户长时间、大规模的使用,可靠性、性能方面具有一定保证,并且方便以后同步升级到etcd的新版本

    2、修复文件日志配置错误时,导致程序阻塞的问题

    配置错误包括以下场景:

    • 没有创建文件夹、日志权限

    • 文件目录不存在

    • 磁盘空间满,无法创建日志文件

    • ......

    3、新增proxy_write_v2 插件,提供更加灵活直观的转发重写配置,若先前已经使用了proxy_write 插件,可自行删除旧插件,重新配置proxy_write_v2 插件,相关教程请参考proxy_write_v2插件配置

    4、删除服务发现的scheme 字段

    注意事项

    当前版本由于替换了内置的kv实现,其数据和v0.6.4 及其之前版本不兼容,官方提供了数据导入工具apinto-import ,导入操作请点击Apinto升级指南了解具体升级细节

    版本预告(v0.8.0)

    1、会话机制升级,为多协议提供底层会话支持

    2、新增Websocket协议转发功能

    3、新增环境变量模块,支持使用环境变量配置网关转发信息,包括但不限于路由、上游服务、服务发现、鉴权、各类插件

    写在最后

    目前Apinto 及其周边项目已经开源,我们希望通过Apinto强大的插件拓展能力,用户可像乐高积木一样根据需要自行拓展Apinto的插件,以满足不同的业务市场需求。
    Apinto 目前属于萌芽阶段,我们希望集合广大开源爱好者的力量,与大家一起讨论方案,接受大家的批评指正,一起将产品打磨完善,做下一个端与端间的Traffic Middleware。
    这是一个开放和积极的项目,我们诚挚地邀请您一起参与到我们的项目开源工作中。每一个贡献都是有意义的,包括但不限于:

    • 查找bugs,取得性能上的提升

    • 帮助完善文档,提供用户操作体验

    • 提交你们的issue,让我们知道您的奇思妙想

    • 参与自定义插件的开发,丰富apinto的能力

    • ...

    欢迎各位开源爱好者参与到Apinto 项目中,和我们一起为开源事业贡献自己的力量。

    联系我们


  • 更新 | Apinto v0.6版本发布

    前言

    经过两个月的设计开发,Apinto v0.6版本于2022年6月12日正式发布

    本次更新与Apinto Dashboard同步更新上线,重写了openAPI渲染模版逻辑,大家可以选择使用开源的Apinto Dashboard进行可视化网关配置操作,也可以通过最新版的openAPI,开发属于自己的一套可视化UI界面。

    进程模型优化

    新增admin进程,提供openAPI及渲染模版内容

    进程名称及其作用如下:

    • master进程:
      • 类型:常驻进程
      • 作用
      • 守护进程,管理子进程的启停
      • 负责Raft集群的通信与同步
      • Cli命令交互
      • openAPI流量入口,监听管理端口
      • 将openAPI请求转发到leader节点的admin进程中处理
    • admin进程
      • 类型:常驻进程,仅当节点为leader时启动
      • 作用
      • 配置态进程,该进程缓存了worker进程运行所需要的所有信息
      • 处理openAPI请求,校验请求数据的合法性
      • 提供render模版,供dashboard渲染
    • worker进程
      • 类型:常驻进程
      • 作用
      • 网关核心进程,执行流量转发的工作流程
      • 支持加载外部插件
      • 当插件更新/重加载时,该进程会重启
    • help进程:
      • 类型:临时进程
      • 作用:
      • 由master启动,处理完临时任务后停止
      • 当执行安装/升级拓展时,会优先启动该进程校验拓展的可靠性及合法性

    raft集群模型优化,重写事件同步操作

    集群同步模型如下:

    丰富openAPI接口,支持页面渲染

    开发者可通过修改配置的tag 标签,生成相应格式的Json Scheme 渲染模版,tag 标签内容参考json-scheme标签说明

    Dashboard调用流程如下:

    删除全局插件类型(原“type”字段)

    插件不再区分生效阶段,生效顺序及生效阶段由开发者进行定义。
    插件执行顺序如下图:

    移除Cli操作拓展插件功能(包括安装、更新、卸载等)

    拓展安装、更新、卸载等功能将在下版本通过openAPI方式提供,与插件市场同步上线。

    写在最后

    目前Apinto 及其周边项目已经开源,我们希望通过Apinto强大的插件拓展能力,用户可像乐高积木一样根据需要自行拓展Apinto的插件,以满足不同的业务市场需求。
    Apinto 目前属于萌芽阶段,我们希望集合广大开源爱好者的力量,与大家一起讨论方案,接受大家的批评指正,一起将产品打磨完善,做下一个端与端间的Traffic Middleware。
    这是一个开放和积极的项目,我们诚挚地邀请您一起参与到我们的项目开源工作中。每一个贡献都是有意义的,包括但不限于:

    • 查找bugs,取得性能上的提升

    • 帮助完善文档,提供用户操作体验

    • 提交你们的issue,让我们知道您的奇思妙想

    • 参与自定义插件的开发,丰富apinto的能力

    • ...

    欢迎各位开源爱好者参与到Apinto 项目中,和我们一起为开源事业贡献自己的力量。

    联系我们


  • 虽迟但到,Apinto Dashboard v1.0 Beta版本正式发布🎉🎉

    让各位久等了,经过将近两个月的设计开发,Apinto Dashboard V1.0 Beta版本于2022年6月19日正式发布🎉🎉。

    此次发布的Apinto Dashboard是开源网关Apinto 的衍生项目,它为Apinto提供了可视化配置界面。

    从此,我们将告别繁复的命令行curl命令,只需要在ui界面轻轻一点,就可以自动生成配置,上手成本极低。我们可以快速将后端接口托管到网关中,并可以配置鉴权、流控等安全性操作,用Apinto构建安全可靠的服务Api。

    特性

    通过UI界面动态更新Apinto网关配置

    Apinto Dashboard与Apinto交互流程图

    动态加载模版,根据需要开启/隐藏相关界面

    修改文件config.ymlprofessions配置,即可在侧边栏中隐藏/显示

    配置信息:

    导航栏:

    Json Scheme交互,自动渲染界面,约束配置数据

    交互数据如下:

    界面渲染:

    提供丰富的操作日志,监控配置变更记录

    在Dashboard的所有都会记录在操作日志列表中,点击详情可以看到相关操作涉及的数据改动详情。我们也可以通过搜索功能,查找某个时间段的记录,这样我们以后排查问题的时候也能判断是否有非法操作。

    友好的操作体验,自动获取流程依赖

    Dashboard提供友好的操作体验,在我们配置插件的时候,可以自行选择直接输入完整json配置,也可以选择使用UI配置,配置完成后,json部分将自动同步,ui也是页面也是根据json-scheme语法自动生成。

    以后开发apinto的模块或者拓展时,只需要定义好配置的类型、label、最大值最小值等相关限制,就可自动生成页面。

    整个操作也是联动的,比如我们现在需要为路由新增一个鉴权,此时,只要在路由页面点击增加鉴权插件,然后在选择框里选择相应的鉴权,提交即可,这样,带有鉴权的路由便生成完成。

    相信大家已经迫不及待想去试用了,接下来我将给大家介绍下如何部署Apinto Dashboard。

    部署

    由于Apinto Dashboard 是Apinto 的可视化UI项目,因此在部署该项目前,需要确保Apinto项目已经部署完成。

    若未部署Apinto ,请参考教程Apinto部署

    1. 下载并解压安装包

    wget https://github.com/eolinker/apinto-dashboard/releases/download/v1.0.4-beta/apinto-dashboard-v1.0.4-beta.linux.x64.tar.gz && tar -zxvf apinto-dashboard-v1.0.4-beta.linux.x64.tar.gz && cd apinto-dashboard

    2. 启动程序

    nohup ./apinto-dashboard > logs/stdout_apinto-dashboard_"$(date '+%Y%m%d-%H%M%S')".log 2>&1 &

    该命令会将日志输出到logs 目录下以stdoutapinto-dashboard 为前缀的日志文件中

    3. 浏览器打开Apinto Dashboard 地址

    本示例在本地部署,因此ip为127.0.0.1,端口为8081,在浏览器中输入账号密码登录即可

    至此,Dashboard部署完毕,如果大家需要了解更多的使用信息,请点击更多

    写在最后

    • APINO 简介:Apinto是一个基于 Golang 开发的微服务网关,能够实现高性能 HTTP API 转发、多租户管理、API 访问权限控制等目的,拥有强大的自定义插件系统,用户可以自行扩展,能够快速帮助企业进行 API 服务治理、提高 API 服务的稳定性和安全性。接下来我们将提供插件市场,通过Apinto强大的插件拓展能力,用户可像乐高积木一样根据需要自行拓展Apinto的插件,丰富Apinto的能力。

    • 官网网址:https://www.apinto.com

    • Github 链接:https://github.com/eolinker/apinto

    • 论坛地址:https://community.apinto.com/

    • 帮助文档:https://help.apinto.com/docs

    • QQ群号:725853895

    • 微信群二维码:
      img


  • Apinto Ingress Controller发布

    前言

    通过开源网关团队的努力,Apinto Ingress Controller将在3月下旬正式推出。

    在此之前,Apinto更新配置只能通过Open API的方式更新,且只支持宿主机部署、容器部署,更新配置也相对比较麻烦。

    因此,Apinto Ingress Controller的推出意味着我们可以将Apinto部署在Kubernetes中,并且通过配置文件的形式实时更新。

    设计

    虽然原生 ingress controller 支持在 yaml 中 annotation 定义脚本片段,但更多是为了支持高级功能而实现的一个临时方案,一方面大量的annotation脚本不好管理,不好维护,另一方面,对特性的支持也不太友好。

    而Apinto有路由、服务、负载、鉴权、插件等多种类型的资源,需要有更加灵活的方式去定义资源。因此我们选择了编写Kubernetes CRD文件的方式去定义Apinto的资源。

    下面为Apinto Router CRD的简单定义:

    apiVersion: apiextensions.k8s.io/v1
    kind: CustomResourceDefinition
    metadata:
      name: apintorouters.apinto.com
    spec:
      group: apinto.com
      scope: Namespaced
      names:
        plural: apintorouters
        singular: apintorouter
        kind: ApintoRouter
        shortNames:
          - ar
          - router
      versions:
        - name: v1beta
          served: true
          storage: true
          schema:
            openAPIV3Schema:
              type: object
              properties:
                spec:
                  type: object
                  required: ["name", "listen", "driver", "target", "rules"]
                  properties:
                    name:
                      type: string
                      minLength: 1
                    driver:
                      type: string
                      enum: ["http"]
                    listen:
                      type: integer
                      minimum: 1
                      maximum: 65535
                    target:
                      type: string
                      pattern: '\w+(@service)$'
                    method:
                      type: array
                      items:
                        type: string
                        enum: ["*", "DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT", "TRACE"]
                    host:
                      type: array
                      items:
                        type: string
                        pattern: '[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+\.?'
                    protocol:
                      type: string
                      enum: ["http","https"]
                    cert:
                      type: array
                      items:
                        type: object
                        properties:
                          key:
                            type: string
                            minLength: 1
                          crt:
                            type: string
                            minLength: 1
                    rules:
                      type: array
                      minItems: 1
                      items:
                        type: object
                        properties:
                          location:
                            type: string
                            minLength: 1
                          header:
                            type: object
                            x-kubernetes-preserve-unknown-fields: true
                          query:
                            type: object
                            x-kubernetes-preserve-unknown-fields: true
                    plugins:
                      type: object
                      x-kubernetes-preserve-unknown-fields: true

    架构设计如下:

    用户提交YAML文件时,会触发ValidatingWebhook操作,Kubernetes此时会回调定义好的Admission Server地址,Apinto Client将YAML文件配置转换成Apinto Gateway的可读配置,Apinto Gateway会校验配置信息的完整性和可靠性,校验完成后,将结果依次返回,最后返回操作结果给用户。

    开始使用

    自定义资源的配置顺序与apinto一致,均有依赖关系。

    以配置路由以及服务为例:

    服务 service.yml

    apiVersion: apinto.com/v1beta
    kind: ApintoService
    metadata:
      name: demo-anonymous
    spec:
      name: demo-anonymous
      driver: http
      desc: "示例服务"
      timeout: 30000
      anonymous:
        type: round-robin
        config: "http://demo-apinto.eolink.com:8280" #该接口返回http调用信息
      retry: 2
      rewrite_url: /

    路由 router.yml

    apiVersion: apinto.com/v1beta
    kind: ApintoRouter
    metadata:
      name: apinto.router
    spec:
      name: apinto.router# 路由名称
      listen: 8080    # 监听端口
      driver: http # 驱动
      protocol: http
      method:
        - GET
      rules:      # 规则列表
        - location: "/demo"  # 匹配路径
      target: demo-anonymous@service    # 目标服务ID,格式为:{服务名称}@service

    创建服务和路由

    kubectl create -f service.yml
    kubectl create -f router.yml

    创建完服务以及路由之后,调用apinto暴露到集群外的服务来查看是否存在该路由

    curl -X GET 'http://{node_ip}:{admin_port}/api/router/apinto.router'

    返回

    {
        "create": "2022-03-23 06:14:48",
        "driver": "http",
        "id": "apinto.router@router",
        "listen": 8080,
        "method": ["GET"],
        "name": "apinto.router",
        "profession": "router",
        "protocol": "http",
        "rules": [{
            "location": "/demo"
        }],
        "target": "demo-anonymous@service",
        "update": "2022-03-23 06:14:48"
    }

    通过调用apinto暴露到集群外的服务来请求该路由

    curl -X GET 'http://{node_ip}:{http_port}/demo'

    返回

    {
        "body": "",
        "header": {
            "Accept": ["*/*"],
            "User-Agent": ["curl/7.75.0"],
            "X-Forwarded-For": ["10.24.1.1,10.24.1.1"]
        },
        "host": "192.2.9.43:31080",  
        "method": "GET",
        "path": "/demo",
        "remote_addr": "192.4.5.22:19091", 
        "url": "/demo"
    }

    备注:以上的ip数据非原始数据

    使用示例点此进行跳转。

    写在最后

    Apinto是一个基于 Golang 开发的微服务网关,能够实现高性能 HTTP API 转发、多租户管理、API 访问权限控制等目的,拥有强大的自定义插件系统可以自行扩展,能够快速帮助企业进行 API 服务治理、提高 API 服务的稳定性和安全性。

    目前Apinto及其周边项目已经开源,我们希望通过Apinto强大的插件拓展能力,用户可像乐高积木一样根据需要自行拓展Apinto的插件,以满足不同的业务市场需求。

    这是一个开放和积极的项目,我们诚挚地邀请您一起参与到我们的项目开源工作中。每一个贡献都是有意义的,包括但不限于:

    • 查找bugs,取得性能上的提升
    • 帮助完善文档,提供用户操作体验
    • 提交你们的issue,让我们知道您的奇思妙想
    • 参与自定义插件的开发,丰富apinto的能力

    期待各位的参与,一起让这个项目变得更好。

    联系我们


  • Apinto Gateway 的前世今生

    Goku项目自2022年1月14日起,正式改名为Apinto,文章或图片提到的Goku字样实际是和Apinto同属一个项目。

    大家好,我是孟柱,目前是Goku的架构师。

    今天很开心可以和大家分享我们在过去几年在Goku网关上做的一些事情,也希望和大家多多交流。

    首先来讲一下我们为什么要做一个新的API网关。

    Eolinker自建API网关产品的想法从2017年就有了,当时我们团队有以下的考虑:

    首先是公司的愿景使命驱动,因为Eolinker 是一家致力于发展API经济的技术公司,我们目前已经为数十万开发者提供了强大的API管理和测试工具,而API网关是API流量管理和微服务架构的重要组成部分,我们希望能够填补这块的技术空白,并且结合现有产品为用户提供更大的价值 。

    其次是业务驱动,我们首先是网关的使用者,其次才是开发者。因为Eolinker 的产品本身有使用API网关的需求,比如我们的SaaS产品和API交易平台,市面上的API网关在数据处理方面做得不好,比如针对多个服务数据的整合、编排等。无法满足我们业务的需求。因此干脆就考虑自己来做。

    最后是技术驱动:

    当时我们调研过市面上的大部分网关,大多基于第三方产品开发,拥有较多的依赖和技术包袱,不便于后续深度开发和扩展,我们希望能够做一个性能优异、功能强大、使用简单的网关产品,只能从头开始设计开发。

    以上三点最终推动了我们从网关的使用者变成一个开发者,并将Goku网关从18年逐步迭代到现在。

    迭代的过程还是比较曲折的,如果按年可以大致分为以下几个阶段:

    前世1( 2018 ):Goku Lite V1

    2018年9月份我们开发了最早期的goku开源版本,实现了基本的网关转发以及插件扩展等功能,但是该版本也存在以下的问题:

    1. 控制平面和数据平面耦合程度比较高
    2. 配置的同步国语依赖数据库,如果数据库数据异常,可能导致网关节点运行不正常
    3. 当涉及到异地架构的时候,可能会由于网络环境较差导致数据同步失败

    19年我正式加入Eolinker,在此之前我在酷狗音乐负责底层架构,当时开发和迭代了酷狗音乐的一系列底层服务,并推动了酷狗的微服务化转变。

    我到Eolinker接到的第一个任务就是要提升Goku的性能和稳定性,我们对架构进行了分析发现了刚才提到的一些问题。

    因此我们在19年3月开始对整个goku进行了重构,此时网关的架构发生了以下改变:

    1. 将数据库和节点进行解耦,控制台直接推送配置信息到节点
    2. 配置可以回滚,并且当推送失败的时候不会影响网关的正常运行,控制台也会自动重新推送配置

    此时网关的整体稳定性有了较大提升。

    20年初,我们继续将网关进行重构,将网关彻底拆分成控制台、环境、集群、节点等4个层面,这样的架构可以满足我们的部分商业客户的复杂的API运维需求,同时网关的功能也可以更加深入,此时的商业版网关已经在大部分功能方面与Kong的企业版持平,并且提供了部分更深入的多集群管理功能。

    到了2021年,经过前面几年的网关架构和客户需求的摸索,我们已经在微服务网关上面积累了大量的实践经验,现在我们抱着更加开放的心态,希望能够将过往的产品和技术经验重新整理并回馈技术社区,因此我们在今年3月开始了新的一轮重构。

    这一次重构几乎重写了以前的所有代码,我们为此自研了一套中间件开发框架EOSC(Eolinker Open Structure)。EOSC就像是乐高积木的底座,提供了标准的接口,我们可以根据这些接口开发自定义的模块,并且设置各个模块的执行流程,并最终在这个标准底座上衍生出不同的产品形态。

    接下来向大家介绍的Goku,其实就是我们开发了一系列的路由、鉴权、服务等模块,并且组合得到的“网关”产品。未来如果有需要,我们可以基于EOSC衍生出service mesh等其他产品形态。

    目前我们重构后的goku,已经在性能等方面超越了nginx,未来我们希望将eosc打造成一个最好的通用中间件开发框架,并且提供一个插件市场,让eosc能够真正像乐高一样扩展出不同的产品。

    对于goku网关,我们目前在性能上已经有一些优势,接下来我们除了要保持性能优势之外,还会不断将我们之前在企业服务的功能和最佳实践迁移过来,打造市面上最强的开源网关,并且将产品的使用和学习成本都降低,真正成为微服务领域的技术软件设施。

    目前我们已经提供了网关产品的一些基本功能,比如动态路由、服务发现、负载均衡、鉴权、健康检查等,而且也可以通过自定义插件来不断强化Goku。

    接下来我们会全面强化Goku的开源产品,由于我们是重新重构了整个产品,因此这个需要花一点时间,大家如果有兴趣一起参与进来,相信速度会更快。

    这里我们也列了个主干路线图,本月我们会首先完成集群的支持,然后完善插件扩展的模型,方便后续更快地开发插件。在10月份会发布插件市场,让所有人都能自由在上面发布和下载插件,扩展出自己的Goku功能。

    Goku的前世今生已经和大家基本介绍完了,接下来我们会逐步把企业级网关的功能和实践都应用在开源网关中,并且目前我们已经正式加入了Linux基金会,我们也计划在后续将Goku捐献给Linux基金会,让Goku能够帮助全球开发者更快更好的管理API流量。

    我们也欢迎大家参与到我们的开源工作中,可以加入我们的QQ群或者Slack群交流。

    QQ群号:725853895

    Slack跳转链接


  • Apinto 快速部署及使用演示

    Goku项目自2022年1月14日起,正式改名为Apinto,文章或图片提到的Goku字样实际是和Apinto同属一个项目。

    Apinto网关的部署提供了以下两种安装方式:通过安装包安装、源码编译安装。

    Apinto网关的安装非常简单,使用安装包安装的方式,从下载到安装成功仅仅只要几秒钟。而启动也仅需一条命令,可以指定各种运行参数,包括网关的http和https监听端口、ssl证书文件及配置文件的路径。若不填写任何运行参数则默认网关http监听8081端口。值得一提的是,后续我们将会支持更多种安装方式,包括一键部署脚本,Docker和k8s。用户可以根据需求来选择合适自己的安装方式。

    讲完安装部署,接下来就是网关的使用。假设goku网关的域名及端口为127.0.0.1:8081。现在有一个使用场景,我想通过请求路径为goto_goku的http请求访问网关的8080端口后会将请求转发给gokuapi.com。这是一个简单的转发过程。当一个请求到达网关后,网关会解析这个请求并进行转发。

    而goku网关快速进行转发只需要配置路由及服务。通俗一点讲,在goku网关,服务可以理解为一组API的集合,而路由则是网关通过什么样的条件才能匹配到某一个服务。那么网关应该怎样配置呢?首先需要创建一个demo服务,服务的转发地址设置为goku官网,创建后会返回demo服务id,然后再创建路由,匹配路径设置为goto_goku,最后将服务id绑定至路由。

    配置有两种方式,一种是通过yaml文件配置,在网关启动时会读取文件内的配置。另一种是直接调用openAPI来配置,为了方便演示,这里用yaml文件来演示如何配置路由及服务。

    首先我们需要创建一个服务,这里我们将服务命名为demo_service,并且配置该服务接收请求的协议、转发目标、超时时间、重试次数、转发方法等。目前我们配置的demo_service会将接收到的请求以get方式转发到gokuapi.com,并且如果请求超过3000毫秒会自动重试2次。

    接下来配置了一个路由来监听请求,比如这里我们设置了一个路由监听8080端口,当有路径为goto_goku的http请求过来时,将数据转发给刚才配置好的demo_service服务。

    刚刚演示了如何快速用网关进行简单的转发,除此之外我们可以给路由和服务增加许多额外的功能,比如使用注册中心来代替静态的转发目标,或者是给服务设置鉴权来保证服务的安全。更多的功能可以访问我们的帮助中心,或者在我们的qq群或slack群发表疑问。


  • 以鉴权为例,介绍如何快速开发一个插件

    Goku项目自2022年1月14日起,正式改名为Apinto,文章或图片提到的Goku字样实际是和Apinto同属一个项目。


    Apinto 网关由于采用了模块化的设计,你几乎可以扩展其中的所有功能,为了方便大家了解如何扩展Apinto ,我这里花几分钟的时间演示如何去开发Apinto 的鉴权插件。

    首先来了解一下goku网关执行的流程,客户端发送请求给网关,当路由模块匹配成功后,会将请求下发到服务模块,在这个过程中如果配置了鉴权模块,则会先进行身份认证,符合条件的请求才会最终下发到负载均衡模块,配合服务发现,最终转发到后端服务。

    在流程图中,蓝色部分是我们网关的功能模块,也可以理解为是网关执行过程中的各个阶段,灰色部分便是我们功能模块的具体功能实现,比如在路由模块中可以同时实现http、tcp等多种协议的匹配。

    在Goku中,我们定义了几个基本概念:

    首先是Profession,可以理解为功能模块,比如路由模块,鉴权模块,负载模块,服务模块等,不同的Profession负责不同的工作职责。

    其次是Driver,可以理解为功能模块内的不同的功能,比如对于鉴权模块来说,里面包含了APIKey、Basic Auth、JWT等不同的Driver。他们都是执行鉴权的工作,但是各自的鉴权方式不同。

    然后是Worker,可以理解为某个具体功能的配置信息,为运行时的配置更新器,其定义了当配置更改时,如何去对缓存进行操作

    了解了这三个基本概念之后,我们就可以很快地开发一个新的插件,开发的基本流程如下:

    1. 我们需要先定义好插件的配置格式,比如xxxx
    2. 我们需要实现IWorker接口,当配置发生改变时,网关将会调用IWorker的相关方法进行更新同步,比如xxxx
    3. 我们实现Driver接口,该接口主要用于创建IWorker对象,比如xxxx
    4. 实现Factory接口,用于创建IDriver对象,比如xxxx
    5. 而此时的Factory对象,则是我们apikey驱动的入口,比如xxxx

    目前我们设计了两种驱动加载的模式,一种是将驱动编译进原程序中,这样最终编译出来的是一个完整的网关程序。另外一种是将渠道单独编译成.so扩展文件,由网关节点加载.so文件。

    关于插件的具体开发方式,大家可以访问我们的帮助文档来了解,如果在开发过程中遇到疑问,可以随时在我们的QQ群或者slack群内提问,我们会及时解答。