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


        推荐阅读
        • 本文介绍了Java并发库中的阻塞队列(BlockingQueue)及其典型应用场景。通过具体实例,展示了如何利用LinkedBlockingQueue实现线程间高效、安全的数据传递,并结合线程池和原子类优化性能。 ... [详细]
        • 优化ListView性能
          本文深入探讨了如何通过多种技术手段优化ListView的性能,包括视图复用、ViewHolder模式、分批加载数据、图片优化及内存管理等。这些方法能够显著提升应用的响应速度和用户体验。 ... [详细]
        • 本文将介绍如何编写一些有趣的VBScript脚本,这些脚本可以在朋友之间进行无害的恶作剧。通过简单的代码示例,帮助您了解VBScript的基本语法和功能。 ... [详细]
        • 1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ... [详细]
        • 深入理解Tornado模板系统
          本文详细介绍了Tornado框架中模板系统的使用方法。Tornado自带的轻量级、高效且灵活的模板语言位于tornado.template模块,支持嵌入Python代码片段,帮助开发者快速构建动态网页。 ... [详细]
        • PHP 5.2.5 安装与配置指南
          本文详细介绍了 PHP 5.2.5 的安装和配置步骤,帮助开发者解决常见的环境配置问题,特别是上传图片时遇到的错误。通过本教程,您可以顺利搭建并优化 PHP 运行环境。 ... [详细]
        • 1.如何在运行状态查看源代码?查看函数的源代码,我们通常会使用IDE来完成。比如在PyCharm中,你可以Ctrl+鼠标点击进入函数的源代码。那如果没有IDE呢?当我们想使用一个函 ... [详细]
        • 深入理解Cookie与Session会话管理
          本文详细介绍了如何通过HTTP响应和请求处理浏览器的Cookie信息,以及如何创建、设置和管理Cookie。同时探讨了会话跟踪技术中的Session机制,解释其原理及应用场景。 ... [详细]
        • 使用 Azure Service Principal 和 Microsoft Graph API 获取 AAD 用户列表
          本文介绍了一段通用代码示例,该代码不仅能够操作 Azure Active Directory (AAD),还可以通过 Azure Service Principal 的授权访问和管理 Azure 订阅资源。Azure 的架构可以分为两个层级:AAD 和 Subscription。 ... [详细]
        • 本文详细介绍了Java编程语言中的核心概念和常见面试问题,包括集合类、数据结构、线程处理、Java虚拟机(JVM)、HTTP协议以及Git操作等方面的内容。通过深入分析每个主题,帮助读者更好地理解Java的关键特性和最佳实践。 ... [详细]
        • 将Web服务部署到Tomcat
          本文介绍了如何在JDeveloper 12c中创建一个Java项目,并将其打包为Web服务,然后部署到Tomcat服务器。内容涵盖从项目创建、编写Web服务代码、配置相关XML文件到最终的本地部署和验证。 ... [详细]
        • 如何高效创建和使用字体图标
          在Web和移动开发中,为什么选择字体图标?主要原因是其卓越的性能,可以显著减少HTTP请求并优化页面加载速度。本文详细介绍了从设计到应用的字体图标制作流程,并提供了专业建议。 ... [详细]
        • Explore a common issue encountered when implementing an OAuth 1.0a API, specifically the inability to encode null objects and how to resolve it. ... [详细]
        • 本文介绍了如何使用JQuery实现省市二级联动和表单验证。首先,通过change事件监听用户选择的省份,并动态加载对应的城市列表。其次,详细讲解了使用Validation插件进行表单验证的方法,包括内置规则、自定义规则及实时验证功能。 ... [详细]
        • 作为一名新手,您可能会在初次尝试使用Eclipse进行Struts开发时遇到一些挑战。本文将为您提供详细的指导和解决方案,帮助您克服常见的配置和操作难题。 ... [详细]
        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社区 版权所有