前端微服务化

从模块化到微服务化

Posted by stefan on April 4, 2017

之前的设想

「理想总是高于现实」,这tmd大概说的就是我们现在cloudwood的代码。

在规划目录结构和业务流之前,我是这么想的,大概用下图可以表示:

1.png

有两点需要说明下:

  1. 为啥要用多Express实例来区分PC/Mobile(NA)/H5,而不是纯靠路由区分,原因在于:

    • 错误隔离、因为不同的Express可以控制在实例内部报错,业务之间不会相互影响;

    • 配置隔离,因为不同的Express可以使用自己的配置,比如模板类型、静态资源目录等。

  2. 为啥API要单独设计?因为我们API除了对外提供服务,还要为内部其他子系统(Express)提供数据相关的工具方法。

当然,这一切的前提是我们使用了一套BaaS服务,为了方便,我们没有在物理层面进行服务拆分,只是在代码模块层面做了拆分。

但是,即便是这样,模块也没分好。。。

  • 本来设计的是util模块(一个独立模块)里放纯粹的工具方法(比如JSON处理、时间处理)等,但是现在里面却塞了大量的跟业务耦合的代码;

  • API被纯粹当成了Restful HTTP 接口,完全没体现出来内外分离的感觉;

  • Express实例之间尽然出现相互引用;

  • 作为最外层挂载器的Base Express,原本设计的意义在于处理全局错误和全局(400、500)handler,结果却变成了业务池,注入了大量代理代码(代理到HTTP)。

所以,现在的cloudwood惨不忍睹。

我们该怎么办

微服务改造 + subtree。

说白了就是要把之前耦合在一起的代码拆成独立的服务,把之前共有依赖的本地调用拆分为subtree模块:

2.png

那么,什么情况下拆分成独立的服务,什么情况下拆分为独立的供他人嵌入的subtree模块。判断方法很简单:

如果这个模块纯粹依赖特定输入提供特殊输出,需要以HTTP的方式对外提供服务,那么就拆分为服务;如果这个模块只是提供通用处理的方法,不需要和业务数据打交道,那么就拆分为subtree。

这样看来,之前的Internal API、util比较适合于拆分为subtree模块,Express实例可以拆分为服务。

当然,服务是可以嵌套的,我们做的第一步是要先拆除去,然后再说……