目录
  1. 1. 分布式–记一次搭建RPC框架
    1. 1.1. 写在前面
    2. 1.2. 创建整个文件结构
      1. 1.2.1. 第一步:创建一个空项目
      2. 1.2.2. 第二步:创建 service、consumer、provider 三个 Module Maven 工程
      3. 1.2.3. 第三步:编写 Service
        1. 1.2.3.1. Pom 文件
        2. 1.2.3.2. Entity
        3. 1.2.3.3. Service 接口
      4. 1.2.4. 第四步:编写 provider
        1. 1.2.4.1. Pom文件(注意里面要依赖 service 项目)
        2. 1.2.4.2. ServiceImpl
        3. 1.2.4.3. mapper
        4. 1.2.4.4. application.properties
      5. 1.2.5. 第五步:编写 consumer
        1. 1.2.5.1. Pom 文件
        2. 1.2.5.2. RestController
        3. 1.2.5.3. application.properties
      6. 1.2.6. 第六步:下载 zk-ui
    3. 1.3. 测试
分布式--记一次搭建RPC框架

分布式–记一次搭建RPC框架

基于 Springboot + zookeeper + dubbo 框架,所用 IDE 为 IDEA

写在前面

  整体结构并不复杂,provider 和 consumer 都依赖于 service 项目,在 service 中我们可以创建一些共用的组件,比如说工具类、BaseEntity、AjaxResult 等等。然后就是一些实体类和规定对应的 servcie 接口,并不提供实现方法。而 provider 中则负责实现 service 中的接口并有对数据库进行操作的 mapper 及 xml 文件。consumer 就负责与前端数据做交互,里面有 RestController 。在 consumer 和 provider 中都需要通过 dubbo 与 zookeeper 建立连接。

  • zookeeper 开放 2181 端口给 provider、consumer、dubbo-admin
  • provider的20880开放给所有consumer,但8080服务器端口可以完全屏蔽
  • consumer的8080开放给所有provider
  • dubbo-admin的8080开放给管理员用户,便于通过浏览器监控注册中心服务的情况

  consumer 向 zk 订阅服务,provider 向 zk 注册服务。zk 接受到新注册的服务会告知订阅服务的 consumer,而这时消费者和生产者之间就变成了点对点的通信是由 consumer 直接调用 provider,不经过 zk 这样效率更高。

20160823142315665

image-20200306102929880

创建整个文件结构

第一步:创建一个空项目

image-20200306101355511

第二步:创建 service、consumer、provider 三个 Module Maven 工程

  • 快捷键 crtl + alt + shift + s,打开 Projcet Structure 界面,点击加号创建

image-20200306102139824

  • 创建一个 Maven 项目

image-20200306114848933

第三步:编写 Service

image-20200306103307682

Pom 文件

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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
<?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.archiver.dubbo</groupId>
<artifactId>service</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.7.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<java.version>1.8</java.version>
<dubbo.version>2.7.3</dubbo.version>
</properties>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>8</source>
<target>8</target>
</configuration>
</plugin>
</plugins>
</build>

<dependencies>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus</artifactId>
<version>3.1.0</version>
</dependency>
<!--commons -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.6</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.5</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.54</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>

<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>${dubbo.version}</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
</exclusions>
</dependency>

<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
<version>${dubbo.version}</version>
</dependency>

<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>4.0.1</version>
</dependency>

<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>2.8.0</version>
</dependency>
</dependencies>
</project>
  • common 中写一些共用的组件

Entity

然后按照自己的习惯创建一个实体类,必须实现序列化接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Data
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
@TableName("t_student")
public class Student extends BaseEntity {

private static final long serialVersionUID = 2L;

@TableField("user_name")
String userName;

@TableField("sex")
String sex;

@TableField("status")
String status;
}

Service 接口

这里我用的是 mybatis-plus

1
2
3
4
public interface IStudentService extends IService<Student> {

List<Student> index(Student student);
}

第四步:编写 provider

image-20200306103339341

按照上面的步骤再创建一个 module 名字是 provider,这里写具体的实现方法以及对应 mapper

Pom文件(注意里面要依赖 service 项目)

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
<?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>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.7.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>

<groupId>com.archiver.dubbo</groupId>
<artifactId>provider</artifactId>
<version>1.0-SNAPSHOT</version>

<dependencies>
<dependency>
<groupId>com.archiver.dubbo</groupId>
<artifactId>service</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!-- Druid数据源 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.10</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.1.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

</project>

ServiceImpl

  • 注意这里的注解不是 mvc 中的注解,是 dubbo 中的 service 注解
1
2
3
4
5
6
7
8
9
10
11
12
import org.apache.dubbo.config.annotation.Service;

