dubbo之服务配置及启停

前言

dubbo之集群》一文所提到功能已经基本完善,dubbo如何进一步封装,使用之简单易用呢?

服务代理

通过《浅谈AOP》中的Javassist技术,dubbo为我们简化代码如下

public class ProxyTest {

    public static void main(String[] args) throws Exception {

        ServiceRepository repository = ApplicationModel.getServiceRepository();
        repository.registerService(GreetingsService.class);

        URL url = URL.valueOf("dubbo://127.0.0.1:28092/dubbo.GreetingsService?monitor=mm&timeout=12000");

        Protocol protocol = new ProtocolFilterWrapper(new DubboProtocol());

        protocol.export(new  JdkProxyFactory().getInvoker(new GreetingsServiceImpl(), GreetingsService.class, url));


        Invoker<GreetingsService> invoker = protocol.refer(GreetingsService.class, url);

        invoker = Cluster.getCluster(null, false).join(new StaticDirectory(Lists.newArrayList(invoker)));

        GreetingsService greetingsService = new  JdkProxyFactory().getProxy(invoker, new Class[]{ GreetingsService.class});

        System.out.println( greetingsService.sayHi("yoyo"));
    }
}

服务配置

dubbo进一步通过配置的形势缩小代码,demo如下

public class ConfigTest {

    public static void main(String[] args) throws InterruptedException {
        
        // 基本信息全局配置
        ConfigManager configManager = ApplicationModel.getConfigManager();
        configManager.setApplication(new ApplicationConfig("test"));

        // 注册中心全局配置
        RegistryConfig registryConfig  = new RegistryConfig("127.0.0.1", "zookeeper");
        registryConfig.setPort(2181);
        configManager.addRegistry(registryConfig);

        // 服务提供配置
        ServiceConfig<GreetingsService> serviceConfig = new ServiceConfig();
        serviceConfig.setInterface(GreetingsService.class);
        serviceConfig.setRef(new GreetingsServiceImpl());
        serviceConfig.export();

        // 服务调用配置
        ReferenceConfig<GreetingsService> referenceConfig = new ReferenceConfig();
        referenceConfig.setInterface(GreetingsService.class);
        referenceConfig.setProtocol("dubbo");
        GreetingsService greetingsService = referenceConfig.get();
        System.out.println(greetingsService.sayHi("rrrrrr"));
    }
}

除了上述JavaBean的启动方式dubbo还提供了spring的注解及配置文件方式完成以上配置。以配置文件方式为例子:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
     http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">

    <!--定义了提供方应用信息,用于计算依赖关系;在 dubbo-admin 或 dubbo-monitor 会显示这个名字,方便辨识-->
    <dubbo:application name="test"/>
    <!--使用 zookeeper 注册中心暴露服务,注意要先开启 zookeeper-->
    <dubbo:registry address="zookeeper://localhost:2181"/>
    <!-- 用dubbo协议在20880端口暴露服务 -->
    <dubbo:protocol name="dubbo" port="20880" />
    <!--使用 dubbo 协议实现定义好的 api.PermissionService 接口-->
    <dubbo:service interface="dubbo.GreetingsService" ref="greetingsServiceImpl" protocol="dubbo" />
    <!--具体实现该接口的 bean-->
    <bean id="greetingsServiceImpl" class="dubbo.GreetingsServiceImpl"/>

    <dubbo:reference id="greetingsService" interface="dubbo.GreetingsService"/>
</beans>
public class SpringDubboTest {

    public static void main(String[] args) throws InterruptedException {
        ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("spring-dubbo.xml");
        GreetingsService greetingsService = (GreetingsService) context.getBean("greetingsService");
        System.out.println(greetingsService.sayHi("oyooo"));
    }
}
  1. spring通过DubboNamespaceHandler类解析"dubbo"标签,分别对应
标签名称类名
dubbo:applicationApplicationConfig
dubbo:moduleModuleConfig
dubbo:registryRegistryConfig
dubbo:monitorMonitorConfig
dubbo:providerProviderConfig
dubbo:consumerConsumerConfig
dubbo:protocolProtocolConfig
dubbo:serviceServiceBean
dubbo:referenceReferenceBean
  1. service服务提供者启动流程
    在这里插入图片描述
  2. 消费者启动时
    在这里插入图片描述

ServiceRepository功能及属性

ServiceRepository是存储了所有服务端发布的服务、客户端需要访问的服务,通过ServiceRepository可以获取所有本dubbo实例发布的服务和引用的服务。

简而言之:就是你项目dubbo服务的元数据信息

ServiceRepository是通过ApplicationModel.getServiceRepository方法创建或者获取的。里面包括三个字段:services、consumers、providers。作用分别是:

  • services:类型是ConcurrentMap<String, ServiceDescriptor>,key是远程服务的接口名。
  1. ServiceDescriptor记录了服务接口的Class对象,接口名,服务接口每个方法的名字、入参类型、返回值类型等详细信息,可以理解为记录了远程服务接口的详细描述.
  2. 客户端、服务端在启动的时候都会调ServiceRepository.registerService方法将ServiceDescriptor对象注册到services中。下面两个属性需要的ServiceDescriptor对象也是从services中获取的。
  • consumers:类型是ConcurrentMap<String, ConsumerModel>,key是由服务接口+“:”+group+“:”+version组成的serviceKey.
  1. ConsumerModel中也有serviceKey,除了serviceKey之外还有ServiceDescriptor、ReferenceConfig对象、MethodConfig配置信息、可以访问远程服务提供者的Invoker对象。
  2. 在客户端启动的时候,dubbo会调用ReferenceConfig的init方法,在init方法里面调用ServiceRepository.registerConsumer方法,该方法会创建ConsumerModel对象,并将其注册到ServiceRepository中。
  3. 之后,dubbo可以访问该consumers属性,获取所有的客户端需要访问的远程服务信息。
  • providers:类型是ConcurrentMap<String, ProviderModel>,key是由服务接口+“:”+group+“:”+version组成的serviceKey.
  1. ProviderModel中也有serviceKey,除了serviceKey之外还有ServiceDescriptor、ServiceConfig对象以及对外提供服务的spring bean对象。
  2. 在服务端启动暴露服务的时候,dubbo会调用ServiceConfig的doExportUrls方法,在doExportUrls方法里面调用ServiceRepository.registerProvider方法,该方法会创建ProviderModel对象,并将其注册到ServiceRepository中。
  3. 之后,dubbo可以访问该providers属性,获取所有服务端发布的服务信息。

另外dubbo中也支持远程存储这些元数据,具体参考WritableMetadataService类

总结

  1. 服务启动时,先是服务准备好并且本地爆露完再向注册中心提交连接。
  • 防止过早的向注册中心写入,请求找不到服务.
  • @see RegistryProtocol.export
  1. 服务停止时,先是取消注册中心连接,然后等请求完成关闭
  • 阻止新请求过来,然后再等待正在运行的请求处理完成
  • @see RegistryProtocol.ExporterChangeableWrapper.unexport

主要参考

源码分析Dubbo前置篇-寻找注册中心、服务提供者、服务消费者功能入口
源码分析Dubbo服务消费端启动流程
源码分析Dubbo服务提供者启动流程

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值