当前位置:首页 > 短网址资讯 > 正文内容

微服务架构 API 的开发与治理

www.ft12.com7年前 (2017-08-24)短网址资讯2454
虽然已经红了很久,但是“微服务架构”正变得越来越重要,也将继续火下去。各个公司与技术人员都在分享微服务架构的相关知识与实践经验,但我们发现,目前网上的这些相关文章中,要么上来就是很有借鉴意义的干货,要么就是以高端的专业术语来讲述何为微服务架构。就是没有一个做到成熟地将技术传播出来,同时完美地照顾“初入微服务领域人员”,从 0 开始,采用通俗易懂的语言去讲解微服务架构的系列。所以,我们邀请青柳云的苏槐与 InfoQ 一起共建微服务架构专题“Re:从 0 开始的微服务架构”,为还没有入门该领域的技术人员开路,也帮助微服务架构老手温故知新。

这是专题的第三篇文章,聊聊内网环境中的 API 开发与治理

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

那么,在各个微服务之间具体怎么进行轻量级的通信呢?这篇文章就来聊聊微服务 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 好?》,几位大神讲得都挺好。

[http://www.ft12.com]

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 进行调用链管理


扫描二维码推送至手机访问。

版权声明:本文由短链接发布,如需转载请注明出处。

本文链接:https://www.ft12.com/article_431.html

分享给朋友:

相关文章

短网址服务开发关键问题与解决方案

一、背景分析二维码的出现使资源传输由原来的USB拷贝转变为二维码扫描访问或下载。为下载资源提供短网址服务,需将短网址生成二维码。资源数据量预计可达10亿级别,日新增数据1000万左右,每秒并发访问数预计2000个连接,响应时间在0.1秒以内...

58速运“里程计算”优化与演进

58速运“里程计算”优化与演进

58速运货物运输,滴滴快递网约车,司机端都是按照行驶公里数收费的,所以“里程”的准确性,是这类业务的一个核心难题,“里程计算”方案演进,以及其中优化思想,是本文要讨论的问题 一、直接调用地图API这是最容易想到的方法,最省事,但司...

FT12短网址教你如何快速定位不小心暴露的全局变量

FT12短网址教你如何快速定位不小心暴露的全局变量

今天在查看页面控制台的时候,无意中看到了一个暴露到全局的变量 i,全局变量是不会被压缩工具压缩成简写的字母,这个被频繁使用的变量名暴露到全局也是个相当大的隐患,可能一个不小心就覆盖了第二次暴露到全局的同名变量。刚开始我就怀疑是自己出现了这样...

ShortURL(短网址)系统逻辑是怎么设计的?

个人相关:三年前在公司做过一个短地址服务,目前在线上跑。 而这个问题,也是我现在招聘面试题里面必考的一道,这一道题里面有很多可考的地方,能够相对综合的考察候选人的功力。最烂的回答 实现一个算法,将长地址转成短地址。实现长和短一一对应。然后...

娃娃机和迷你KTV“躺着挣钱” 解密孤独消费的逻辑

周末,三里屯某商场,正是午饭之后的时间,一楼产品区购物者三三两两、若有寂静,但摆在商场入口的 4 个迷你KTV“包间”,却座无虚席。透过玻璃可以看到, 4 个包间里分别坐着情侣、一对女生、带着孩子的年轻爸爸妈妈,还有一位背影看起来有些寂寥的...

叫板微信 支付宝小程序正式公测

叫板微信 支付宝小程序正式公测

【亿邦动力网讯】8月18日消息,亿邦动力网获悉,支付宝小程序于昨日起正式开始公测。目前只有企业类型支付宝账号才能申请公测,申请通过后才可去开发者中心创建小程序。早在今年1月份,就有消息称支付宝小程序也正在开发中。在微信小程序面世的8个多月后...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。