Re:从 0 开始的微服务架构--(三)微服务架构 API 的开发与治理--转

原文来自:聊聊架构公众号git

前面的文章中有说到微服务的通讯方式,Martin Folwer 先生在他对微服务的定义中也提到“每一个服务运行在其独立的进程中,服务与服务间采用 轻量级的通讯机制 互相协做(一般是基于 HTTP 协议的 RESTful API)”。程序员

那么,在各个微服务之间具体怎么进行轻量级的通讯呢?这篇文章就来聊聊微服务 API 开发及治理的几个方面。github

首先须要解释一下,标题中的“内网环境中 的 API”指的是提供给内网里的其它微服务调用的 API。与其相对应的是“开放给互联网 用户调用的 API”,它们的开发方法大致相同,但治理方法却不太同样。api

例如开放给互联网用户调用的 API 须要在 API 网关上加上受权、鉴权、限流、限并发、统计、计费等等功能。架构

本篇文章分享的是内网环境中的 API 开发及治理。并发

API 开发框架

API 开发,首先考虑的就是该用什么样的协议,是 HTTP API 仍是 RPC?微服务

咱们先来介绍一下这两种 API 类型:工具

 HTTP API性能

HTTP API 指的是简单的基于 HTTP 协议的 API,具体的例子就是 Spring MVC 的 Controller,例如 

http://127.0.0.1/helloworld/myapi.do”

 RPC

RPC 就是 Remote Procedure Call,中文名远程过程调用,在 API 调用的场景下,大多指的是基于 Socket 通讯方法的远程调用(固然,咱们也可使用 HTTP 协议来实现 RPC 调用,例如 gRPC)。Json-RPC 和 Xml-RPC 指的是使用 Json 或 Xml 做为文本格式的方式传输命令和数据。

那么回到刚才那个问题,到底要使用 HTTP API 仍是 RPC 呢?咱们之所要对比 HTTP API 和 RPC,主要是由于你们都知道 HTTP 简单,而基于 Socket 的 RPC 性能更好

这个问题咱们纠结了好久,直到后来,想明白了下面两件事,最终决定在绝大部分场景中使用 HTTP API。

HTTP API 的性能足以支撑大多数项目

一般来说(根据资料),算上序列化的时间,RPC 协议的吞吐量是 HTTP 性能 两倍(没有亲测),例如 Protobuf、Thrift、Kyro、Dubbo 等等。

这里面,又以 Thrift 的性能最高。具体的性能测试报告能够参考《RPC 框架性能基本比较测试》。

咱们团队在结合自身技术栈、成本、稳定性、易用性、可维护性、业务场景等等因素综合考虑后,以为咱们面临的大多数场景中,HTTP 和 RPC 的性能差异并非主要问题

再加上下图所示的 HTTP 性能测试结果做为佐证,咱们彻底能够采用 HTTP API 的方式来进行微服务 API 开发。

再者,当业务发展到必定的程度,若是某些业务功能的性能压力变大时,咱们仍是可使用 RPC 小范围地进行改造。这也是符合敏捷思想的一个决定。

下图是对 helloworld 页面进行 10000 次连续请求的测试结果,总耗时 1.504 秒,平均每一个请求耗时 0.15 毫秒。

测试环境:原生 Tomcat7(没有任何优化)运行在本地虚拟机上

下面是对 helloworld 页面以 100 并发数进行 10 万次请求的测试结果,平均每一个请求耗时 11.9 毫秒。

测试环境:原生 Tomcat7(没有任何优化)运行在本地虚拟机上

因此,按照上面的测试结果,HTTP API 方式的性能彻底足以支撑绝大多数的微服务 API 开发。让咱们把 RPC 方式留给那些可能出现双十一业务量的大型互联网公司去玩

RESTful API 适用于开放 API 的场景

这是另外一个折磨人的问题。相对于 HTTP API,RESTful API 在 HTTP API 的基础上增长了一些很是抽象晦涩的概念,例如资源(Resource)、表述(REpresentation)、状态转移(State Transfer)、统一接口(Uniform Interface)……。

在经历了一次又一次的折磨,例如“login/logout 是什么 RESTful 方法?”、“批量删除该怎么实现?”、“RESTful 的 resource 究竟该怎么定义?”以后,愈来愈感受这是一个形而上学的问题,太过于抽像。

咱们不应盲从于时髦的技术,须要加上技术人的基于自身状况的理性思考。因此,RESTful 虽好,但不是咱们团队的菜。

再者,即便团队中有些人能够理解并正确地实践,也很难或者说不可能让整个团队来正确地实践这样一种方法。

因此,咱们在一番挣扎后,选择了 HTTP API 方式,原来怎么开发,如今仍是怎么开发,把主要精力放到了 API 的监控和治理上面。

