热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

利用Dubbo的SPI扩展容器

在实际开发中,很多Dubbo的服务提供者都会运行在web容器上,如果提供者服务上同时对外

在实际开发中,很多Dubbo的服务提供者都会运行在web容器上,如果提供者服务上同时对外提供http服务的话,这么做是有必要的,但如果你的服务提供者只是对外提供dubbo服务的话,那么用web容器就有些重了,因为毕竟web容器主要是用来响应http请求以及静态页面的。如果单独作为dubbo服务提供者,只需要通过一个main方法加载一个简单的spring容器将服务暴露出去即可。
注:本文以dubbo的2.6.5版本为例
  • 一、Dubbo的内置容器

dubbo内置了三种容器
Log4jContainer:只是针对log4j配置文件做了处理。

LogbackContainer:只是针对logback日志配置文件做了处理。

SpringContainer:
它的start方法会创建ClassPathXmlApplicationContext容器,然后分别执行refresh方法和start方法刷,暴露dubbo服务;其stop方法会执行ClassPathXmlApplicationContext的stop及close方法。

可以看到,这三种容器,只有SpringContainer真正的加载了容器并暴露了服务,所以要用dubbo自带的容器的话,SpringContainer是必选的,可以单独使用,另外两个需要配合SpringContainer使用,但是如果要使用SpringContainer的话,你需要把配置文件放到指定的为止,因为源码中已经定义死了:

