[apache/dubbo]关于ScopeModel的设计疑惑

2024-06-24 295 views
2

在Dubbo3.x版本中,引入了ScopeModel设计。 我看到ScopeMode设计的结构是 FrameworkModel(1) / \ ApplicationModel ApplicationModel / \
ModuleModel ModuleModel

但是基于我对Dubbo的了解,目前Dubbo服务提供方都只是一个应用对应一个ApplicationModel,以及一个ModuleModel。 不太明白为什么设计成1对多的关系。

我的猜想: 是不是为了考虑下面这种情况才设计的? 比如发布一个user-service服务,在Dubbo内部只会存在下面两个ApplicationModel。

  • DUBBO_INTERNAL_APPLICATION
  • user-service

回答

9

同问

3

FrameworkModel -> ApplicationModel -> ModuleModel,中间的映射都是 1:N 的

抽象这三个能力是为了实现 Dubbo 的多实例支持,FrameworkModel 是实现类似 JVM 租户级别的隔离,ApplicationModel 是为了实现一个机器上发布多个应用(如 demo-application1 和 demo-application2 一起发布),ModuleModel 是为了实现服务生命周期的独立管理(如一个 demo-application 可以由多个 Spring 容器共同提供)。

所以一个 Dubbo 服务是对应到 ModuleModel 上的。

举一个复杂一些的例子,比如:

目前需要发布 DemoInterface1、DemoInterface2、DemoInterface3、DemoInterface4 四个服务 订阅 DemoService1、DemoService2、DemoService3、DemoService4 四个服务

其中 DemoInterface1 和 DemoInterface2 由 demo-application-1 这个应用名发布(而且由 2 个 Spring Context 分别管理),DemoInterface3 和 DemoInterface4 demo-application-2 这个应用名发布 ,DemoService1、DemoService2、DemoService3、DemoService4 由 demo-application-3 这个应用名订阅。此外出于多租户的考虑,DemoInterface1、DemoInterface2、DemoInterface3、DemoInterface4 在 20880 端口和 20881 端口都独立发布,这 8 个服务(多租户 2 * 4 个服务)的实现都不一样。

那么实际上 Scope 的层级结构是:

FrameworkModel (1) -> ApplicationModel (1.1 demo-application-1) -> ModuleModel (1.1.1 Spring Context 1) -> DemoInterface1 (bind on 20880)
FrameworkModel (1) -> ApplicationModel (1.1 demo-application-1) -> ModuleModel (1.1.2 Spring Context 2) -> DemoInterface2 (bind on 20880)
FrameworkModel (1) -> ApplicationModel (1.1 demo-application-2) -> ModuleModel (1.2.1 Spring Context) -> DemoInterface3 (bind on 20880)
FrameworkModel (1) -> ApplicationModel (1.1 demo-application-2) -> ModuleModel (1.2.1 Spring Context) -> DemoInterface4 (bind on 20880)
FrameworkModel (1) -> ApplicationModel (1.1 demo-application-3) -> ModuleModel (1.3.1 Spring Context) -> DemoService1
FrameworkModel (1) -> ApplicationModel (1.1 demo-application-3) -> ModuleModel (1.3.1 Spring Context) -> DemoService2
FrameworkModel (1) -> ApplicationModel (1.1 demo-application-3) -> ModuleModel (1.3.1 Spring Context) -> DemoService3
FrameworkModel (1) -> ApplicationModel (1.1 demo-application-3) -> ModuleModel (1.3.1 Spring Context) -> DemoService4

FrameworkModel (2) -> ApplicationModel (2.1 demo-application-1) -> ModuleModel (2.1.1 Spring Context 1) -> DemoInterface1 (bind on 20881)
FrameworkModel (2) -> ApplicationModel (2.1 demo-application-1) -> ModuleModel (2.1.2 Spring Context 2) -> DemoInterface2 (bind on 20881)
FrameworkModel (2) -> ApplicationModel (2.1 demo-application-2) -> ModuleModel (2.2.1 Spring Context) -> DemoInterface3 (bind on 20881)
FrameworkModel (2) -> ApplicationModel (2.1 demo-application-2) -> ModuleModel (2.2.1 Spring Context) -> DemoInterface4 (bind on 20881)
FrameworkModel (2) -> ApplicationModel (2.1 demo-application-3) -> ModuleModel (2.3.1 Spring Context) -> DemoService1
FrameworkModel (2) -> ApplicationModel (2.1 demo-application-3) -> ModuleModel (2.3.1 Spring Context) -> DemoService2
FrameworkModel (2) -> ApplicationModel (2.1 demo-application-3) -> ModuleModel (2.3.1 Spring Context) -> DemoService3
FrameworkModel (2) -> ApplicationModel (2.1 demo-application-3) -> ModuleModel (2.3.1 Spring Context) -> DemoService4

上述所有服务独立工作,互相不影响

这一块需要出一个具体的文档来说明(#10831)

8

嗯,了解, Dubbo3目前还没支持多实例功能对吧。

0

嗯,了解, Dubbo3目前还没支持多实例功能对吧。

目前支持的了

2

没有找到相关文档的介绍,麻烦提供一下文档说明的地址哈,感谢!

9

好的。

8

@AlbumenJ 基于对ScopeModel的理解,我尝试的写了一个Demo,你看下是不是这样的一个使用场景。

public class ProviderMain {
    public static void main(String[] args) throws InterruptedException {
        // 服务提供者暴露服务配置
        ServiceConfig<IHelloService> helloServiceConfig = new ServiceConfig<>();
        helloServiceConfig.setInterface(IHelloService.class);
        helloServiceConfig.setRef(new HelloService());
        // 通过DubboBootstrap简化配置组装,控制启动过程
        DubboBootstrap.getInstance()
                .application("dubbo-sdk-provider") // 应用配置
                .registry(new RegistryConfig("zookeeper://192.168.8.133:2181?timeout=20000&blockUntilConnectedWait=30")) // 注册中心配置
                .protocol(new ProtocolConfig("dubbo")) // 全局默认协议配置
                .service(helloServiceConfig) // 添加ServiceConfig
                .start();   // 启动Dubbo

        ServiceConfig<IModelService> modelServiceConfig = new ServiceConfig<>();
        modelServiceConfig.setInterface(IModelService.class);
        modelServiceConfig.setRef(new ModelService());
   //在同一个FrameworkModel中创建多个ApplicationModel
        ApplicationModel applicationModel=new ApplicationModel(FrameworkModel.defaultModel());
        applicationModel.setModelName("test-sdk-provider");
        DubboBootstrap.getInstance(applicationModel).registry(new RegistryConfig("nacos://192.168.8.133:8848"))
                .application("test-sdk-provider")
                .protocol(new ProtocolConfig("dubbo"))
                .service(modelServiceConfig)
                .start().await();
    }
}
1

这个例子里面的 ServiceConfig 改成 ReferenceConfig 就是没问题的。同一个接口(interface、version、group都一样)在同一个 Framework 底下是不行的,因为一个 dubbo 端口只能发布一次一个服务,如果发布多个会导致调用的时候不知道选哪个。