七的博客

手写RPC框架系列(二) - 搭建RPC框架基础工程

RPC手写系列

手写RPC框架系列(二) - 搭建RPC框架基础工程

通过上一章节中,我们学习了 RPC 的基本理论以及结构。 这个章节将开始实际的动手操作,搭建我们的 RPC 框架基础工程。

章节的大致内容如下:

  • 项目的基本结构
  • 初始化核心模块
  • 初始化客户端例子模块
  • 初始化服务端例子模块
  • 初始化 RPC 服务接口模块

1. 本章前置知识

  • 具备基础的 Java 语言基础。
  • 掌握 Maven 的基本概念以及依赖传递等特性。

2. 项目结构预览

首先先创建一个 Java 项目,这里我们使用 Maven 作为构建工具。 创建一个多模块的 Maven 项目, 包含以下几个模块:

  • rpc-core: RPC 框架的核心实现,包括网络通信、服务代理等。
  • rpc-example : RPC 例子聚合 pom 模块,子模块包括客户端模块、服务端模块、服务接口模块。
  • rpc-example-api: RPC 服务接口定义。
  • rpc-example-client: RPC 客户端实现,用于发起远程调用。
  • rpc-example-server:RPC 服务端实现,用于处理客户端请求、

总体项目结构

目录结构如下:

.
├── pom.xml   // 聚合模块pom
├── rpc-core  // rpc核心模块,客户端跟服务端共享模块
│   ├── pom.xml
│   └── src
├── rpc-example  // rpc例子
   ├── pom.xml
   ├── rpc-example-api  // rpc接口模块
   │   ├── pom.xml
   │   └── src
   │   
   ├── rpc-example-client  // rpc客户端例子
   │   ├── pom.xml
   │   └── src
   │   
   └── rpc-example-server  // rpc服务端例子
       ├── pom.xml
       └── src

3. 创建目录结构

下面开始在 IDE 中创建工程,并逐步添加模块。

3.1. 初始化父聚合 pom 模块

父聚合模块的作用主要是可以更好的管理子模块,子模块包括:

  • rpc-core
  • rpc-example

引入的 Maven 依赖有:

  • fastjson: JSON 相关的工具类。
  • lombok: 用于简化实体类的 get、set 等方法。

示例 pom.xml 如下:

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>spring-boot-starter-parent</artifactId>
        <groupId>org.springframework.boot</groupId>
        <version>2.3.7.RELEASE</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.suny.rpc</groupId>
    <artifactId>netty-rpc</artifactId>
    <packaging>pom</packaging>
    <version>1.0.0-SNAPSHOT</version>
    <name>netty-rpc</name>
    <description>rpc 项目</description>
    
    
    // 定义两个子模块
     <modules>
        <module>rpc-core</module>
        <module>rpc-example</module>
    </modules>

    // 定义版本
    <properties>
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <spring-boot.version>2.3.7.RELEASE</spring-boot.version>
    </properties>

    <dependencies>
        // json 序列化以及反序列化工具
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.72</version>
        </dependency>

       // apache 工具类
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.1</version>
        </dependency>

       // 简化 set get 等
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

       // springboot 测试依赖
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>


    </dependencies>

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

            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter</artifactId>
                <version>${spring-boot.version}</version>
            </dependency>
        </dependencies>

    </dependencyManagement>

</project>



3.2 初始化 rpc-core 模块

rpc-core 模块的主要作用是网络通信、服务代理等。这里模块声明为父模块 netty-rpc 的子模块,同时打包方式为 jar 。

引入的 Maven 依赖有:

  • commons-lang3: Apache 封装的工具类模块。

  • commons-collections: Apache 封装的集合相关的工具类模块。

  • netty-all: 用于网络通信。

  • spring-context:项目是结合 Spring 进行使用,引入 context 模块使用。

  • slf4j-api: 日志门面库。

  • curator-recipes: Zookeeper 的客户端 SDK。

示例 pom.xml 如下:

<?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>
        <artifactId>netty-rpc</artifactId>
        <groupId>com.suny.rpc</groupId>
        <version>1.0.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>rpc-core</artifactId>
    <packaging>jar</packaging>
    <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>

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

    <dependencies>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
        </dependency>
        <dependency>
            <groupId>commons-collections</groupId>
            <artifactId>commons-collections</artifactId>
            <version>3.2.2</version>
        </dependency>

        <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty-all</artifactId>
            <version>4.1.45.Final</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
        </dependency>


        <!--  zookeeper 客户端-->
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-recipes</artifactId>
            <version>4.2.0</version>
            <exclusions>
                <exclusion>
                    <groupId>org.apache.zookeeper</groupId>
                    <artifactId>zookeeper</artifactId>
                </exclusion>
            </exclusions>
        </dependency>


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

    </dependencies>

</project>

3.3. 初始化 rpc-example 模块

rpc-example 模块的作用主要是管理例子相关的子模块,子模块包括:

  • rpc-example-client: 客户端例子
  • rpc-example-server:服务端例子
  • rpc-example-api:服务接口相关

示例 pom.xml 如下:

<?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>
        <artifactId>netty-rpc</artifactId>
        <groupId>com.suny.rpc</groupId>
        <version>1.0.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>rpc-example</artifactId>
    <packaging>pom</packaging>

    <modules>
        <module>rpc-example-client</module>
        <module>rpc-example-server</module>
        <module>rpc-example-api</module>
    </modules>

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

</project>


3.4 初始化 rpc-example-api 模块

rpc-example-api 模块的主要作用是将客户端以及服务端公用的实体类、接口定义等抽取出来的公共模块,可以方便调用方的使用。

示例 pom.xml 如下:

<?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>
        <artifactId>rpc-example</artifactId>
        <groupId>com.suny.rpc</groupId>
        <version>1.0.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>rpc-example-api</artifactId>
    <packaging>jar</packaging>

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

</project>

3.5. 初始化 rpc-example-server 模块

rpc-example-server 模块是服务端例子模块,模块讲解服务端怎么暴露一个服务接口给客户端。这里需要注意的是,服务端模块是一个 Spring Boot 的应用,所以需要引入 spring-boot-starter 依赖。

示例 pom.xml 如下:

<?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>
        <artifactId>rpc-example</artifactId>
        <groupId>com.suny.rpc</groupId>
        <version>1.0.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>rpc-example-server</artifactId>
    <packaging>jar</packaging>

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

    <dependencies>
        <dependency>
            <groupId>com.suny.rpc</groupId>
            <artifactId>rpc-core</artifactId>
            <version>1.0.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>com.suny.rpc</groupId>
            <artifactId>rpc-example-api</artifactId>
            <version>1.0.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.3.7.RELEASE</version>
                <configuration>
                    <mainClass>com.suny.rpc.nettyrpc.server.RpcServerApplication</mainClass>
                </configuration>
                <executions>
                    <execution>
                        <id>repackage</id>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

3.6. 初始化 rpc-example-client 模块

rpc-example-client 模块是客户端例子模块,模块讲解服务端怎么调用一个服务端的服务接口。这里需要注意的是,客户端模块是一个 Spring Boot 的应用,所以需要引入 spring-boot-starter 依赖。

示例 pom.xml 如下:

<?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>
        <artifactId>rpc-example</artifactId>
        <groupId>com.suny.rpc</groupId>
        <version>1.0.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>rpc-example-client</artifactId>

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

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.suny.rpc</groupId>
            <artifactId>rpc-core</artifactId>
            <version>1.0.0-SNAPSHOT</version>
        </dependency>

        <dependency>
            <groupId>com.suny.rpc</groupId>
            <artifactId>rpc-example-api</artifactId>
            <version>1.0.0-SNAPSHOT</version>
        </dependency>

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

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.3.7.RELEASE</version>
                <configuration>
                    <mainClass>com.suny.rpc.nettyrpc.client.NettyRpcApplication</mainClass>
                </configuration>
                <executions>
                    <execution>
                        <id>repackage</id>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

4. 总结

这个章节主要是介绍 RPC 框架工程的基本搭建流程,包括项目结构设置、关键依赖配置。截止到目前,我们暂时还没有开始编写相关的代码,在后续的章节中,将逐步开始编写相关的代码。