来自 | 才云 Caicloud(Caicloud2015)内容 | 郭维 社区开发者
自 2009 年开源以来,Go 作为一种强大、高效、简洁、易上手的编程语言,在帮助阅读、调试和维护大型软件系统上发挥着越来越重要的作用。而依托其健康生态,Golang 社区也相继涌现出诸如 beego、gin、chi、go-restful 等知名框架,为 Go 提供额外功能支持。
但选择过多,反受其乱。面对层出不穷的优秀框架,不同团队、不同开发者在框架选择上往往会出现分歧,不同框架之间也彼此壁垒高筑,导致业务与框架耦合,开发效率大大降低
为了解决这类问题,才云 Caicloud 实现了 Golang API 框架 Nirvana,把 API 从对框架的依赖中彻底解放出来。它专为提高生产力和可用性设计,可扩展、性能高,旨在成为才云 Caicloud 所有 Golang 服务的基石,助力业务的高速开发。接轨 Kubernetes 这些痛点不可忽视

近年来,为了满足业务发展需要,应对日益激烈的市场竞争,大量企业开始使用容器部署云工作负载。而随着容器使用量的增长、Kubernetes 成为容器编排的事实标准,在 Kubernetes 上打造新一代容器云平台成了企业谋求发展的必由之路。
为了顺应时局,技术团队除了进行思维上的转变,还要应对团队和业务方向的调整,对团队项目和产品完成切割分化。这之中就涉及对 Go 框架变更的抉择。
两年前,才云 Caicloud 团队在构建基于 Kubernetes 的云平台时,在框架上遇到了不少麻烦:当时 Kubernetes 正值发展期,为了快速开发,工程师们往往倾向于选择自己熟悉的框架。因此,虽然大多数项目用的是 go-restful(Kubernetes 的选型),但用 beego、gin、chi 等框架的工程师也不在少数,这就给业务整合带来了很多问题:

  • 不同框架对 API 的描述形式不一致,这增加了不同团队间的沟通成本;

  • 不同框架 API 风格差距较大,文档自动化困难;

  • 错误定义和处理方式在不同项目之间存在差别,会导致客户端处理困难。

曾经开放的工程师文化成了变革的最大阻力业务和框架隔离 Nirvana 出奇招

Nirvana 就是在这个背景下诞生的。
借鉴了 Kubernetes 声明式 API 的设计,巧妙规避了框架对 API 的侵入。同时,为了实现业务和框架的隔离,它定义一个规范,让 API 按照规范书写,完全屏蔽了框架对 API 的影响。
一言以蔽之,Nirvana 框架的设计思路始终围绕工程师们亲历的种种痛点:

  • 构建风格一致的 API 项目;

  • 使用统一的 RESTful 路由与声明式 API 定义,避免业务对框架产生依赖;

  • 使用统一的错误生成和处理方式;

  • 提供开箱即用的基础功能,包括 Prometheus metrics、tracing、profiling 等;

  • 自动生成 API 文档和客户端代码。

在 Nirvana 中,用一套 API Definition 来声明式地描述业务 API。下面是一个列出消息列表 API 的例子:

  1. Definition{

  2.    // 这个 API 返回的是资源数组,所以使用 List 方法。

  3.    Method:     def.List,

  4.    // Summary 是一个短语,用于描述这个 API 的用途。这个短语在生成文档和客户端的时候用于区分 API。

  5.    // 这个字符串去掉空格后会作为生成客户端时的函数名,因此请确保这个字符串是有意义的。

  6.    Summary:    "List Messages",

  7.    // 详细描述这个 API 的用途。

  8.    Description: "Query a specified number of messages and returns an array",

  9.    // 业务函数

  10.    Function:   message.ListMessages,

  11.    // 对应业务函数的参数信息。用于告知 Nirvana 从请求的那一部分取得数据,然后传递给业务函数。

  12.    Parameters: []def.Parameter{

  13.        {

  14.            // 参数来源

  15.            Source:     def.Query,

  16.            // 参数名称,作为 key 从 Source 里取值。

  17.            // 与业务函数的参数名称无关。

  18.            Name:       "count",

  19.            // 默认值

  20.            Default:    10,

  21.            // 参数描述

  22.            Description: "Number of messages",

  23.        },

  24.    },

  25.    // 对应业务函数的返回结果。用于告知 Nirvana 业务函数返回结果如何放到请求的响应中。

  26.    Results: def.DataErrorResults("A list of messages"),

  27. }

而对应业务 API 的形式则是:

  1. type Message struct {

  2.    ID      int `json:"id"`

  3.    Title   string `json:"title"`

  4.    Content string `json:"content"`

  5. }

  6. func ListMessages(ctx context.Context, count int) ([]Message, error) {

  7.    messages := make([]Message, count)

  8.    for i := 0; i < count; i++ {

  9.        messages[i].ID = i

  10.        messages[i].Title = fmt.Sprintf("Example %d", i)

  11.        messages[i].Content = fmt.Sprintf("Content of example %d", i)

  12.    }

  13.    return messages, nil

  14. }

