美文网首页java
分布式--Dubbo入门

分布式--Dubbo入门

作者: aruba | 来源:发表于2022-06-17 09:04 被阅读0次

    Dubbo是阿里的内部RPC框架,于2011年对外提供,2019年捐献给Apache,至此由Apache维护更新,Dubbo依赖Spring,除了RPC访问外,还提供了服务治理功能,如:负载均衡、数据统计等

    结合上图,Dubbo主要分为5个角色:

    角色 描述
    Provider 服务提供者
    Container 容器,即Spring容器,提供者借助Spring初始化
    Register 注册中心,存放提供者对外提供的信息。如ip、端口、协议、对外接口等
    Consumer 消费者,RPC调用方
    Monitor 监控中心,统计访问情况

    图中虚线部分均为异步,实线为同步,流程为:

    0. start:启动Spring容器时,初始化Provider
    1. register:Provider信息注册到Registry
    2. subscribe:Consumer通过Registry订阅
    3. notify:Registry将Provider信息通知给Consumer
    4. invoke:Consumer通过Provider信息调用Provider方法
    5. count:将访问信息上传到Monitor

    Dubbo支持的协议

    协议 优点 缺点
    Dubbo协议(官方推荐) 采用NIO复用单一长连接,并使用线程池并发处理请求,减少握手和加大并发效率,性能较好 大文件上传时,可能出现问题
    RMI协议 JDK自带 偶尔连接失败
    Hessian协议 可与原生Hessian互操作,基于HTTP协议 需hessian.jar支持,http短连接的开销大

    Dubbo支持的注册中心

    注册中心 优点 缺点
    Zookeeper(官方推荐) 支持分布式,生态圈大 受限于zookeeper软件的稳定性,但通过分布式辅助软件可以解决
    Multicast 去中心化,不需要单独安装软件 Provider和Consumer和Registry不能跨机房(路由)
    Redis 支持集群,性能高 要求服务器时间同步,否则会出现集群失败问题
    Simple 标准RPC服务,没有兼容问题 不支持集群

    一、使用Dubbo

    创建一个maven工程,依赖springboot

        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.7.0</version>
        </parent>
    
        <dependencyManagement>
            <dependencies>
                <dependency>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter</artifactId>
                    <version>2.7.0</version>
                </dependency>
                <dependency>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-web</artifactId>
                    <version>2.7.0</version>
                </dependency>
                <!-- https://mvnrepository.com/artifact/org.apache.dubbo/dubbo-spring-boot-starter -->
                <dependency>
                    <groupId>org.apache.dubbo</groupId>
                    <artifactId>dubbo-spring-boot-starter</artifactId>
                    <version>2.7.8</version>
                </dependency>
                <dependency>
                    <groupId>org.apache.curator</groupId>
                    <artifactId>curator-recipes</artifactId>
                    <version>4.2.0</version>
                </dependency>
            </dependencies>
        </dependencyManagement>
    

    1. api模块

    新建Maven子模块,作为对外接口:

    定义接口:

    public interface DemoService {
        public String demo(String demo);
    }
    

    2. provider模块

    新建Maven子模块,作为提供者

    2.1 导入依赖

    provider不需要作为web项目

        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter</artifactId>
            </dependency>
            <!--dubbo-->
            <dependency>
                <groupId>org.apache.dubbo</groupId>
                <artifactId>dubbo-spring-boot-starter</artifactId>
            </dependency>
            <!--zookeeper-->
            <dependency>
                <groupId>org.apache.curator</groupId>
                <artifactId>curator-recipes</artifactId>
            </dependency>
            <!--api模块-->
            <dependency>
                <groupId>com.aruba.demo1</groupId>
                <artifactId>api</artifactId>
                <version>1.0-SNAPSHOT</version>
            </dependency>
        </dependencies>
    
    2.2 springboot配置文件

    resources目录下新建application.yml,配置dubbo,内容如下:

    dubbo:
      application:
        name: dubbo-provider
      registry:
        address: zookeeper://192.168.42.4:2181
    
    2.3 实现对外接口

    使用@DubboService注解,表示该对象为Dubbo使用的Provider对象

    @DubboService
    public class DemoServiceImpl implements DemoService {
    
        @Override
        public String demo(String demo) {
            return demo + ",hello";
        }
    
    }
    
    2.4 启动springboot

    使用注解开启dubbo

    @SpringBootApplication
    @EnableDubbo
    public class ProviderApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(ProviderApplication.class, args);
        }
    
    }
    

    3. consumer模块

    创建一个Maven子模块,作为调用方

    3.1 导入依赖
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <!--dubbo-->
            <dependency>
                <groupId>org.apache.dubbo</groupId>
                <artifactId>dubbo-spring-boot-starter</artifactId>
            </dependency>
            <!--zookeeper-->
            <dependency>
                <groupId>org.apache.curator</groupId>
                <artifactId>curator-recipes</artifactId>
            </dependency>
            <!--api模块-->
            <dependency>
                <groupId>com.aruba.demo1</groupId>
                <artifactId>api</artifactId>
                <version>1.0-SNAPSHOT</version>
            </dependency>
        </dependencies>
    
    3.2 springboot配置文件

    在resources目录下新建application.xml,内容为:

    dubbo:
      application:
        name: dubbo-consumer
      registry:
        address: zookeeper://192.168.42.4:2181
    
    3.3 service层

    定义接口:

    public interface DemoConsumerService {
        public String demoConsumer();
    }
    

    实现接口,远程对象使用@DubboReference注解注入:

    @Service
    public class DemoConsumerServiceImpl implements DemoConsumerService {
    
        @DubboReference
        private DemoService service;
    
        @Override
        public String demoConsumer() {
            return service.demo("dubbo");
        }
    }
    
    3.4 controller层
    @RestController
    public class DemoController {
    
        @Autowired
        private DemoConsumerService service;
    
        @RequestMapping("/demo")
        public String demo() {
            return service.demoConsumer();
        }
    
    }
    
    3.5 SpringBoot启动类

    同样需要使用@EnableDubbo注解开启dubbo

    @SpringBootApplication
    @EnableDubbo
    public class ConsumerApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(ConsumerApplication.class, args);
        }
    
    }
    

    浏览器访问结果:

    二、负载均衡

    Dubbo内置了以下负载均衡策略:

    策略名 描述
    Random(默认) 随机访问集群中节点,概论与权重有关
    RoundRobin 轮询访问集群中节点,频率与权重有关,2.7.8版本权重不设置不生效
    LeastActive 活跃数相同的随机,高活跃数的优先访问
    ConsistentHash 相同请求参数总是发到一个节点
    ShortestResponse 最快响应,选出响应时间最短的节点

    使用方式

    Provider和Consumer都可以使用以上策略,指定策略名使用全小写,第一种方式为注解时指定:

    对象 注解 指定属性
    Provider @DubboService loadbalance 如:@DubboService(loadbalance = "roundrobin")
    Consumer @DubboReference loadbalance 如:@DubboReference(loadbalance = "random")

    第二种方式为springboot配置文件中指定全局策略:

    dubbo:
      application:
        name: dubbo-provider
      registry:
        address: zookeeper://192.168.42.4:2181
      #指定provider的负载均衡策略
      provider:
        loadbalance: random
      #指定consumer的负载均衡策略
      consumer:
        loadbalance: random
    

    下面以Provider注解为例子

    1. 为Provider实现类指定策略

    方法中加个控制台输出,以便于后续观察负载均衡策略的效果

    @DubboService(weight = 1, loadbalance = "roundrobin")
    public class DemoServiceImpl implements DemoService {
    
        @Override
        public String demo(String demo) {
            System.out.println(demo);
            return demo + ",hello";
        }
    
    }
    

    2. 模拟集群环境

    复制springboot启动类:

    springboot配置文件中,指定协议端口,来启动多次

    dubbo:
      application:
        name: dubbo-provider
      registry:
        address: zookeeper://192.168.42.4:2181
      protocol:
        name: dubbo
        port: 20881
    

    修改port,我这边是从20881改到20884,每次修改完启动下对应的springboot启动类,4个启动完的效果:

    3. Consumer调用

    轮询的效果是依次访问节点,启动Consumer后,进行浏览器访问:

    项目地址:

    https://gitee.com/aruba/dubbo.git

    相关文章

      网友评论

        本文标题:分布式--Dubbo入门

        本文链接:https://www.haomeiwen.com/subject/kqhqvrtx.html