从零写分布式RPC框架 系列 1.0 (5)整合测试

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/alinyua/article/details/83863043

本篇将对前面几篇模块作整合处理,使用spring-boot-starter的形式进行发布。然后新建 examples 工程模块对其测试使用。

系列文章:

从零写分布式RPC框架 系列 1.0 (1)架构设计
从零写分布式RPC框架 系列 1.0 (2)RPC-Common模块设计实现
从零写分布式RPC框架 系列 1.0 (3)RPC-Server模块设计实现
从零写分布式RPC框架 系列 1.0 (4)RPC-Client模块设计实现
从零写分布式RPC框架 系列 1.0 (5)整合测试
使用gpg插件发布jar包到Maven中央仓库 完整实践

一 创建spring-boot-starter模块

创建RPC-Server和RPC-Client对应的spring-boot-starter模块如下,只依赖了对应的spring-boot-autoconfigure,可以将其视为spring-boot-autoconfigure的包装,两者的区别还在于一些依赖没有被传递到spring-boot-starter来,不过使用起来没有区别
spring-boot-starter

二 在主工程添加部署到Maven中央仓库的配置

如果只是想在本地玩玩的话,使用install就好,没必要deploy,另外如果由于测试过程自动开启RPC服务器等待连接导致测试不会结束,可以直接使用-Dmaven.test.skip=true跳过测试阶段。

在主工程pom文件中添加如下信息:developers,scm,licenses,distributionManagement还有相关插件,代码较多,这里就不贴出来了。感兴趣的也可以直接到GitHub查看本项目,具体配置方法见使用gpg插件发布jar包到Maven中央仓库 完整实践,该文章即以本项目为例。

三 新建examples工程

新建examples工程,包含3个模块:

  • rpc-lib
    rpc接口模块,定义RPC服务提供者和RPC消费者公用的接口规范
  • rpc-provider
    rpc服务提供者模块,负责服务实现,并对外提供RPC调用服务
  • rpc-consumer
    rpc服务消费者模块,负责服务消费,通过rpc-lib的契约(接口)向rpc-provider调用服务实现。

主工程pom文件如下:

  1. spring-cloud-dependencies是spring-cloud的依赖管理模块,也可以去掉
  2. rpc-lib是rpc-provider和rpc-consumer共同依赖的模块,所以放在这里维持版本统一
  3. rpc-netty-server-spring-boot-starter和rpc-netty-client-spring-boot-starter则是我们的项目,也是实现RPC的核心依赖
  4. 最后面我还加上了repository地址,在项目deploy到中央仓库之前会先加入这个仓库,所以这个仓库可以更快拉取的最新发现jar包,对于调试来说就不用再等了,日常使用中可以去掉。