很显然,业务函数并不关心自身是如何暴露给外部的,实现方法也和其他内部函数没有差别(这只是一个简单的例子,更多详细内容请查阅 Nirvana Definition 文档:https://caicloud.github.io/nirvana/zh-hans/topics/definition.html)。
在这个例子里,API Definition 描述了完整的 API 结构,包括 RESTful 路径、请求方法、请求描述、请求参数、请求响应和请求 handler。框架只需要解析 API Definition,就能得到业务逻辑的入口和出口处理方式。对开发者而言,API 的开发过程从“ 命令式路由 + 数据转换 + 业务逻辑” 变成了“API Definition + 业务逻辑”。框架与业务逻辑之间通过 API Definition 进行桥接。
Nirvana 框架

API Definition 作为声明式 API,除了让框架读取信息生成路由和对外提供服务,它本身也完整描述了一个 API 的工作方式。因此,还能用它生成 openapi 文档和客户端。在接下来的几个小节中,将详述 Nirvana 提供的这些能力。
路由工作流
任何一个 API 框架都具备基本的 HTTP Serve 能力( HTTP 接口服务能力)。在 Nirvana 中,HTTP Serve 由 Golang 基础库 http 提供。HTTP 请求的路由方式如下图所示:

在这个请求的工作流中:

  • Filters 是请求过滤器,可以对不符合要求的请求进行提前响应,而不会进入路由匹配过程;

  • Middlewares 是围绕请求的中间件,能够控制请求的处理行为;

  • Executor 是最终处理请求的执行器,负责通过参数生成器(ParameterGenerators)和结果处理器(DestinationHandlers)将请求注入到业务逻辑之中,并将返回结果处理后返回。

在这里,Filters、Middlewares、ParameterGenerators 和 DestinationHandlers 都是可以被开发者重新定义的。这也意味着开发者可以改变 Nirvana 的原生处理行为,使之符合自身需求。
服务构建工作流
Nirvana 另一个工作流是将 API Definition 构建到路由中去,并完成整个服务的启动工作。

在 Nirvana 启动时,除 API Definition 之外,它还能够通过插件往框架里注入一些功能,包括注册 Filters、Middlewares、添加其他路由 endpoint 等。目前 Nirvana 已经提供对 metrics、profiling、tracing、log 等常用插件的支持。
通过以上两个工作流,以及 Nirvana 中大量的模块方法注册接口,开发者可以自行扩展 API Definition 的能力,让 API Definition 与业务逻辑更加贴合。API Definition 单向依赖并描述了业务逻辑,并作为框架和业务之间的桥梁,既达到了声明式 API 的定义形式,也满足了业务不依赖框架的目标。
框架扩展
无论是路由还是服务构建过程,Nirvana 的实现都不是 hardcode 的。在框架的大部分包里,你能发现类似以下形式的代码结构:

  1. var consumers = map[string]Consumer{

  2.    definition.MIMENone:        &NoneSerializer{},

  3.    definition.MIMEText:        NewSimpleSerializer(definition.MIMEText),

  4.    definition.MIMEJSON:        &JSONSerializer{},

  5.    definition.MIMEXML:         &XMLSerializer{},

  6.    definition.MIMEOctetStream: NewSimpleSerializer(definition.MIMEOctetStream),

  7.    definition.MIMEURLEncoded:  &URLEncodedConsumer{},

  8.    definition.MIMEFormData:    &FormDataConsumer{},

  9. }

  10. // RegisterConsumer register a consumer. A consumer must not handle "*/*".

  11. func RegisterConsumer(c Consumer) error {

  12.    if c.ContentType() == definition.MIMEAll {

  13.        return invalidConsumer.Error(definition.MIMEAll)

  14.    }

  15.    consumers[c.ContentType()] = c

  16.    return nil

  17. }

在这种结构里,开发者可以自定义每一块的实现方式,甚至替换框架默认行为。帮助自己最大限度地利用 Nirvana,使它符合业务特定需求。
插件机制
在服务构建工作流中,提到了插件机制。下面介绍三个重要插件 metrics、profiling和tracing。
1. metrics 插件
Prometheus 作为 CNCF 的开源项目,为我们提供了非常适于描述业务指标的格式:Prometheus Metrics。Nirvana 提供的 metrics 插件可以在启动时默认暴露 /metrics 接口。对此,开发者可以将业务指标注册到 Prometheus 中,通过这个接口让 Prometheus 采集。也就是说,Nirvana 不仅能帮助开发者了解业务的运行状态,也为开发者定位业务问题提供了强有力的帮助。
2. profiling 插件
Golang 提供了进程级别的 profiling 能力。Nirvana 通过 profiling 插件直接将这个能力注入到框架中。开发者只需要启用插件即可获得这些调试和性能测试能力,获得业务内部执行的状态信息。 
3. tracing 插件
在 CloudNative 时代,业务通常会以微服务或 Serverless 的形式进行架构。多个服务之间的交互通常是黑盒的,这易导致我们难以定位分布式架构中的服务问题。Tracing 作为解决分布式架构下的调用链方案,可以在分布式系统出现问题时为开发者提供大量的信息,帮助开发者排查问题。Nirvana 的 tracing 插件使用了 open-tracing 的接口规范,并借助 CNCF 开源项目 jaeger 的能力,为开发者提供一站式 tracing 方案。
文档和客户端生成
API Definition 和 Nirvana 的结合帮助我们完成了服务构建。在服务之外,通过 API Definition 的描述能力,Nirvana 还实现了基于 openapi 的文档生成和客户端生成。
Nirvana 的文档生成基于 openapi 2.0(即 swagger 2.0)规范,从 API Definition 中提取 API 信息,生成 API 描述文件 swagger.json。除了生成 API 描述文件之外,它还能通过 ReDoc 直接提供文档服务(更多信息请查看 https://caicloud.github.io/nirvana/zh-hans/guides/doc.html)。在 Nirvana 中,生成文档的方式十分简单:

  1. $ nirvana api --serve=":8081"

只需一条命令,API 文档即可生成,并通过 8081 端口提供服务。之后我们就能通过网页查看文档了:

Nirvana 的客户端生成同样基于 API Definition ——读取类型信息,生成客户端包(目前仅支持生成 Golang 包)。客户可以直接引用这个包来调用服务,整个客户端的使用方式与本地调用一致(更多信息请查看 https://caicloud.github.io/nirvana/zh-hans/guides/client.html)。 
下面是一键生成客户端的示例:

  1. $ nirvana client

这个命令会在当前目录下生成一个 client 目录,在这个目录内生成 Golang 客户端代码:

  1. type Client struct {

  2.    rest *rest.Client

  3. }

  4. // ListMessages returns all messages.

  5. func (c *Client) ListMessages(ctx context.Context, count int) (messages []Message, err error) {

  6.    err = c.rest.Request("GET", 200, "/apis/v1/messages").

  7.        Query("count", count).

  8.        Data(&messages).

  9.        Do(ctx)

  10.    return

  11. }

如果您想进一步了解 Nirvana,可以参考才云 Caicloud 云原生 CI/CD 项目 Cyclone(更多信息请查看 https://github.com/caicloud/cyclone)。它包含一个 API 组件 Cyclone Server, 基于 Nirvana 对外提供简单易用的 API。
Nirvana:涅槃

Nirvana,梵语中的涅槃。
一如我们对它的期待:让 API 从对框架的依赖中涅槃重生。
经过一年多的开源,目前 Nirvana 在基础 API 服务能力上已经经过内部验证。由于数据传输层和转换层的复杂度被大大降低,才云 Caicloud 也切实体验到了这个开源框架带来的便捷,以及它在加速业务开发上的显著效果。
未来,Nirvana 将在以下几方面继续发力:

  • 持续优化扩展文档和客户端生成的能力,降低开发者在这两块上的心智负担;

  • 持续优化 metrics、profiling、tracing 的能力,并增加新的云原生能力,让这些能力成为云原生应用的标配;

  • 框架模块化加强,让 Nirvana 的每一块代码皆可定制;

  • 优化框架性能,降低反射对服务的影响;

  • 让 Nirvana 成为 Golang 的 CloudNative & SOA 框架。

Nirvana 正致力于成为让业务无感知的框架。目前,才云 Caicloud 正在这条路上踽踽独行,也真诚地希望将来能有更多开发者愿意加入进来,一起构建 Nirvana,一起建设 Golang 社区,一起拥抱开源的胜利。
也许你的加入,能让这场涅槃更加炫目!
感谢参与开源本项目的所有开发者!
Nirvana GitHub:https://github.com/caicloud/nirvana
Nirvana 文档:https://caicloud.github.io/nirvana/zh-hans/

来自 | 才云 Caicloud(Caicloud2015);内容 | 郭维 社区开发者

才云 Caicloud 开源 Nirvana:让 API 从对框架的依赖中涅槃重生相关推荐

  1. Caicloud 开源 Nirvana:让 API 从对框架的依赖中涅槃重生

    戳蓝字"CSDN云计算"关注我们哦! 文章来自:才云caicloud作者:才云 我们造了个轮子 来自 | 才云 Caicloud 内容 | 郭维 社区开发者 自 2009 年开源以 ...

  2. 才云 Caicloud 步履不停,与云原生先行者携手同行

    杭州2018年9月20日电 /美通社/ -- 在初秋的暑气与阵阵小雨的交织激荡中,在云原生领域精英与业界领袖的见证参与下,由才云科技(Caicloud)."K8sMeetup 中国社区&qu ...

  3. 才云开源 Nirvana:Golang REST API框架

    自 2009 年开源以来,Go 作为一种强大.高效.简洁.易上手的编程语言,在帮助阅读.调试和维护大型软件系统上发挥着越来越重要的作用.而依托其健康生态,Golang 社区也相继涌现出诸如 beego ...

  4. 不止操作系统,智能手机才更需要开源!

    作者 | JC Torres 译者 | 弯月 责编 | 屠敏 出品 | CSDN(ID:CSDNnews) 毫不夸张地说,绝大部分现代生活都与智能手机有某种关系.即使是最简单的事情,比如发短信和打电话 ...

  5. 腾讯云数据库开源再突破:TDSQL PG版查询性能提升百倍

    日前,腾讯云数据库开源产品TDSQL PG版(开源代号TBase)宣布推出重磅升级--经过一年半的打磨,上万张表访问场景下,内存占用节省60%:查询性能提升百倍:SQL语句兼容性增强.同时,大力提升原 ...

  6. 2017 码云最火爆开源项目 TOP 50,你都用过哪些 – 坏~牧羊人 – 博客园

    2017 码云最火爆开源项目 TOP 50,你都用过哪些 本文转自:https://share.html5.qq.com/fx/u?r=JdjvzwC 2017 年度码云热门项目排行榜 TOP 50 ...

  7. TAPD助力FIT2CLOUD飞致云驰骋开源疆场

    本文将带你了解FIT2CLOUD飞致云众多开源项目背后的研发体系,包括如何借助腾讯TAPD敏捷研发协作平台实现高效的研发与协作,保障众多开源项目的持续迭代.同时介绍腾讯TAPD如何与我们自身Meter ...

  8. 2017 码云最火爆开源项目 TOP 50,你都用过哪些

    本文转自:https://share.html5.qq.com/fx/u?r=JdjvzwC 2017 年度码云热门项目排行榜 TOP 50 出炉啦!我们根据所有开源项目在码云的用户关注度.活跃度.访 ...

  9. DaoCloud道客云原生开源项目Clusterpedia(The Encyclopedia of Kubernetes clusters)加持kubectl,检索多集群资源

    DaoCloud道客云原生开源项目Clusterpedia,全称The Encyclopedia of Kubernetes clusters,源码查看地址:https://github.com/cl ...

最新文章

  1. DCN-cs6200 ipv6 6to4隧道
  2. 【转修正】sql server行版本控制的隔离级别
  3. 在O(1)时间删除链表节点
  4. POSA2:Wrapper Facade模式
  5. 八. 输入输出(IO)操作6.文件与目录管理
  6. 李倩星r语言实战_《基于R的统计分析与数据挖掘》教学大纲
  7. 常用的mysql sql_mode
  8. 常用Openssl命令
  9. 地图图表、柱状图、条形图、折线图、中国地图、世界地图、省市地图、仪表盘、雷达图、饼图、散点图、气泡图、瀑布图、堆叠图、热力图、桑基图、关系图、漏斗图、Axure原型、rp原型、产品原型
  10. Spring boot入门(三):集成AdminLTE(Freemarker),结合generate代码生成器,利用DataTable和PageHelper分页...
  11. 快速了解java语言
  12. 非参数统计的Python实现—— Kruskal-Wallis 单因素方差分析
  13. 分享:20 本优秀的 Python 电子书
  14. 标定学习笔记(四)-- 手眼标定详解
  15. JAVA之父,詹姆斯·高斯林传奇人生
  16. 关键字synchronized与volatile详解
  17. 同学早已年薪百万 为何你却还在朋友圈集赞?
  18. 微计算机原理及应用第八章,微机原理第八章--8251讲解
  19. matplotlib报Unknown symbol: \rule, found ‘\‘ (at char 42), (line:1, col:43)
  20. 银行管理系统(c链表实现)

热门文章

  1. VScode+keil插件-取代keil开发不要太爽了
  2. 推荐关于PX4 ECL EKF方程推导的两篇“宝藏“文章
  3. Google Earth Engine(GEE)——GEE最全介绍(7000字长文)初学者福音!
  4. 人人都是钢铁侠,超级盔甲问世
  5. Eclipse软件使用教程
  6. 谷歌浏览器显示oracle,css让table不显示边框的代码在火狐和谷歌浏览器中无效
  7. 如何制定一个好计划?运用SMART原则
  8. Windows虚拟内存
  9. 首款搭载Tango技术的AR手机Phab2 Pro将在下月开售
  10. 利用网络,下载网络资源