@Service
public class StudentServiceImpl extends ServiceImpl<StudentMapper, Student> implements IStudentService {

@Override
public List<Student> index(Student student) {
//这里我只让他在控制台输出了一句话
System.out.println("冲冲冲");
return null;
}
}

mapper

  • StudentMapper
1
2
3
@Mapper
public interface StudentMapper extends BaseMapper<Student> {
}
  • StudentMapper.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.archiver.provider.student.mapper.StudentMapper">
<resultMap id="BaseResultMap" type="com.archiver.service.student.entity.Student">
<id column="id" jdbcType="INTEGER" property="id" />
<id column="user_name" jdbcType="VARCHAR" property="userName" />
<id column="sex" jdbcType="VARCHAR" property="sex" />
<id column="status" jdbcType="VARCHAR" property="status" />

</resultMap>
<sql id="Base_Column_List">
id,
user_name, sex, status
</sql>

application.properties

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
# dubbo连接zookeeper配置
dubbo.application.name=MyDubbo_provider
dubbo.registry.protocol=zookeeper
dubbo.registry.address=zookeeper://127.0.0.1:2181
# dubbo服务注册配置
dubbo.protocol.name=dubbo
dubbo.protocol.port=20880
# 这个是扫描服务的实现类
dubbo.scan.base-packages=com.archiver.provider.**.service

package.base=com.archiver.service
#mybatis-plus配置
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
mybatis-plus.type-aliases-package=${package.base}.entity
mybatis-plus.mapper-locations=classpath:mapper/**/*Mapper.xml

#druid 连接池配置
spring.datasource.druid.url=jdbc:mysql://127.0.0.1:3307/byte_easy?useUnicode=true&characterEncoding=utf-8&serverTimezone=CTT
spring.datasource.druid.username=root
spring.datasource.druid.password=123456
spring.datasource.druid.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.druid.initial-size=5
spring.datasource.druid.max-active=30
spring.datasource.druid.min-idle=5
spring.datasource.druid.max-wait=60000
spring.datasource.druid.time-between-eviction-runs-millis=60000
spring.datasource.druid.min-evictable-idle-time-millis=300000
spring.datasource.druid.validation-query=SELECT 1 FROM DUAL
spring.datasource.druid.test-while-idle=true
spring.datasource.druid.test-on-borrow=false
spring.datasource.druid.test-on-return=false
spring.datasource.druid.pool-prepared-statements=true
spring.datasource.druid.max-pool-prepared-statement-per-connection-size=50
spring.datasource.druid.filters=stat,wall
spring.datasource.druid.connection-properties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
spring.datasource.druid.use-global-data-source-stat=true
spring.datasource.druid.stat-view-servlet.login-username=admin
spring.datasource.druid.stat-view-servlet.login-password=123456
spring.datasource.druid.web-stat-filter.exclusions=*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*

第五步:编写 consumer

消费者就相当于一个 controller,来与前台进行交互

image-20200306103404021

Pom 文件

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
<?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">
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.7.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>consumer</artifactId>

<properties>
<java.version>1.8</java.version>
</properties>

<dependencies>
<dependency>
<groupId>com.archiver.dubbo</groupId>
<artifactId>service</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

RestController

  • 这里也要注意 @Reference 注解,我们平常是 @AutoWired 注解,这里要使用 dubbo 的注解
1
2
3
4
5
6
7
8
9
10
11
12
13
14
@RestController
@RequestMapping("rest/student")
public class RestStudentController {

@Reference
private IStudentService studentService;

@RequestMapping
public AjaxResult index(Student student){

studentService.index(student);
return AjaxResult.success();
}
}

application.properties

1
2
3
4
5
server.port=8085
#dubbo配置
dubbo.application.name=MyDubbo_consumer
dubbo.registry.protocol=zookeeper
dubbo.registry.address=zookeeper://127.0.0.1:2181

第六步:下载 zk-ui

  OK 至此我们完成了基础项目的搭建,为了能更好的直观的看到 zk 中的服务,来管理 zk,我们还需要一个可视化的 zk 管理界面工具,这里用的是 zk-ui。项目连接

  这个下载下来直接启动就好,端口号是 9090,账号:admin,密码:manager

测试

  • 访问消费者 controller

image-20200306122541420

  • 登录 zk-ui

image-20200306122615455

这样就注册到了 zk 中,接下来也访问成功,那么整个基础框架就搭好了。

文章作者: Archiver
文章链接: https://www.kaiming66.com/2020/03/06/Distributed/%E5%88%86%E5%B8%83%E5%BC%8F--%E8%AE%B0%E4%B8%80%E6%AC%A1%E6%90%AD%E5%BB%BARPC%E6%A1%86%E6%9E%B6/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Archiver`s Blog
打赏
  • 微信
  • 支付寶

评论