热门标签 | 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的私我。


        推荐阅读
        • 实体映射最强工具类:MapStruct真香 ... [详细]
        • 深入解析 Apache Shiro 安全框架架构
          本文详细介绍了 Apache Shiro,一个强大且灵活的开源安全框架。Shiro 专注于简化身份验证、授权、会话管理和加密等复杂的安全操作,使开发者能够更轻松地保护应用程序。其核心目标是提供易于使用和理解的API,同时确保高度的安全性和灵活性。 ... [详细]
        • 探讨如何真正掌握Java EE,包括所需技能、工具和实践经验。资深软件教学总监李刚分享了对毕业生简历中常见问题的看法,并提供了详尽的标准。 ... [详细]
        • Startup 类配置服务和应用的请求管道。Startup类ASP.NETCore应用使用 Startup 类,按照约定命名为 Startup。 Startup 类:可选择性地包括 ... [详细]
        • ssm框架整合及工程分层1.先创建一个新的project1.1配置pom.xml ... [详细]
        • 尾花|花萼_相关性Correlations 皮尔逊相关系数(pearson)和斯皮尔曼等级相关系数(spearman)
          尾花|花萼_相关性Correlations 皮尔逊相关系数(pearson)和斯皮尔曼等级相关系数(spearman) ... [详细]
        • DWR(Direct Web Remoting)是一个用于简化Web应用中JavaScript与Java服务器端交互的Ajax库。本文通过一个简单的示例,展示如何使用DWR框架实现基本的Ajax功能。 ... [详细]
        • 优化ListView性能
          本文深入探讨了如何通过多种技术手段优化ListView的性能,包括视图复用、ViewHolder模式、分批加载数据、图片优化及内存管理等。这些方法能够显著提升应用的响应速度和用户体验。 ... [详细]
        • 1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ... [详细]
        • 本文详细介绍了 Dockerfile 的编写方法及其在网络配置中的应用,涵盖基础指令、镜像构建与发布流程,并深入探讨了 Docker 的默认网络、容器互联及自定义网络的实现。 ... [详细]
        • 本文详细介绍了如何使用Spring Boot进行高效开发,涵盖了配置、实例化容器以及核心注解的使用方法。 ... [详细]
        • 本文详细分析了Hive在启动过程中遇到的权限拒绝错误,并提供了多种解决方案,包括调整文件权限、用户组设置以及环境变量配置等。 ... [详细]
        • Hadoop入门与核心组件详解
          本文详细介绍了Hadoop的基础知识及其核心组件,包括HDFS、MapReduce和YARN。通过本文,读者可以全面了解Hadoop的生态系统及应用场景。 ... [详细]
        • 本文探讨了大型服务端开发过程中常见的几个误区,包括异步任务处理不当、日志同步模式使用、网络操作未设置超时、缓存命中率及响应时间未统计、单一缓存模式、分布式缓存加锁不当以及团队管理上的误区,旨在帮助开发者避免这些常见错误。 ... [详细]
        • 日志记录对于软件开发至关重要,特别是在调试和维护阶段。通过日志,开发者能够追踪错误源头并了解系统的运行状态。本文将探讨如何在Django框架中有效配置和使用日志记录功能。 ... [详细]
        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社区 版权所有