Dubbo

分布式系统概述

用户体验

  • 美观
  • 功能
  • 速度
  • 稳定性

其中美观由UI决定、功能由PM决定,而速度和稳定性则与开发人员息息相关

互联网项目特点

  • 用户多
  • 流量大、并发高
  • 海量数据
  • 易受攻击
  • 功能繁琐
  • 变更快

大型互联网项目架构目标

衡量网站的性能指标

响应时间

指执行一个请求从开始到最后收到响应数据所花费的总体时间

并发数

指系统同时能够处理的请求数量

  • 并发连接数
    • 指的是客户端向服务器发起请求,并建立了TCP连接,每秒钟服务器连接的总TCP数量
  • 请求数(QPS)
    • 每秒多少请求
  • 并发用户数
    • 单位时间内多少用户
吞吐量

单位时间内系统能处理的请求数量

  • QPS(Query per second) 每秒查询数
  • TPS(Transactions per second)每秒事务数
    • 一个事务是指一个客户机向服务器发送请求然后服务器做出反应的过程。客户机在发送请求时开始计时,收到服务器响应后结束计时,以此来计算使用的时间和完成的事务个数。
    • •一个页面的一次访问,只会形成一个TPS;但一次页面请求,可能产生多次对服务器的请求,就会有多个QPS

大型互联网项目目标

  • 高性能:提供快速的访问体验。

  • 高可用:网站服务一直可以正常访问。

  • 可伸缩:通过硬件增加/减少,提高/降低处理能力。

  • 高可扩展:系统间耦合低,方便的通过新增/移除方式,增加/减少新的功能/模块。

  • 安全性:提供网站安全访问和数据加密,安全存储等策略。

  • 敏捷性:随需应变,快速响应。

集群与分布式

  • 集群:很多人一起干一样的事,同一业务部署在多台机器
  • 分布式:很多人一起干不一样的事,这些不一样的事,合起来是一件大事,一个大的业务系统,拆分成多个小的业务模块,不同模块部署在不同机器上

高性能、高可用、可伸缩、高扩展

image-20240409220727156

Dubbo概述

  • Dubbo是阿里巴巴公司开源的一个高性能、轻量级的 Java RPC 框架。
  • 致力于提供高性能和透明化的 RPC 远程服务调用方案,以及 SOA 服务治理方案
  • 官网

Dubbo基本架构

节点角色说明:

  • Provider:暴露服务的服务提供方

  • Container:服务运行容器

  • Consumer:调用远程服务的服务消费方

  • Registry:服务注册与发现的注册中心

  • Monitor:统计服务的调用次数和调用时间的监控中心

image-20240409235820537

Dubbo快速入门

Dubbo官方推荐使用Zookeeper作为注册中心

所以需要首先安装zookeeper

Zookeeper安装

我们选择在VMWare虚拟机CentOS7系统上进行安装,安装zookeeper版本为3.5.6

Zookeeper下载地址

下载安装

下载对应安装包,并上传到虚拟机对应目录

1
2
3
4
cd /home/springCloudTool #切换到对应目录
mkdir zookeeper #创建目录
通过winscap将安装包上传至/home/springCloudTool/zookeeper目录下
tar -zxvf apache-ZooKeeper-3.5.6-bin.tar.gz #解压安装包

image-20240410002642779

启动配置

1
2
3
4
5
cd /home/springCloudTool/zookeeper #切换目录
mkdir zkdata #创建目录
cd ./conf #进入配置文件目录
cp zoo_sample.cfg zoo.cfg #拷贝配置文件
vim zoo.cfg #修改配置文件

修改存储目录

image-20240410003008221

启动zookeeper

1
2
3
4
cd ../bin #进入目录
./zkServer.sh start #启动zookeeper
./zkServer.sh stop #停止zookeeper
./zkServer.sh status #查看zookeeper状态

image-20240410004115488

Dubbo快速入门案例

入门案例参考官网教程

创建项目Dubbo-Demo-Project

在此项目下创建三个子模块

  • common-api 公共接口模块
  • dubbo-consumer 服务消费者模块
  • dubbo-provider 服务提供者模块

