-
Notifications
You must be signed in to change notification settings - Fork 2.2k
新版Dubbo Admin技术文档
- Domain Model:Dubbo的领域模型,分为Application(应用),Service(服务),Instance(实例)以及ConditionRule等流量规则。
- Console,符合Gin标准的web handler和service
- Manager:从上层来看:屏蔽数据存储层的差异,提供统一的CURD接口;对下层:读写分离,可以对多个store进行路由
- Cache: 具有业务属性的缓存。
- Discovery:数据源的一部分,定位为RPC服务发现组件(即注册中心),可以获取RPC的相关信息,如Zookeeper,Nacos
- Engine:数据源的一部分,定位为实例的运行基础设施,可以获取实例相关的运行信息,如Kubernetes,Docker
- Store:key-value类型的数据存储,为每种Domain Model提供持久化的能力
- Indexer:索引,为上层提供不同资源的索引
在Dubbo Admin中,所有的领域模型均由proto来定义,经过一层包装后就成为了一种Resource, Dubbo Admin中定义的Resource是符合Kubernetes Object标准的。
以Instance为例,我们使用proto定义instance,然后使用resourcegen将Instance作为spec嵌入到InstanceResource中:

PS: 如何使用工具来更新/新增领域模型请看开发者指南
Dubbo 的关键领域模型如上图所示,核心是Application(应用),Instance(实例),Service(服务)。此外,路由规则也在流量治理中发挥重要的作用。
Dubbo Admin中的Resource从业务属性上来可以划分为原子资源和组合资源。原子资源对应的是discovery/engine侧watch到的资源,这些资源能够映射到Dubbo Admin中的某个领域模型的部分属性,比如RuntimeInstance;而组合资源则是由多个原子资源的属性组合而来,比如Instance就是由RPCInstance和RuntimeInstance组合而来。
对于admin控制台前端来说,大部分情况下一个页面都是映射到组合资源的,因此查询时如何查出来组合资源就自然分为两种方式:
- 在查询时,根据一个key查询多个原子资源,然后再合并为组合资源,返回给前端。这种方式的优点是组合资源不占用存储,缺点也显而易见,查询时会相当复杂。
- 在原子资源落库后,通过EventBus来异步(这里的异步指的是和查询流程异步)更新组合资源,前端查询时直接查组合资源即可。这种方式就是查询的时候会非常简洁,效率也很高,缺点就是异步事件流是一环套一环的,数据之间的级联更新往往debug困难。 考虑到用户体验,目前admin的【原子资源合并为组合资源】的绝大部分场景采用的还是第二种方案。开发者们在面对组合资源时,先考虑查询时是否复杂,如果查询复杂,则采用异步的方案,如果在查询的过程中合并比较简单,则可以考虑第一种方案。
图例:

路由规则的异步更新链路:

metadata的异步更新链路:

rpc instance的异步更新链路:

Dubbo Admin中的模块通过Component来进行定义,Component定义了一个标准模块需要有的属性和方法,一旦有了这些属性和方法,通过runtime.RegisterComponent就能够将Component注册到runtime中,从而在启动时能够以标准的运行方式在一个单独的协程中运行。
Admin的核心模块包括如下几部分:EventBus,Store,Discovery,Engine。
- EventBus:事件中转站。Admin中最常用的场景是当AResource发生变化时,发送一个AResource更新的事件,BResource需要根据AResource的更新进行联动更新。
- Store: 持久化层。对Resource进行CURD操作。
- Discovery:对注册中心(如zookeeper, nacos等)进行封装,监听注册中心的变化,将注册中心的事件转化成admin的领域模型,并持久化到store中。
- Engine:对运行引擎(kubernetes, docker compose等)进行封装,监听运行引擎的变化,将运行引擎的事件转化成admin的领域模型,并持久化到store中。
- Console:与前端控制台打交道的web层,可细分为handler和service。
Discovery 和 Engine从本质上来说其实都是一个list-watch模型。不同的是,Discovery watch的数据源一般是注册中心如zk,nacos等,而Engine watch的一般是应用运行引擎如kubernetes,docker compose, vm等。kubernetes中提供了client-go来抽象并实现了list watch这个机制:

- Reflector: ListWatch k8s apiserver,监听指定类型的变更事件,将变更信息push 到 Delta FIFO队列中
- Informer: 从 Delta FIFO 读出事件,调用Indexer,完成持久化,并分发事件
- Indexer:内存索引&存储代理,依托KeyFunc维护索引,调用store的方法后需要更新索引
- Store: 存储层,key-value类型的存储结构,client-go中已有memory实现
我们可以将admin中的一些组件映射到上面这张图,Indexer和Store和上图中的组件的定位一模一样,从接口上来说,基本可以复用。而Discovery和Engine从定位上则包含了Reflector,Queue,Informer这几个组件,即包含了从指定数据源进行ListWatch,队列缓冲,事件分发,再调用Indexer完成持久化这一过程。因此Discovery和Engine的大框架就完全复用client-go中的Infomer。
