序
本文主要研究一下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端的都是同一个领域服务提供能力,他们分开部署,也就解决了稳定性和隔离的问题,而代码层面,领域层面的能力是统一的。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。