• dubbo初步认识


      dubbo中文网站:http://dubbo.apache.org/zh-cn/

      dubbo英文网站:http://dubbo.apache.org/en-us/

    1.Apache Dubbo是一款高性能Java RPC框架

      Apache Dubbo (incubating) |ˈdʌbəʊ| 是一款高性能、轻量级的开源Java RPC框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。

      其结构图如下:

    角色说明:

    Provider      暴露服务的服务提供方
    Consumer  调用远程服务的服务消费方
    Registry      服务注册与发现的注册中心
    Monitor       统计服务的调用次数和调用时间的监控中心
    Container   服务运行容器

    调用关系说明:

    服务容器负责启动,加载,运行服务提供者。
    服务提供者在启动时,向注册中心注册自己提供的服务。
    服务消费者在启动时,向注册中心订阅自己所需的服务。
    注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。
    服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
    服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。

      中文图:

      

    RPC--远程过程调用协议:

      RPC(Remote Procedure Call)—远程过程调用,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。RPC协议假定某些传输协议的存在,如TCP或UDP,为通信程序之间携带信息数据。在OSI网络通信模型中,RPC跨越了传输层和应用层。RPC使得开发包括网络分布式多程序在内的应用程序更加容易。

      RPC采用客户机/服务器模式。请求程序就是一个客户机,而服务提供程序就是一个服务器。首先,客户机调用进程发送一个有进程参数的调用信息到服务进程,然后等待应答信息。在服务器端,进程保持睡眠状态直到调用信息的到达为止。当一个调用信息到达,服务器获得进程参数,计算结果,发送答复信息,然后等待下一个调用信息,最后,客户端调用进程接收答复信息,获得进程结果,然后调用执行继续进行

      RPC类似于webservice,将服务发布为一个service。如果需要我们可以在普通的项目中使用RPC机制,RPC存在commons包中。

       关于RPC的认识参考另一篇hadoop中的使用:https://www.cnblogs.com/qlqwjy/p/9087727.html

    2、dubbo快速入门

      一款dubbo管理项目(monitor管理器),基于web项目,部署在tomcat下面即可运行访问,默认用户名和密码都是root。https://github.com/qiao-zhi/springboot/blob/master/dubbo-admin-2.5.4.war

    pom.xml

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <groupId>cn.qlq</groupId>
        <artifactId>zookeper</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <dependencies>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.12</version>
            </dependency>
            <dependency>
                <groupId>org.apache.zookeeper</groupId>
                <artifactId>zookeeper</artifactId>
                <version>3.4.8</version>
            </dependency>
            <dependency>
                <groupId>org.apache.curator</groupId>
                <artifactId>curator-framework</artifactId>
                <version>2.12.0</version>
            </dependency>
            <dependency>
                <groupId>org.apache.curator</groupId>
                <artifactId>curator-recipes</artifactId>
                <version>2.12.0</version>
            </dependency>
    
    
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>dubbo</artifactId>
                <version>2.5.5</version>
            </dependency>
            <dependency>
                <groupId>org.javassist</groupId>
                <artifactId>javassist</artifactId>
                <version>3.20.0-GA</version>
            </dependency>
            <dependency>
                <groupId>org.jboss.netty</groupId>
                <artifactId>netty</artifactId>
                <version>3.2.5.Final</version>
            </dependency>
            <dependency>
                <groupId>com.101tec</groupId>
                <artifactId>zkclient</artifactId>
                <version>0.2</version>
            </dependency>
            <dependency>
                <groupId>org.apache.curator</groupId>
                <artifactId>curator-framework</artifactId>
                <version>2.12.0</version>
            </dependency>
            <dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>1.2.16</version>
            </dependency>
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-api</artifactId>
                <version>1.7.25</version>
            </dependency>
        </dependencies>
        <build>
            <!-- 配置了很多插件 -->
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.5.1</version>
                    <configuration>
                        <source>1.7</source>
                        <target>1.7</target>
                        <encoding>UTF-8</encoding>
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    </project>

    1.基于XML的方式

    1.1服务提供者

    接口以及其实现

    package dubbo;
    
    public interface DubboService {
        String sayHello(String name);
    }
    package dubbo;
    
    public class DubboServiceImpl implements DubboService {
        public String sayHello(String name) {
            return "Hello " + name;
        }
    }

    provider.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
        xsi:schemaLocation="http://www.springframework.org/schema/beans  
            http://www.springframework.org/schema/beans/spring-beans.xsd  
            http://code.alibabatech.com/schema/dubbo  
            http://code.alibabatech.com/schema/dubbo/dubbo.xsd ">
    
        <!-- 提供方应用信息,用于计算依赖关系 -->
        <dubbo:application name="hello-world-app" />
    
        <!-- 使用multicast广播注册中心暴露服务地址,IP设置: 224.0.0.0 - 239.255.255.255 -->
        <dubbo:registry address="multicast://224.5.6.7:1234" />
    
        <!-- 用dubbo协议在20880端口暴露服务 -->
        <dubbo:protocol name="dubbo" port="20880" />
    
        <!-- 声明需要暴露的服务接口 -->
        <dubbo:service interface="dubbo.DubboService" ref="demoService" />
        <!-- 和本地bean一样实现服务 -->
        <bean id="demoService" class="dubbo.DubboServiceImpl" />
    </beans>

    启动类:

    package dubbo;
    
    import java.io.IOException;
    
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class Provider {
        public static void main(String[] args) throws IOException {
            ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] { "provider.xml" });
            context.start();
            System.in.read(); // 按任意键退出
        }
    }

    1.2服务消费者

    接口同上:

    package dubbo;
    
    public interface DubboService {
        String sayHello(String name);
    }

    consumer.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
        xsi:schemaLocation="http://www.springframework.org/schema/beans  
            http://www.springframework.org/schema/beans/spring-beans.xsd  
            http://code.alibabatech.com/schema/dubbo  
            http://code.alibabatech.com/schema/dubbo/dubbo.xsd ">
    
        <!-- 消费方应用名,用于计算依赖关系,不是匹配条件,不要与提供方一样 -->
        <dubbo:application name="consumer-of-helloworld-app" />
    
        <!-- 使用multicast广播注册中心暴露发现服务地址 -->
        <dubbo:registry address="multicast://224.5.6.7:1234" />
    
        <!-- 生成远程服务代理,可以和本地bean一样使用demoService -->
        <dubbo:reference id="dubboService" interface="dubbo.DubboService" />
    </beans>

    启动类:

    package dubbo;
    
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class Consumer {
        public static void main(String[] args) {
            ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] { "consumer.xml" });
            context.start();
            DubboService demoService = (DubboService) context.getBean("dubboService"); // 获取远程服务代理
            String hello = demoService.sayHello("world"); // 执行远程方法
            System.out.println(hello); // 显示调用结果
        }
    }

    结果:

    Hello world

    补充:当然可以基于zookeeper注册服务

    将上面consumer.xml和provider.xml的注册地址改为zookeeper地址:(zookeeper要启动或者集群启动)

    <dubbo:registry address="zookeeper://127.0.0.1:2181" />

    zookeeper的节点信息如下:

    发布到zookeeper之后查看从dubbo-admin项目查看生产者和消费者:

     

    2.API实现

      接口类还是上面的接口,服务提供者的实现类还是上面的实现类。

    provider生产者:

    package dubbo.api;
    
    import java.util.concurrent.CountDownLatch;
    
    import com.alibaba.dubbo.config.ApplicationConfig;
    import com.alibaba.dubbo.config.ProtocolConfig;
    import com.alibaba.dubbo.config.RegistryConfig;
    import com.alibaba.dubbo.config.ServiceConfig;
    
    import dubbo.DubboService;
    import dubbo.DubboServiceImpl;
    
    public class Provider {
        public static void main(String[] args) throws InterruptedException {
            CountDownLatch countDownLatch = new CountDownLatch(1);
    
            // 服务实现
            DubboService dubboService = new DubboServiceImpl();
    
            // 当前应用配置
            ApplicationConfig application = new ApplicationConfig();
            application.setName("provider");
    
            // 连接注册中心配置
            RegistryConfig registry = new RegistryConfig();
            registry.setAddress("multicast://224.5.6.7:1234");
            registry.setUsername("aaa");
            registry.setPassword("bbb");
    
            // 服务提供者协议配置
            ProtocolConfig protocol = new ProtocolConfig();
            protocol.setName("dubbo");
            protocol.setPort(12345);
            protocol.setThreads(200);
    
            // 注意:ServiceConfig为重对象,内部封装了与注册中心的连接,以及开启服务端口
            // 服务提供者暴露服务配置
            ServiceConfig<DubboService> service = new ServiceConfig<DubboService>(); // 此实例很重,封装了与注册中心的连接,请自行缓存,否则可能造成内存和连接泄漏
            service.setApplication(application);
            service.setRegistry(registry); // 多个注册中心可以用setRegistries()
            service.setProtocol(protocol); // 多个协议可以用setProtocols()
            service.setInterface(DubboService.class);
            service.setRef(dubboService);
            service.setVersion("1.0.0");
    
            // 暴露及注册服务
            service.export();
    
            countDownLatch.await();
        }
    }

    consumer消费者:

    package dubbo.api;
    
    import com.alibaba.dubbo.config.ApplicationConfig;
    import com.alibaba.dubbo.config.ReferenceConfig;
    import com.alibaba.dubbo.config.RegistryConfig;
    
    import dubbo.DubboService;
    
    public class Consumer {
        public static void main(String[] args) {
            // 当前应用配置
            ApplicationConfig application = new ApplicationConfig();
            application.setName("consumer");
    
            // 连接注册中心配置
            RegistryConfig registry = new RegistryConfig();
            registry.setAddress("multicast://224.5.6.7:1234");
            registry.setUsername("aaa");
            registry.setPassword("bbb");
    
            // 注意:ReferenceConfig为重对象,内部封装了与注册中心的连接,以及与服务提供方的连接
    
            // 引用远程服务
            ReferenceConfig<DubboService> reference = new ReferenceConfig<DubboService>(); // 此实例很重,封装了与注册中心的连接以及与提供者的连接,请自行缓存,否则可能造成内存和连接泄漏
            reference.setApplication(application);
            reference.setRegistry(registry); // 多个注册中心可以用setRegistries()
            reference.setInterface(DubboService.class);
            reference.setVersion("1.0.0");
    
            // 和本地bean一样使用xxxService
            DubboService dubboService = reference.get(); // 注意:此代理对象内部封装了所有通讯细节,对象较重,请缓存复用
            System.out.println(dubboService.sayHello("china"));
        }
    }

    3.基于spring的注解实现

       参考:https://www.cnblogs.com/qlqwjy/p/10539824.html

        不管基于何种方式,dubbo的生产者停掉之后消费者不能进行消费。

    4.配置加载流程

      Dubbo的配置读取总体上遵循了以下几个原则:

    1.Dubbo支持了多层级的配置,并按预定优先级自动实现配置间的覆盖,最终所有配置汇总到数据总线URL后驱动后续的服务暴露、引用等流程。
    2.ApplicationConfig、ServiceConfig、ReferenceConfig可以被理解成配置来源的一种,是直接面向用户编程的配置采集方式。
    3.配置格式以Properties为主,在配置内容上遵循约定的path-based的命名

    4.1配置来源

    默认有四种配置来源:

    JVM System Properties,-D参数
    Externalized Configuration,外部化配置
    ServiceConfig、ReferenceConfig等编程接口采集的配置
    本地配置文件dubbo.properties

    4.2覆盖关系

    4.3配置格式

    目前Dubbo支持的所有配置都是.properties格式的,包括-D、Externalized Configuration等,.properties中的所有配置项遵循一种path-based的配置格式: 

    # 应用级别
    dubbo.{config-type}[.{config-id}].{config-item}={config-item-value}
    # 服务级别
    dubbo.service.{interface-name}[.{method-name}].{config-item}={config-item-value}
    dubbo.reference.{interface-name}[.{method-name}].{config-item}={config-item-value}
    # 多配置项
    dubbo.{config-type}s.{config-id}.{config-item}={config-item-value}
    • 应用级别
    dubbo.application.name=demo-provider
    dubbo.registry.address=zookeeper://127.0.0.1:2181
    dubbo.protocol.port=-1
    • 服务级别
    dubbo.service.org.apache.dubbo.samples.api.DemoService.timeout=5000
    dubbo.reference.org.apache.dubbo.samples.api.DemoService.tineout=6000
    dubbo.reference.org.apache.dubbo.samples.api.DemoService.sayHello.timeout=7000
    • 多配制项
    dubbo.registries.unit1.address=zookeeper://127.0.0.1:2181
    dubbo.registries.unit2.address=zookeeper://127.0.0.1:2182
    
    dubbo.protocols.dubbo.name=dubbo
    dubbo.protocols.dubbo.port=20880
    dubbo.protocols.hessian.name=hessian
    dubbo.protocols.hessian.port=8089
    • 扩展配置
    dubbo.application.parameters.item1=value1
    dubbo.application.parameters.item2=value2
    dubbo.registry.parameters.item3=value3
    dubbo.reference.org.apache.dubbo.samples.api.DemoService.parameters.item4=value4

    4.4几种配置格式

    • xml配置
      <!-- dubbo-provier.xml -->
      
      <dubbo:application name="demo-provider"/>
      <dubbo:config-center address="zookeeper://127.0.0.1:2181"/>
      
      <dubbo:registry address="zookeeper://127.0.0.1:2181" simplified="true"/>
      <dubbo:metadata-report address="redis://127.0.0.1:6379"/>
      <dubbo:protocol name="dubbo" port="20880"/>
      
      <bean id="demoService" class="org.apache.dubbo.samples.basic.impl.DemoServiceImpl"/>
      <dubbo:service interface="org.apache.dubbo.samples.basic.api.DemoService" ref="demoService"/>
    • annotation
      // AnnotationService服务实现
      
      @Service
      public class AnnotationServiceImpl implements AnnotationService {
          @Override
          public String sayHello(String name) {
              System.out.println("async provider received: " + name);
              return "annotation: hello, " + name;
          }
      }
      ## dubbo.properties
      
      dubbo.application.name=annotation-provider
      dubbo.registry.address=zookeeper://127.0.0.1:2181
      dubbo.protocol.name=dubbo
      dubbo.protocol.port=20880
    • springboot
    ## application.properties
      
      # Spring boot application
      spring.application.name=dubbo-externalized-configuration-provider-sample
      
      # Base packages to scan Dubbo Component: @com.alibaba.dubbo.config.annotation.Service
      dubbo.scan.base-packages=com.alibaba.boot.dubbo.demo.provider.service
      
      # Dubbo Application
      ## The default value of dubbo.application.name is ${spring.application.name}
      ## dubbo.application.name=${spring.application.name}
      
      # Dubbo Protocol
      dubbo.protocol.name=dubbo
      dubbo.protocol.port=12345
      
      ## Dubbo Registry
      dubbo.registry.address=N/A
      
      ## DemoService version
      demo.service.version=1.0.0
    • API
    public static void main(String[] args) throws IOException {
        ServiceConfig<GreetingsService> service = new ServiceConfig<>();
        service.setApplication(new ApplicationConfig("first-dubbo-provider"));
        service.setRegistry(new RegistryConfig("multicast://224.5.6.7:1234"));
        service.setInterface(GreetingsService.class);
        service.setRef(new GreetingsServiceImpl());
        service.export();
        System.out.println("first-dubbo-provider is running.");
        System.in.read();
    }

    补充:最新版本的dubbo的使用:

    pom.xml

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <groupId>cn.qlq</groupId>
        <artifactId>zookeper</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <dependencies>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.12</version>
            </dependency>
            <dependency>
                <groupId>org.apache.zookeeper</groupId>
                <artifactId>zookeeper</artifactId>
                <version>3.4.8</version>
            </dependency>
            <dependency>
                <groupId>org.apache.curator</groupId>
                <artifactId>curator-framework</artifactId>
                <version>2.12.0</version>
            </dependency>
            <dependency>
                <groupId>org.apache.curator</groupId>
                <artifactId>curator-recipes</artifactId>
                <version>2.12.0</version>
            </dependency>
    
    
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>dubbo</artifactId>
                <version>2.6.6</version>
            </dependency>
            <dependency>
                <groupId>org.javassist</groupId>
                <artifactId>javassist</artifactId>
                <version>3.20.0-GA</version>
            </dependency>
            <dependency>
                <groupId>io.netty</groupId>
                <artifactId>netty-all</artifactId>
                <version>4.1.34.Final</version>
            </dependency>
    
            <dependency>
                <groupId>com.101tec</groupId>
                <artifactId>zkclient</artifactId>
                <version>0.2</version>
            </dependency>
            <dependency>
                <groupId>org.apache.curator</groupId>
                <artifactId>curator-framework</artifactId>
                <version>2.12.0</version>
            </dependency>
            <dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>1.2.16</version>
            </dependency>
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-api</artifactId>
                <version>1.7.25</version>
            </dependency>
            <dependency>
                <groupId>commons-lang</groupId>
                <artifactId>commons-lang</artifactId>
                <version>2.6</version>
            </dependency>
        </dependencies>
        <build>
            <!-- 配置了很多插件 -->
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.5.1</version>
                    <configuration>
                        <source>1.7</source>
                        <target>1.7</target>
                        <encoding>UTF-8</encoding>
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    </project>

    provider.xml如下:

    <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:dubbo="http://dubbo.apache.org/schema/dubbo" xmlns="http://www.springframework.org/schema/beans"
        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:application name="hello-world-app">
            <!-- 关闭QOS:Quality of Service -->
            <dubbo:parameter key="qos.enable" value="false" />
            <dubbo:parameter key="qos.accept.foreign.ip" value="true" />
            <dubbo:parameter key="qos.port" value="2222" />
        </dubbo:application>
    
        <!-- 使用multicast广播注册中心暴露服务地址,IP设置: 224.0.0.0 - 239.255.255.255 -->
        <dubbo:registry address="zookeeper://127.0.0.1:2181" />
    
        <!-- 用dubbo协议在20880端口暴露服务 -->
        <dubbo:protocol name="dubbo" port="20880" />
    
        <!-- 声明需要暴露的服务接口 -->
        <dubbo:service interface="dubbo.DubboService" ref="demoService" />
        <!-- 和本地bean一样实现服务 -->
        <bean id="demoService" class="dubbo.DubboServiceImpl" />
    </beans>
  • 相关阅读:
    [BOST] 博赞有机的学习技巧
    [BOST] 你的大脑比你想象的更优秀
    Markdown学习笔记
    nodejs原生态模块,写个聊天室
    【2】自定义WindowsForm分页控件使用【共两篇】
    【1】自定义WindowsForm分页控件使用【共两篇】
    《Log4net写出适合自己的日志类》第三篇【终】【怎样让它适合你自己需求】
    《Log4net写出适合自己的日志类》第二篇【没有理论的实践是盲目】
    《Log4net写出适合自己的日志类》第一篇【上来就是干,先实践后理论】
    记忆留住深刻过往,博客写出平淡事迹【博客首篇】
  • 原文地址:https://www.cnblogs.com/qlqwjy/p/10398087.html
Copyright © 2020-2023  润新知