这里推荐你们看看知乎上的这篇讨论 《WEB 开发中,使用 JSON-RPC 好,仍是 RESTful API 好?》,几位大神讲得都挺好。

[https://www.zhihu.com/question/28570307]

API 治理API 文档

API 存在的意义在于有人调用它,若是调用方在调用 API 的时候很麻烦,甚至不能正确地调用,那么团队内部及团队之间的沟通成本及配合程度就会大受影响。

咱们是经过文档来沟通的,项目开始的时候还好,但随着时间的推移,文档的更新变得不是那么及时(这实际上是个自我辩解的说法,事实是大部分状况下文档都不更新了),API 变动时,也不容易找出哪些模块调用了这个 API。

因此,得先解决 文档不及时更新 的问题。虽然咱们能够经过流程管理的方式来强制你们更新文档,但这对于开发人员来讲,显然是不够科学或人性化的,由于变动一个 API,就要在两个地方进行修改,一是 API 代码,二是 API 文档,程序员的思惟就得在代码和文档之间不断切换,工做效率必然受影响。

咱们就想,能不能只须要在同一个地方修改,若是能作到,API 文档的更新就没有那么麻烦了,于人于已都是好事。

通过调研,咱们选择使用 Swagger 来编写文档,按照 Swagger 的规范,在 API 上加一些描述性的 Annotation 就能够了。

经过以上的 Annotation,将自动生成如下在线 API 文档。

调用方能够在 API 文档界面填入参数并点击“Try it out!”按钮尝试调用这个 API。这样,在没有 API 提供方支持的状况下,便可以自行完成绝大部分的 API 调用,是否是很爽?

调用链管理

API 开发出来了,API 文档也写好了,接下来就是被调用了。前篇文章讲到,经过 Spring Cloud 的 Eureka + Ribbon + Zuul 能够很方便地调用到这些 API。

那么,如何来追踪 API 被谁调用了,调用是否出错及出错缘由,调用链路里各个 API 的性能怎么样,是否是存在僵尸 API……这些都是关于 API 治理的问题。

实现这个目标,有一个比较取巧的方法,就是在 Ribbon 的客户端里作点文章,在调用 API 以前记录一下开始时间,API 调用返回后,记录 API 调用耗时、调用状态,若是有错则记录一下错误缘由。

若是还想追踪调用链,能够在请求头里加上一个调用链 ID,这样就来把调用关系都串连起来。

下边是咱们本身研发的调用链管理组件(DCTrace)的几个效果图:

查看微服务之间的调用关系,调用性能

查看调用失败缘由

图形化查看调用关系,太乱 ,下次迭代改进一下 [摊手]

站在技术管理者的角度,能够从调用链里看出来,哪些模块之间发生了不正当关系 [噗嗤];哪些模块之间本该有关系的,事实却没有;经过对比 Swagger 和调用链的 API 清单,找出僵尸 API……

API 测试

使用微服务架构后,API 是每一个微服务的 惟一能力出口。因为互联网行业的快速发展,软件需求变动变得愈来愈频繁,迭代升级的速度变得愈来愈快。

对于提供方来讲,须要保证变动和迭代的过程当中,不影响以前承诺的功能(包括正确性、稳定性和性能等)。

对于调用方来讲,一样须要确保自身依赖的 API 能正常使用,不能由于其它模块的错误而致使自身业务受到影响(包括正确性、稳定性和性能等)。

毕竟,从组织角度来看,系统出错就是出错,无论缘由是自身致使的仍是服务提供方致使的,因此 服务调用方就须要对服务提供方进行管理

这也就是前几年契约测试(Pact)方法大行其道的缘由。有兴趣的朋友能够去看看这种测试方法。

对于 API 白盒测试,推荐使用基于 Java 的 REST-Assured 测试框架,用起来特别方便。

[https://github.com/rest-assured/rest-assured]

更进一步,基于 HTTP 协议、JSON/XML 报文的规范性,彻底能够开发一个 API 测试小工具(暂且叫它 小鹰 吧)来替换 REST-Assured。咱们也暂未实践,只是以为会颇有用,供你们参考。

基础步骤是:

  1. 服务提供方开发 API,并正确书写 Swagger 文档。

  2. 服务提供方在小鹰的界面上选择须要测试的 API,并填写测试参数。(API 清单和参数均可以经过调用 Swagger 的 API 获取)

  3. 服务调用方根据自已的理解,也将对本身有用的服务方提供的 API 配置到小鹰上。

  4. 小鹰 7*24 小时为服务提供方和调用方巡视这些 API,并在异常出现时发送警报。

总   结

因此,对于微服务 API 开发,咱们

  • 使用最多见的技术(例如 Spring MVC)进行 API 开发

  • 使用 REST-Assured(以及将来的 小鹰)进行测试

  • 使用 Swagger 来管理 API 文档

  • 使用自研的 DCTrace 进行调用链管理

相关文章
相关标签/搜索