从 MVC 到微服务,技术演变的必经之路

  API 的设计永远只有一次机会,特别是像七牛这类做对外服务的云服务厂商。API 设计完之后,一直都会有人调用,由于无法知道谁正在调用 API ,就无法让对方停用,从而无法升级。所以 API 只有一次机会,发布后就定了型。例如京东的部门不算多,但是 API 发布之后有很多部门在调用。团队做升级时,会通知所有部门停用 API 并且要升级的事情。但在升级完成之后,还是会有部门询问 API 为什么不通了?所以要符合可靠可用这两点,只有一次机会。

  API Gateway

  通常在企业里用的是 API Gateway ,因为它们可以直连。用这个方式有几个优点:

  一些通用的事情可以在 Gateway 上面做,包括所有API的请求调用量、请求响应时间、4xx 和 5xx 等错误出错数,这些东西可以通过日志或者其它方式很实时展现出来。

  所有的服务其实都需要负载均衡,可以在 API Gateway 统一做一些规则、限流。

  API 的设计要素

  版本号

  永远要清楚谁调了哪一个版本的 API 。虽然 API 发布只有一次机会,但有版本号之后能有所防备,做版本升级或版本兼容性的时候会更容易。

  RequstID

  RequstID 可以有效地提高效率,并在后台加快 Bug 复查和定位问题。给客户端的请求都有ID ,客户端发现有问题或者返回失败时,直接把 RequstID 给服务器端,服务器端拿 RequstID 到后台日志里查,就可以定义到问题。实际上从客户端发过来的一个请求,在后台经过了十几个微服务。而这十几个微服务调用的上下文串联和跟踪的工作,都需要一个 RequstID ,能够从请求端开始,往后去传递,每个人都要记录 RequstID ,出现问题时,把微服务的日志拉出来,就可以很快定位问题的来源。

  安全认证和 Signature

  要知道谁调了什么东西,并且保证被调的东西不被篡改。外部调动 API 时都会做安全认证,但是内部调用时不一定会做安全认证。但往往很多时候事情的发展都是出乎意料的,有可能因为老板的决定或者业务的变化,API 需要对外开放,如果前期做了安全认证,就可以避免很多麻烦。

  文档可读性

  一定要写好文档,不论是对客户、领导还是外部用户,文档写得漂亮更能彰显性能的优点。

  Error Code 和 Message 的问题

  以前有两个流派的 Error Code 和 Message 的展现方式。第一种是调用一个请求,对方把错误码写在 HTTP 的 Code 里面,可能用 400、404、409。第二种调法是客户端给服务端发了一个请求,返回 200,在 Body 里面有一个真正的 Code ,通过观察这个 Code 来判断调用是否成功,不成功就会通知 Error Message 。经过几年的实践后推荐使用第二种,因为在微服务相互调用时,它的协议不仅仅局限于 HTTP ,可能是其它方式的调用,直接用这个协议表示这种方式的调用状态并不合适,相反在里面表示一个状态会更好。

图 7

图 8

  做一个案例分析,如图 7 所示是一家公司的架构图,野蛮生长的时候更注意的是功能的效率。架构很简单,没有服务需要进行小拆分,都是放在一起形成一个大块整体。前期功能性开发很快,但到了一定阶段后,不管是调用效率还是开发效率都会显现出不足之处。所以进行一个拆分,把大块的拆成十几个、二十几个(如图 8 所示)。基本上每家在做架构升级时,都会把一堆大的东西拆成小的,即微服务;而把四个变六个,就是微服务的架构升级。

  然而在升级的过程中,也会存在一些「战争」,如下:

  效率与规则的战争。

  习惯与规范的战争。

  迭代与优化的战争。

  产品与开发的战争。

  业务爆发与服务能力的战争。

  业务爆发有两种:

  一种是用户量、请求量上来了,服务却跟不上;

  其次是是业务模式增加,需要开发更多的功能,但是开发更多功能时,却会导致服务能力和服务质量的下降。

  微服务变火的原因

  十年前的技术到近几年才开始变得很火的原因,需要从微服务的优劣势进行分析,主要是以下几个原因: