【远程调用框架】如何实现一个简单的RPC框架(二)实现与使用

本文详细介绍了如何实现一个简单的RPC框架,包括服务注册查找中心的设计与接口、LCRPC服务框架的核心部分、服务发布与调用的实现,以及使用示例。重点讲述了服务注册接口、服务信息查询接口的API设计,并提供了服务发布与调用的步骤和代码示例。
摘要由CSDN通过智能技术生成

【如何实现一个简单的RPC框架】系列文章:

【远程调用框架】如何实现一个简单的RPC框架(一)想法与设计
【远程调用框架】如何实现一个简单的RPC框架(二)实现与使用
【远程调用框架】如何实现一个简单的RPC框架(三)优化一:利用动态代理改变用户服务调用方式
【远程调用框架】如何实现一个简单的RPC框架(四)优化二:改变底层通信框架
【远程调用框架】如何实现一个简单的RPC框架(五)优化三:软负载中心设计与实现
第一个优化以及第二个优化修改后的工程代码可下载资源 如何实现一个简单的RPC框架


参考【远程调用框架】如何实现一个简单的RPC框架(一)想法与设计,对应四个模块一共创建了四个Java工程,他们分别是:

  • 【ServiceAccessCenter】:一个Java Web应用,服务注册查找中心

  • 【LCRPC】:LCRPC服务框架的核心部分,最终利用Maven生成一个jar包提供服务发布以及远程调用功能

  • 【LCRPCTest】:服务端的测试部分,发布一个计算器服务

  • 【LCRPCClientTest】:客户端的测试部分,利用服务发布者提供的二方包,远程调用该计算器服务

1. 服务注册查找中心

一个Java Web应用,服务注册查找中心

1.1 接口设计

1.1.1 服务注册接口

  • (1)url:localhost:8080/ServiceAccessCenter/serviceRegistry.do POST请求
  • (2)参数:JSON格式的字符串,如下:
{
"interfaceName":"interfaceName",
"version":"version",
"implClassName":"imlClassName",
"ip":"ip"
}

(3)响应结果:true(代表注册成功)false(代表注册失败)

1.1.2 服务ip地址列表查询接口

  • (1)url:
    localhost:8080/ServiceAccessCenter/queryServiceIPsByID.do?serviceID=interfaceName_version GET请求
  • (2)参数:serviceID 服务的唯一标识
  • (3)响应结果:该服务对应的ip列表数组/空字符串,如下:
["ip","ip"]

1.1.3 服务信息查询接口

  • (1)url:
    localhost:8080/ServiceAccessCenter/queryServiceInfoByID.do?serviceID=interfaceName_version GET请求
  • (2)参数:serviceID 服务的唯一标识
  • (3)响应结果:该服务的所有信息,如下:
{"interfaceName":"interfaceName","version":"version","implClassName":"imlClassName","ips":["ip","ip"],"ip":"ip"}

1.2 类设计

1.2.1 UML类图

这里写图片描述

1.2.2 核心代码

核心代码主要是对注册服务集合的管理,包括增加以及查询。注意多线程操作的问题。
- (1)描述服务信息的DO:ServiceInfoDO

package whu.edu.lcrpc.servicecenter.entity;

/**
 * Created by apple on 17/3/26.
 */

import lombok.Data;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * 服务的描述信息,包括:
 * 服务唯一标识\实现类全限定名\ip地址列表等
 */
@Data
public class ServiceInfoDO {
   

    private String interfaceName;//服务对应接口名称
    private String version;//版本号
    private String implClassName;//实现该接口的类
    private Set<String> ips = new HashSet<>();//该服务的地址
    private String ip;//某一次注册服务的地址
}
  • (2)以一个单例类保存服务信息的集合:
public class ServicesSingle {
   
    private static ServicesSingle servicesSingle = null;
    private Map<String,ServiceInfoDO> services = null;

    private ServicesSingle(){
        services = new ConcurrentHashMap<>();
    }

    public static ServicesSingle getServiceSingle(){
        synchronized (ServicesSingle.class){
            if (servicesSingle == null){
                servicesSingle = new ServicesSingle();
            }
        }
        return servicesSingle;
    }


}
  • (3)对服务信息集合操作的接口:
public interface IServiceAccess {
   
    /**
     * 根据用户提供的服务信息,进行服务的注册
     * @param serviceInfo  要注册的服务信息
     * @return
     */
    public boolean serviceRegistry(ServiceInfoDO serviceInfo);

    /**
     * 根据服务的唯一标识ID查询服务的地址列表
     * @param serviceID
     * @return
     */
    public Set<String> queryServiceIPsByID(String serviceID);

    /**
     * 根据服务的唯一标识ID查询服务的信息
     * @param serviceID
     * @return
     */
    public ServiceInfoDO queryServiceInfoByID(String serviceID);

}
  • (4)接口的实现类:
/**
 * 完成服务的管理操作:注册\查询
 */
public class ServiceAccessImpl implements IServiceAccess{
   
    @Override
    public boolean serviceRegistry(ServiceInfoDO serviceInfo) {
        if (serviceInfo.getInterfaceName() == null || serviceInfo.getInterfaceName().length() ==0 ||
                serviceInfo.getImplClassName() == null || serviceInfo.getImplClassName().length() ==0 ||
                serviceInfo.getVersion() == null || serviceInfo.getVersion().length() ==0 ||
                serviceInfo.getIp() == null || serviceInfo.getIp().length() ==0)
            return false;
        String serviceID = serviceInfo.getInterfaceName() + "_" + serviceInfo.getVersion();
        if (ServicesSingle.getServiceSingle().getServices().containsKey(serviceID)){
            ServicesSingle.getServiceSingle().getServices().get(serviceID).getIps().add(serviceInfo.getIp());
        }else {
            serviceInfo.getIps().add(serviceInfo.getIp());
            ServicesSingle.getServiceSingle().getServices().put(serviceID,serviceInfo);
        }
        return true;
    }

    @Override
    public Set<String> queryServiceIPsByID(String serviceID) {
        if (!ServicesSingle.getServiceSingle().getServices().containsKey(serviceID))
            return null;


        return ServicesSingle.getServiceSingle().getServices().get(serviceID).getIps();
    }

    @Override
    public ServiceInfoDO queryServiceInfoByID(String serviceID) {
        if (!ServicesSingle.getServiceSingle().getServices().containsKey(serviceID))
            return null;


        return ServicesSingle.getServiceSingle().getServices().get(serviceID);
    }
}

2. LCRPC服务框架核心部分

LCRPC服务框架的核心部分,最终利用Maven生成一个jar包提供服务发布以及远程调用功能
整个工程是由maven以及spring开发构建的,是一个Java工程,最终利用maven构建jar包提供用户使用。
pom依赖配置如下:

<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>whu.edu.lcrpc.</groupId>
  <artifactId>lcrpc-core</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>lcrpc-core</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <spring.version>4.3.3.RELEASE</spring.version>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
    <!--spring依赖-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-beans</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>${spring.v
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值