分布式–记一次搭建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 这样效率更高。
创建整个文件结构
第一步:创建一个空项目
第二步:创建 service、consumer、provider 三个 Module Maven 工程
- 快捷键 crtl + alt + shift + s,打开 Projcet Structure 界面,点击加号创建
第三步:编写 Service
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/> </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> <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> <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>
|
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
按照上面的步骤再创建一个 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/> </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> <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
1 2 3
| @Mapper public interface StudentMapper extends BaseMapper<Student> { }
|
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.application.name=MyDubbo_provider dubbo.registry.protocol=zookeeper dubbo.registry.address=zookeeper://127.0.0.1:2181
dubbo.protocol.name=dubbo dubbo.protocol.port=20880
dubbo.scan.base-packages=com.archiver.provider.**.service
package.base=com.archiver.service
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
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,来与前台进行交互
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/> </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.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
测试
这样就注册到了 zk 中,接下来也访问成功,那么整个基础框架就搭好了。