项目配置

pom文件配置

对于多模块项目,首先需要在父项目的 pom.xml 里面配置依赖信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
<?xml version="1.0" encoding="UTF-8"?>
<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>com.bang</groupId>
<artifactId>Dubbo-Demo-Project</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>dubbo-provider</module>
<module>dubbo-consumer</module>
<module>common-api</module>
</modules>
<properties>
<dubbo.version>3.2.0-beta.4</dubbo.version>
<spring-boot.version>2.7.8</spring-boot.version>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<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>

<!-- https://mvnrepository.com/artifact/org.apache.dubbo/dubbo-dependencies-zookeeper-curator5 -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-dependencies-zookeeper-curator5</artifactId>
<version>3.2.0-beta.4</version>
<type>pom</type>
</dependency>


</dependencies>
</dependencyManagement>

<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
</plugin>
</plugins>
</pluginManagement>
</build>

</project>

在服务消费者和服务提供者模块中的pom.xml进行如下配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
<?xml version="1.0" encoding="UTF-8"?>
<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>
<parent>
<groupId>com.bang</groupId>
<artifactId>Dubbo-Demo-Project</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>

<artifactId>dubbo-provider</artifactId>

<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<dependencies>
<dependency>
<groupId>com.bang</groupId>
<artifactId>common-api</artifactId>
<version>1.0-SNAPSHOT</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>

</project>
application.yaml文件配置

dubbo-consumer 模块进行如下配置

1
2
3
4
5
6
7
8
dubbo:
application:
name: dubbo-demo-consumer #模块名称
protocol:
name: dubbo
port: -1
registry:
address: zookeeper://192.168.134.129:2181 #服务注册中心zookeeper地址

dubbo-provider 模块进行如下配置

1
2
3
4
5
6
7
8
dubbo:
application:
name: dubbo-demo-provider
protocol:
name: dubbo
port: -1
registry:
address: zookeeper://192.168.134.129:2181

代码逻辑编写

公共模块中编写服务接口

在coomon-api模块下的com/bang/dubbo/demo包下编写服务接口UserService

1
2
3
4
5
package com.bang.dubbo.demo;

public interface UserService {
String sayHello(String name);
}
服务提供模块对公共接口进行实现,提供具体的业务逻辑

在dubbo-provider模块的com/bang/dubbo/demo模块中编写具体接口实现

1
2
3
4
5
6
7
8
9
10
11
package com.bang.dubbo.demo;

import org.apache.dubbo.config.annotation.DubboService;

@DubboService
public class UserServiceImpl implements UserService{
@Override
public String sayHello(String name) {
return "hello,"+name+",welcome to dubbo";
}
}

其中@DubboService 注解,通过这个配置可以基于 Spring Boot 去发布 Dubbo 服务

服务消费模块编写对应的服务调用逻辑

在dubbo-consumer模块的com/bang/dubbo/demo模块中编写具体服务调用代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package com.bang.dubbo.demo;

import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

import java.util.Date;

@Component
public class Task implements CommandLineRunner {
@DubboReference
private UserService userService;

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

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

Task 类中,通过@DubboReference 从 Dubbo 获取了一个 RPC 订阅,这个 userService 可以像本地调用一样直接调用。在 run方法中创建了一个线程进行调用。

编写各个模块启动类

启动类上需添加@EnableDubbo注解

duubo-consumer模块启动类ConsumerApplication
1
2
3
4
5
6
7
8
9
10
11
12
13
14
package com.bang.dubbo.demo;

import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

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

}
dubbo-provider模块启动类ProviderApplication
1
2
3
4
5
6
7
8
9
10
11
12
13
package com.bang.dubbo.demo;

import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

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

测试效果

在服务器上启动zookeeper注册中心

image-20240411002347869

启动服务提供模块

出现下图,即代表服务提供者启动完毕,标志着该服务提供者可以对外提供服务了

image-20240411002436647

启动服务调用模块

出现下图效果,即代表服务消费端启动完毕并调用到服务端成功获取结果

image-20240411002541788