前言

Dubbo作为一款RPC和微服务框架,还是很值得深入学习一波的。

Dubbo帮助我们解决了微服务实战中的两个问题:
1、作为服务开发框架,制定了微服务定义、开发与调用的规范;并通过RPC完成数据交换。解决了开发和通讯的问题。
2、抽象了一套微服务治理模式,包括地址发现、负载均衡、流量路由、可观测性。简化微服务的运维。

架构

总体架构

image-1678886949674
Provider:服务提供方
Consumer:服务消费方
Registry:服务注册与发现的注册中心
Monitor:监控中心,统计调用次数与时间
Container:服务运行容器

调用关系说明
0、服务容器启动,运行服务提供者。
1、服务提供者启动时,向注册中心注册自己。
2、服务消费者启动,从注册中心订阅自己所需的服务。
3、注册中心将服务提供者地址返回给服务消费者,包括变更。
4、服务消费者调用服务提供者
5、服务提供者与消费者,定期上报调用信息。

代码架构

image-1678887833842

说明:
1、左侧为服务消费使用的接口;右侧为服务提供方使用的接口;中轴线上为双方都使用到的接口。
2、紫色三角箭头为继承关系,其它标注参考图最上一排的文字。

各层说明

  • Config 配置层:对外配置接口。
  • Proxy 服务代理层:服务接口透明代理,生成客户端Stub和服务端Skeleton。
  • Registry 注册中心层:封装服务地址的注册与发现,以服务URL为中心。
  • Cluster 路由层:封装多个提供者的路由及负载均衡。
  • Monitor 监控层:RPC调用次数与调用时间监控。
  • Protocol 远程调用层:封装RPC调用。
  • Exchange 信息交换层:封装请求响应模式,同步转异步,以Request、Response为中心。
  • Transport 网络传输层:抽象mina和netty为统一接口,完成网络传输。
  • Serialize 数据序列化层:能够进行复用的一些工具。

核心概念与功能

服务发现

Dubbo提供了服务发现的机制,依赖于第三方注册中心组件来协助。
常见的注册中心如 Nacos、Consul、Zookeeper等。
工作原理图:
image-1678890797704

负载均衡

在有多个服务提供者时,需要通过负载均衡算法的选出请求哪个 服务提供方。
默认是加权随机算法,默认权重相同,在此情况下,对应1比1的请求量。

另外还有:加权轮询、最少活跃优先+加权随机、最短响应优先+加权随机、一致性哈希(适合有状态请求)。

流量管控

Dubbo提供了路由管控策略,有负载均衡(包括多种算法)和路由策略
大致流程:获取到的请求地址集合,经过多个路由策略,变成新的地址子集,再经过负载均衡策略选择服务进行调用。

工作原理:
image-1678942182220

多个路由器组成一个路由链共同协助。

通讯协议

Dubbo提供了自定义的高性能通讯协议:基于HTTP/2的Triple 协议和基于TCP的Dubbo2协议

Dobbo同时支持任意协议的框架,如gRpc、Thrift、REST、JsonRPC、Hession2等。更多协议还可以自定义扩展

扩展适配

Dubbo的扩展性可以方便将Dubbo切分成一个个的子模块,实现热插拔特性。可使用自身实现替代Dubbo原生实现。
image-1678971890556

  • 协议与编码扩展:通讯协议、序列号编码协议
  • 流量管控扩展:集群容错、路由策略、负载均衡、限流降级等
  • 服务治理扩展:注册中心、配置中心、元数据中心
  • 诊断优化扩展:日志、健康检查、流量统计、配置加载等

微服务生态

image-1678974225492

比较丰富的生态支持,不用担心治理诉求

入门实战

接下来以SpringBoot + Dubbo3来搭建演示demo

示例已上传github地址,可以下载直接学习演示。

1、创建项目dubbo-spring-boot-demo
引入pom

