分布式--Dubbo入门

2022-06-19 14:46:20 浏览数 (1)

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

代码语言:javascript复制
    <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子模块,作为对外接口:

定义接口:

代码语言:javascript复制
public interface DemoService {
    public String demo(String demo);
}
2. provider模块

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

2.1 导入依赖

provider不需要作为web项目

代码语言:javascript复制
    <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,内容如下:

代码语言:javascript复制
dubbo:
  application:
    name: dubbo-provider
  registry:
    address: zookeeper://192.168.42.4:2181
2.3 实现对外接口

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

代码语言:javascript复制
@DubboService
public class DemoServiceImpl implements DemoService {

    @Override
    public String demo(String demo) {
        return demo   ",hello";
    }

}
2.4 启动springboot

使用注解开启dubbo

代码语言:javascript复制
@SpringBootApplication
@EnableDubbo
public class ProviderApplication {

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

}
3. consumer模块

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

3.1 导入依赖
代码语言:javascript复制
    <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,内容为:

代码语言:javascript复制
dubbo:
  application:
    name: dubbo-consumer
  registry:
    address: zookeeper://192.168.42.4:2181
3.3 service层

定义接口:

代码语言:javascript复制
public interface DemoConsumerService {
    public String demoConsumer();
}

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

代码语言:javascript复制
@Service
public class DemoConsumerServiceImpl implements DemoConsumerService {

    @DubboReference
    private DemoService service;

    @Override
    public String demoConsumer() {
        return service.demo("dubbo");
    }
}
3.4 controller层
代码语言:javascript复制
@RestController
public class DemoController {

    @Autowired
    private DemoConsumerService service;

    @RequestMapping("/demo")
    public String demo() {
        return service.demoConsumer();
    }

}
3.5 SpringBoot启动类

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

代码语言:javascript复制
@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配置文件中指定全局策略:

代码语言:javascript复制
dubbo:
  application:
    name: dubbo-provider
  registry:
    address: zookeeper://192.168.42.4:2181
  #指定provider的负载均衡策略
  provider:
    loadbalance: random
  #指定consumer的负载均衡策略
  consumer:
    loadbalance: random

下面以Provider注解为例子

1. 为Provider实现类指定策略

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

代码语言:javascript复制
@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配置文件中,指定协议端口,来启动多次

代码语言:javascript复制
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

0 人点赞