<?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.github.linshenkx.test</groupId>
    <artifactId>rpc-netty-spring-boot-starter-examples</artifactId>
    <version>1.0.5.RELEASE</version>
    <packaging>pom</packaging>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.5.RELEASE</version>
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <spring-cloud.version>Finchley.SR2</spring-cloud.version>
        <spring-boot.version>${project.parent.version}</spring-boot.version>
        <rpc-netty-linshen.version>1.0.5.RELEASE</rpc-netty-linshen.version>
    </properties>

    <modules>
        <module>rpc-lib</module>
        <module>rpc-provider</module>
        <module>rpc-consumer</module>
    </modules>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!--公共rpc模块-->
            <dependency>
                <groupId>com.github.linshenkx.test</groupId>
                <artifactId>rpc-lib</artifactId>
                <version>${project.version}</version>
            </dependency>
            <!--核心rpc-netty-spring-boot依赖-->
            <dependency>
                <groupId>com.github.linshenkx</groupId>
                <artifactId>rpc-netty-client-spring-boot-starter</artifactId>
                <version>${rpc-netty-linshen.version}</version>
            </dependency>
            <dependency>
                <groupId>com.github.linshenkx</groupId>
                <artifactId>rpc-netty-server-spring-boot-starter</artifactId>
                <version>${rpc-netty-linshen.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <repositories>
        <repository>
            <id>sonatype-repository</id>
            <name>sonatype-repository</name>
            <url>https://oss.sonatype.org/content/groups/staging</url>
            <releases>
                <enabled>true</enabled>
            </releases>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
    </repositories>

</project>

四 编写 rpc-lib 模块

该模块只提供接口,故无需依赖什么。

结构及pom文件

结构

HelloService 接口

public interface HelloService {
  String say(String name);
}

五 编写rpc-provider模块

该模块负责服务提供,这里我写了两个 profile的application配置文件(slave1和slave2),模拟rpc-provider的集群。

结构及pom文件

结构

HelloService实现类

@RpcService(HelloService.class)
public class HelloServiceImpl implements HelloService {

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

}

application文件

如下,application.yml 提供公共配置,各个slave提供个性化配置。默认使用slave1。
另外,需要注意,这里并没有指定server.port,也没有引入spring-web依赖,即该服务不是web服务,使用的是我们自己实现的RPC协议。
如果rpc-provider部署在不同的集群上,则使用一个aplication.yml即可,这里因为是伪集群,所以需要提供profile指定不同端口。

########### application.yml ###############
zk:
  addressList:
    - IP:2181
    - IP:2182
    - IP:2183
  connectTimeOut: 10000
  sessionTimeOut: 10000
  registryPath: "/defaultRegistry"
spring:
  profiles:
    active: slave1
########### application-slave1.yml ###############
rpc:
  server:
    port: 9991
########### application-slave2.yml ###############
rpc:
  server:
    port: 9992

六 编写 rpc-consumer 模块

该模块依赖和rpc-provider基本一致,只是多了spring-boot-starter-web,application则对应多了server.port。另外需要注意,application不需要指定rpc.server.port,指定了也没有用,服务地址是依靠服务发现获取的。

结构及application文件

结构

HelloController

这里我还用了org.springframework.util提供的 计时器 进行服务计时,小小地测试性能。

/**
 * @version V1.0
 * @author: lin_shen
 * @date: 2018/11/1
 * @Description: TODO
 */
@RestController
@Log4j2
public class HelloController {
    @Autowired
    private RpcClient rpcClient;

    @GetMapping("/hello")
    public String sayHello(@RequestParam(defaultValue = "lin") String name){
        StopWatch stopwatch = new StopWatch();
        stopwatch.start();
        HelloService helloService= rpcClient.create(HelloService.class);
        String returnString= helloService.say(name);
        stopwatch.stop();
        log.info("耗时:"+stopwatch.getTotalTimeSeconds()+"seconds");
        return returnString;
    }

}

七 项目测试

测试之前应先将公共模块 rpc-lib install到本地,然后再把整个examples install 到本地。
然后依次启动 rpc-provider-slave1、rpc-provider-slave2和rpc-consumer
可以根据打印的日志判断启动是否符合预期,如下为slave1的启动信息

可以看到其服务注册地址为:/defaultRegistry/com.github.linshenkx.rpclib.HelloService/address-0000000036
自身服务地址为: 192.168.200.1:9991
slave1
这个时候分别打开链接 http://localhost:9090/hello?name=linShen1http://localhost:9090/hello?name=linShen2http://localhost:9090/hello?name=linShen3等,可以顺利获得对应的 hello信息。
另外,查看两个slave的控制台输出,可以发现请求被随机转发到所有的slave下,即实现了负载均衡(其实算不上,只是随机选择而已)。

另外这个项目1.0版本性能较差,根据测试,第一次请求大概耗时11s(需要到ZK集群获取服务信息生成动态代理类,再建立RPC连接获取结果),之后耗时都是5s多。

猜你喜欢

转载自blog.csdn.net/alinyua/article/details/83863043
今日推荐