<properties>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>

        <dubbo.version>3.2.0-beta.4</dubbo.version>
        <spring-boot.version>2.6.6</spring-boot.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencyManagement>
        <dependencies>
            <!-- Spring Boot -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <!-- Dubbo -->
            <dependency>
                <groupId>org.apache.dubbo</groupId>
                <artifactId>dubbo-bom</artifactId>
                <version>${dubbo.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <dependency>
                <groupId>org.apache.dubbo</groupId>
                <artifactId>dubbo-dependencies-zookeeper-curator5</artifactId>
                <version>${dubbo.version}</version>
                <type>pom</type>
            </dependency>
        </dependencies>
    </dependencyManagement>

2、创建3个模块,分别命名
dubbo-spring-boot-demo-interface
dubbo-spring-boot-demo-provider
dubbo-spring-boot-demo-consumer

3、对于dubbo-spring-boot-demo-interface模块
创建接口,并定义接口如下:

public interface DemoService {
    String sayHello(String name);
}

4、对于dubbo-spring-boot-demo-provider模块
作为服务提供方

4.1、添加pom依赖

<dependencies>
        <dependency>
            <groupId>top.xudj</groupId>
            <artifactId>dubbo-spring-boot-demo-interface</artifactId>
            <version>${project.parent.version}</version>
        </dependency>

        <!-- dubbo -->
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-dependencies-zookeeper-curator5</artifactId>
            <type>pom</type>
            <exclusions>
                <exclusion>
                    <artifactId>slf4j-reload4j</artifactId>
                    <groupId>org.slf4j</groupId>
                </exclusion>
            </exclusions>
        </dependency>

        <!-- spring boot starter -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
    </dependencies>

4.2、添加yaml配置

dubbo:
  application:
    name: dubbo-spring-boot-demo-provider
  protocol:
    # 定义dubbo协议
    name: dubbo
    port: -1
  registry:
    # 指定注册中心 zookeeper
    address: zookeeper://${zookeeper.address:127.0.0.1}:2181

4.3、定义服务提供者实现

**
 * 通过@DubboService发布dubbo服务
 */
@DubboService
public class DemoServiceImpl implements DemoService {

    @Override
    public String sayHello(String name) {
        return "hello " + name;
    }

}

4.4、定义启动类

@SpringBootApplication
@EnableDubbo
public class ProviderApplication {

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

5、对于dubbo-spring-boot-demo-consumer模块
作为服务消费方

5.1、增加pom依赖

<dependencies>
        <dependency>
            <groupId>top.xudj</groupId>
            <artifactId>dubbo-spring-boot-demo-interface</artifactId>
            <version>${project.parent.version}</version>
        </dependency>

        <!-- dubbo -->
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-dependencies-zookeeper-curator5</artifactId>
            <type>pom</type>
            <exclusions>
                <exclusion>
                    <artifactId>slf4j-reload4j</artifactId>
                    <groupId>org.slf4j</groupId>
                </exclusion>
            </exclusions>
        </dependency>

        <!-- spring boot starter -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
    </dependencies>

5.2、添加yaml配置

dubbo:
  application:
    name: dubbo-spring-boot-demo-consumer
  protocol:
    # 定义dubbo协议
    name: dubbo
    port: -1
  registry:
    # 指定注册中心 zookeeper
    address: zookeeper://${zookeeper.address:127.0.0.1}:2181

5.3、添加消费逻辑,调用服务提供方

@Component
public class Task implements CommandLineRunner {

    @DubboReference
    private DemoService demoService;

    @Override
    public void run(String... args) throws Exception {
        String result = demoService.sayHello("world");
        System.out.println("Receive result ======> " + result);

        new Thread(()-> {
            while (true) {
                try {
                    Thread.sleep(1000);
                    System.out.println(new Date() + " Receive result ======> " + demoService.sayHello("world"));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    Thread.currentThread().interrupt();
                }
            }
        }).start();
    }

}

5.4、定义启动类

@SpringBootApplication
@EnableDubbo
public class ConsumerApplication {

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

}

6、启动注册中心
配置是以zookeeper作为注册中心。可以自行安装启动。这里给出一个通过dubbo-samples启动的简易注册中心方式,如下:

git clone --depth=1 https://github.com/apache/dubbo-samples
cd dubbo-samples 执行:./mvnw clean compile exec:java -pl tools/embedded-zookeeper

7、测试
启动服务提供方ProviderApplication
启动服务消费方ConsumerApplication

正常每秒输出:

Thu Mar 16 22:11:37 CST 2023 Receive result ======> hello world
Thu Mar 16 22:11:38 CST 2023 Receive result ======> hello world
Thu Mar 16 22:11:39 CST 2023 Receive result ======> hello world
Thu Mar 16 22:11:40 CST 2023 Receive result ======> hello world

总结

Dubbo作为一款PRC与微服务框架,已经具备了比较完整的生态,它既提供了开发框架的规范,也具备了服务治理的能力。

文中介绍了Dubbo的架构,包括总体架构与代码架构,提供的功能不仅包括文中列出的那些,还有很多治理、诊断等机制可供使用。

最后给出了Dubbo的演示示例,也可以在github下载dubbo源码,启动dubbo-demo模块下的dubbo-demo-spring-boot模块进行学习演示,如下:

1、clone代码:https://github.com/apache/dubbo
2、进入项目:mvn clean install -Dmaven.test.skip=true
3、idea导入项目
4、进行演示:dubbo-demo模块的:dubbo-demo-spring-boot,启动ProviderApplication、ConsumerApplication