本文主要研究一下admin服务的几种架构模式

分类

一般而言,一个服务提供的接口有的是C端用的,有的是给B端用的,还有的是给admin用的,对于admin服务该不该访问业务服务的数据库,这里通常会有很多分歧和实践模式。这里给admin服务的定义就是给admin后台系统的前端提供http接口的服务。

模式1: admin服务不能访问业务数据库

按微服模式的话,每个业务微服务都有独立的数据库,因而admin服务是不能访问业务微服务的数据库的,它只能是通过rpc的形式去编排和组装数据给到admin前端,具体示意如下:

模式2: admin服务访问业务数据库

这种模式的话,赋予了admin服务访问业务数据库的权限,其整体架构模式变成如下:

关于这种方式,有几种实现形式:

  • 形式1:admin与业务服务各自实现对数据库和service的访问
  • 形式2:把共用的dao和service抽取到common包,由admin及业务服务通过jar包依赖去共享

admin服务形式

不管是模式1还是模式2,这里的admin服务可能有几种形式

  • 形式1,是一个大的单体,即所有业务领域的admin接口都在这个单体里头
  • 形式2,每个业务领域都有自己的admin接口,最后通过网关统一提供给前端,对于前端来讲,使用跟形式1没有区别

模式1的形式2

模式2的形式2

在不是太复杂的业务场景或者是团队规模不大的场景,形式1是用的比较多的方式;而在比较复杂的业务以及大规模的团队里头,一般是形式2的方式,这样子可以避免多个团队的人在同一个工程去修改代码

点评

模式1和模式2在很多公司里头都有用

模式1优缺点

  • pros:微服务就是需要业务领域闭环,避免单体相互影响,而admin服务能访问业务领域的数据库就不太合理;

    若admin服务形式2的方式,由每个领域服务自己提供admin接口,那么数据库访问就相对可用了,还会有问题吗?
  • cons:这种方式即把领域能力从领域服务分离出去了,涉及到业务逻辑代码的泄露,有的会说如果我通过dao和service来共享呢,就不会造成分离,也不会造成代码重复,这种方式看起来是很巧妙,但是实际问题比较大,它的问题就是把包含业务逻辑的service通过jar共享出去了,其实本质上就是退回到单体服务了,很容易造成边界不清晰,代码其实也不太可读,一般jar包这种依赖是比较适合工具类或者框架层面的东西,比如spring security,而service这种它跟工具类或者框架类本质上不一样,它涉及到业务逻辑,会变更到业务数据,所以我们会比较关心哪些地方对它进行了调用,怎么调用,场景是怎么样,这些都是由领域服务自己控制,共享出去就失控了

模式2优缺点

  • pros:admin服务与C端接口服务不一样,分开的话,可以分开迭代,还可以进行隔离,即admin服务出问题(当然数据库慢查询等除外)不影响C端服务,可以保证C端服务的稳定性。
  • cons:如果admin服务采用的是形式2,但是还是造成领域逻辑分开到了不同服务,当然在某些场景是合适的,特别是C端服务与B端服务逻辑差异性太大,他们代码复用程度低,说到底其实是有潜在分化为不同子域的趋势。但如果是简单的业务场景,拷贝代码也是可以接受,但是共享service这个是不可取的,实际是倒退到了大单体大泥球

小结

模式1主要是从微服务开发的角度去考虑的,考虑领域逻辑闭环;模式2从服务部署及稳定性的角度去考虑的,是没错,但是具体做法有些会破坏微服务开发的原则,特别是service共用这种方式,假设是dao共享也是把数据库修改的权力扩散出去了,如果是每个微服务独立一个admin服务这种形式,影响还相对小一点,但是也存在领域逻辑可能扩散的问题,不好在同一地方维护,相当于得维护领域服务,还得维护领域admin服务的逻辑。

有没有更好的方式呢,综合模式1和模式2,有的,模式1和2的出发点都对,只是模式2的实现方式有点问题,我们期望的是领域逻辑闭环,而不同场景下领域服务能够隔离,其实模式2应该从部署层面去解决问题,而不是在微服务架构上去处理,也就是说其实我们可以对同一个微服务做不同场景的隔离部署,就解决问题了,比如对于C端、admin端的都是同一个领域服务提供能力,他们分开部署,也就解决了稳定性和隔离的问题,而代码层面,领域层面的能力是统一的。

codecraft
11.9k 声望2k 粉丝

当一个代码的工匠回首往事时,不因虚度年华而悔恨,也不因碌碌无为而羞愧,这样,当他老的时候,可以很自豪告诉世人,我曾经将代码注入生命去打造互联网的浪潮之巅,那是个很疯狂的时代,我在一波波的浪潮上留下...


引用和评论

0 条评论