所以我们用的时候一般是通过实现Container接口来自定义一个容器,然后重写Main类通过Dubbo的SPI机制加载自定义的容器,这样可以自定义加载配置文件。
  • 二、自定义Container

  • 2.1、首先用idea新建一个基于maven的java项目,添加dubbo,zk等依赖,具体的项目创建过程略过。

  • 2.2、写一个接口和实现类,用来对外暴露

  • 2.3、添加spring配置文件,dubbo配置文件等

  • 2.4、定义一个容器类,实现Container接口

    package com.ayo;


    import com.alibaba.dubbo.container.Container;
    import com.ayo.util.PathUtil;
    import org.springframework.context.support.FileSystemXmlApplicationContext;


    /**
    * 自定义一个容器
    */
    public class CustomContainer implements Container{


    /**
    * spring容器上下文
    */
    static FileSystemXmlApplicationContext context;


    /**
    * 启动容器
    */
    public void start() {
    try {
    String path = PathUtil.getAppConfPath().concat(PathUtil.sp()).concat("spring.xml");
    cOntext= new FileSystemXmlApplicationContext(path);
    }catch (Exception e){
    e.printStackTrace();
    }
    }


    /**
    * 停止容器
    */
    public void stop() {
    try {
    if (context != null){
    context.stop();
    context.close();
    cOntext= null;
    }
    }catch (Exception e){
    e.printStackTrace();
    }
    }
    }

    • 2.5、在resources下建一个文件夹命名为META-INF,然后在META-INF下再建一个文件夹命名为dubbo,然后建立一个文件命名为com.alibaba.dubbo.container.Container,里面写上内容

    为什么要这么做?这就是Dubbo的SPI,不知道的可以看下,传送门:

    Dubbo的SPI、适配器原理、动态编译原理

    • 2.6、写一个Main类用于加载和启动自定义的Container

      package com.ayo;


      import com.alibaba.dubbo.common.extension.ExtensionLoader;
      import com.alibaba.dubbo.container.Container;
      import java.text.SimpleDateFormat;
      import java.util.Date;




      /**
      * 自定义dubbo容器
      *
      * @author ayo
      */
      public class Main {


      /**
      * dubbo优雅关机
      */
      public static final String SHUTDOWN_HOOK_KEY = "dubbo.shutdown.hook";


      private static volatile boolean running = true;


      public static void main(String[] args) {
      try {
      final Container customCOntainer= ExtensionLoader.getExtensionLoader(Container.class).getExtension("custom");
      //在dubbo优雅关机的时候会触发此钩子函数
      if ("true".equals(System.getProperty(SHUTDOWN_HOOK_KEY))) {
      Runtime.getRuntime().addShutdownHook(new Thread() {
      public void run() {
      try {
      customContainer.stop();
      System.out.println("Dubbo " + customContainer.getClass().getSimpleName() + " stopped!");
      } catch (Throwable t) {
      t.printStackTrace();
      }
      synchronized (Main.class) {
      running = false;
      Main.class.notify();
      }
      }
      });
      }
      customContainer.start();
      System.out.println("Dubbo " + customContainer.getClass().getSimpleName() + " started!");
      System.out.println(new SimpleDateFormat("[yyyy-MM-dd HH:mm:ss]").format(new Date()) + " Dubbo service server started!");
      } catch (RuntimeException e) {
      e.printStackTrace();
      System.exit(1);
      }
      synchronized (Main.class) {
      while (running) {
      try {
      Main.class.wait();
      } catch (Throwable e) {
      }
      }
      }
      }
      }

      • 2.7、运行Main类中的main方法

      • 2.8、看下服务有没有注册到zk

      • 2.9、写个dubbo消费者测试下接口是否正常

        package com.ayo;


        import com.alibaba.dubbo.config.ApplicationConfig;
        import com.alibaba.dubbo.config.ReferenceConfig;
        import com.alibaba.dubbo.config.RegistryConfig;
        import com.ayo.service.UserService;


        public class Consumer {


        public static void main(String[] args) {
        1.创建服务引用对象实例
        ReferenceConfig referenceCOnfig= new ReferenceConfig();


        2.设置应用程序信息
        ApplicationConfig applicatiOnConfig= new ApplicationConfig("dubbo-consumer");
        referenceConfig.setApplication(applicationConfig);


        //3.设置服务注册中心
        RegistryConfig registryCOnfig= new RegistryConfig("zookeeper://192.168.209.129:2181");
        referenceConfig.setRegistry(registryConfig);


        //3.设置服务接口和超时时间
        referenceConfig.setInterface(UserService.class);
        referenceConfig.setTimeout(5000);


        //5.引用服务
        UserService userService = referenceConfig.get();


        //6.调用服务
        System.out.println(userService.getUserName());
        }
        }

        需要demo的私我。


        推荐阅读
        • 深入解析SpringMVC核心组件:DispatcherServlet的工作原理
          本文详细探讨了SpringMVC的核心组件——DispatcherServlet的运作机制,旨在帮助有一定Java和Spring基础的开发人员理解HTTP请求是如何被映射到Controller并执行的。文章将解答以下问题:1. HTTP请求如何映射到Controller;2. Controller是如何被执行的。 ... [详细]
        • 本文介绍了如何利用 Spring Boot 和 Groovy 构建一个灵活且可扩展的动态计算引擎,以满足钱包应用中类似余额宝功能的推广需求。我们将探讨不同的设计方案,并最终选择最适合的技术栈来实现这一目标。 ... [详细]
        • 深入解析Redis内存对象模型
          本文详细介绍了Redis内存对象模型的关键知识点,包括内存统计、内存分配、数据存储细节及优化策略。通过实际案例和专业分析,帮助读者全面理解Redis内存管理机制。 ... [详细]
        • 深入理解 .NET 中的中间件
          中间件是插入到应用程序请求处理管道中的组件,用于处理传入的HTTP请求和响应。它在ASP.NET Core中扮演着至关重要的角色,能够灵活地扩展和自定义应用程序的行为。 ... [详细]
        • 我有一个SpringRestController,它处理API调用的版本1。继承在SpringRestControllerpackagerest.v1;RestCon ... [详细]
        • 简化报表生成:EasyReport工具的全面解析
          本文详细介绍了EasyReport,一个易于使用的开源Web报表工具。该工具支持Hadoop、HBase及多种关系型数据库,能够将SQL查询结果转换为HTML表格,并提供Excel导出、图表显示和表头冻结等功能。 ... [详细]
        • 深入解析Spring启动过程
          本文详细介绍了Spring框架的启动流程,帮助开发者理解其内部机制。通过具体示例和代码片段,解释了Bean定义、工厂类、读取器以及条件评估等关键概念,使读者能够更全面地掌握Spring的初始化过程。 ... [详细]
        • 科研单位信息系统中的DevOps实践与优化
          本文探讨了某科研单位通过引入云原生平台实现DevOps开发和运维一体化,显著提升了项目交付效率和产品质量。详细介绍了如何在实际项目中应用DevOps理念,解决了传统开发模式下的诸多痛点。 ... [详细]
        • Kubernetes 持久化存储与数据卷详解
          本文深入探讨 Kubernetes 中持久化存储的使用场景、PV/PVC/StorageClass 的基本操作及其实现原理,旨在帮助读者理解如何高效管理容器化应用的数据持久化需求。 ... [详细]
        • 本文作者分享了在阿里巴巴获得实习offer的经历,包括五轮面试的详细内容和经验总结。其中四轮为技术面试,一轮为HR面试,涵盖了大量的Java技术和项目实践经验。 ... [详细]
        • 阿里云ecs怎么配置php环境,阿里云ecs配置选择 ... [详细]
        • Netflix利用Druid实现高效实时数据分析
          本文探讨了全球领先的在线娱乐公司Netflix如何通过采用Apache Druid,实现了高效的数据采集、处理和实时分析,从而显著提升了用户体验和业务决策的准确性。文章详细介绍了Netflix在系统架构、数据摄取、管理和查询方面的实践,并展示了Druid在大规模数据处理中的卓越性能。 ... [详细]
        • 本文深入探讨了SQL数据库中常见的面试问题,包括如何获取自增字段的当前值、防止SQL注入的方法、游标的作用与使用、索引的形式及其优缺点,以及事务和存储过程的概念。通过详细的解答和示例,帮助读者更好地理解和应对这些技术问题。 ... [详细]
        • 主板IO用W83627THG,用VC如何取得CPU温度,系统温度,CPU风扇转速,VBat的电压. ... [详细]
        • PostgreSQL 最新动态 —— 2022年4月6日
          了解 PostgreSQL 社区的最新进展和技术分享 ... [详细]
        author-avatar
        手机用户2502941011
        这个家伙很懒,什么也没留下!
        PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
        Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有