带你手写基于 Spring 的可插拔式 RPC 框架(二)整体结构

前言

上一篇文章中我们已经知道了什么是 RPC 框架和为什么要做一个 RPC 框架了,这一章我们来从宏观上分析,怎么来实现一个 RPC 框架,这个框架都有那些模块以及这些模块的作用。

总体设计

在我们的整个框架里比较重要的几个模块:
rpc-procotol: 既然是可插拔是框架,我们需要支持选择底层协议,这部分是通信协议相关的模块。
rpc-spring: 我们的框架是基于 spring 开发的,这个模块是将我们的一些功能和 spring 整合起来,比如自动注入代理 bean,启动服务端 server 等等。
rpc-register: 注册中心模块,负责服务发现和容错。
rpc-monitor: 将注册中心的信息显示在网页上。
rpc-consumer: 消费端模块,用于测试。
rpc-provider: 服务端模块,用于测试。

  1. 注册中心模块
    对于注册中心来说,可以选择 zookeeper 和 redis,我们只实现了 zookeeper,redis 希望有能力的同学可以在 github 上完善。
    我们在使用 RPC 框架时,服务提供者和服务消费者都需要把自己注册进去,服务消费者可以将服务提供者的信息缓存到本地,通过注册节点删除的回调方法来去掉不可用的服务。
    注册中心代理了我们写 http 请求时手动写地址的功能,帮我们自动找到可用的服务。
  2. 网络协议模块
    服务消费端需要使用接口代理类的 invoke 方法将请求发给服务提供者的 RPC server(双方已经建立好了连接),RPC server 在死循环中一直等待接受请求,收到请求后调用本地的接口实现类进行处理,最后返回结
    果给服务调用端,这样就完成了一个 RPC 服务调用的过程。
    RPC 底层网络通信协议包括三个实现,netty 实现的客户端和服务端,http + Tomcat 实现的客户端和服务端,最后时 Socket 实现的客户端和服务端(性能比较低,编程练习使用)。
  3. 整合 Spring 模块
    我们整个框架是和 Spring 整合在一起的,我们在 Spring 中自定义的一些注解(类似与 Dubbo),自动为接口成代理类并注入到了 Spring 容器中,在代码中使用 @Autowired 自动注入即可使用。RPC server 的启动也要依靠 Spring 来帮我们完成。
  4. 监控模块
    通过这个模块可以查看所有服务的状态以及接口调用的相关信息。
  5. 测试模块
    rpc-provider 和 rpc-consumer 都是测试类,方便于我们对代码进行测试。

效果展示

我们先提前来看看最后最后的效果,首先说明,性能表现测试根据不同的机器和不同的网络环境可能会有所不同,下面的测试结果是基于我自己的机器的。 我的电脑最多起 2000 个并发线程,多了就 OOM 了,在公司的电脑尝试过起 10000 个并发线程,没有任何问题,下面看 2000 个并发线程的表现。

测试类

    public static void main(String[] args) throws Exception {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("rpc.xml");
        //并行度10000
        int parallel = 2000;

        //开始计时
        long a1 = System.currentTimeMillis();

        CountDownLatch signal = new CountDownLatch(1);
        CountDownLatch finish = new CountDownLatch(parallel);

        for (int index = 0; index < parallel; index++) {
            CalcParallelRequestThread client = new CalcParallelRequestThread(signal, finish, index,applicationContext);
            new Thread(client).start();
        }

        //n个并发线程瞬间发起请求操作
        signal.countDown();
        finish.await();

        long a2 = System.currentTimeMillis();

        String tip = String.format("RPC调用总共耗时: [%s] 毫秒", a2 - a1);
        System.out.println(tip);

    }

2000 并发 1秒多,还是比较快的。感兴趣的可以试试在自己的电脑起 1w 或者 10w 加线程测试一下。

原文地址:https://www.cnblogs.com/paulwang92115/p/11116929.html

时间: 2024-10-11 18:20:43

带你手写基于 Spring 的可插拔式 RPC 框架(二)整体结构的相关文章

带你手写基于 Spring 的可插拔式 RPC 框架(一)介绍

概述 首先这篇文章是要带大家来实现一个框架,听到框架大家可能会觉得非常高大上,其实这和我们平时写业务员代码没什么区别,但是框架是要给别人使用的,所以我们要换位思考,怎么才能让别人用着舒服,怎么样才能让我们的框架性能优异.通过自己写一个框架,我们能学到的有很多,能让我们脱离 CURD,在更高的层面上去思考. 目的 写这个框架最主要的目的是要让大家了解整个框架的设计思想和用到的技术,并不是让大家关注代码,当然我实现的代码一定不是完美的,还有很多需要改进的地方,希望大家不吝赐教,一起进步. 提前准备

带你手写基于 Spring 的可插拔式 RPC 框架(五)注册中心

注册中心代码使用 zookeeper 实现,通过图片来看看我们注册中心的架构. 首先说明, zookeeper 的实现思路和代码是参考架构探险这本书上的,另外在 github 和我前面配置文件中的 zookeeper 服务器是用的1个月免费适用的阿里云,大家也可以用它当测试用. 不多说,一次性给出注册中心全部代码. 客户端对应的注册中心接口 public interface RegisterCenter4Consumer { /** * 消费端初始化服务提供者信息本地缓存 */ public v

带你手写基于 Spring 的可插拔式 RPC 框架(三)通信协议模块

在写代码之前我们先要想清楚几个问题. 我们的框架到底要实现什么功能? 我们要实现一个远程调用的 RPC 协议. 最终实现效果是什么样的? 我们能像调用本地服务一样调用远程的服务. 怎样实现上面的效果? 前面几章已经给大家说了,使用动态代理,在客户端生成接口代理类使用,在代理类的 invoke 方法里面将方法参数等信息组装成 request 发给服务端,服务端需要起一个服务器一直等待接收这种消息,接收之后使用反射调 用对应接口的实现类. 首先我们需要实现底层的通信的服务端和客户端,可以有一下几种实

带你手写基于 Spring 的可插拔式 RPC 框架(四)代理类的注入与服务启动

上一章节我们已经实现了从客户端往服务端发送数据并且通过反射方法调用服务端的实现类最后返回给客户端的底层协议. 这一章节我们来实现客户端代理类的注入. 承接上一章,我们实现了多个底层协议,procotol 有 netty,http,和 socket 三个实现类,每个实现类都有启动服务端和客户端发送数据两个方法. 问题 如何实现底层协议的选择那? 可以通过配置文件来选择协议. 单独的配置文件还是和 Spring 的配置文件结合起来那? 我们选择与 Spring 结合的配置文件,自定义一些属性的标签,

基于Spring开发的一个BIO-RPC框架(对小白很友好)

PART1:先来整体看下项目的构成 其中bio-rpc-core就是所谓的rpc框架 bio-rpc-example-client即所谓的服务调用方(你的项目中想要调用服务的地方) bio-rpc-example-server即所谓的服务提供方(你的项目中写好服务想要供别人调用的地方) github地址:https://github.com/Luyu05/BioRpcExample PART2:这个框架咋用? 服务使用方 1.首先,在想要调用服务的地方(bio-rpc-example-clien

手写MyBatis,纯手工打造开源框架(第四篇:决胜千里)- 第272篇

说明 MyBatis版本:3.5.1 相关历史文章(阅读本文之前,您可能需要先看下之前的系列) Spring Boot MyBatis最全教程:你值得拥有MyBatis能脱离Spring吗一图纵览MyBatis的工作原理从源码看MyBatis,竟如此简单MyBatis的Mapper是什么`垃圾` 手写MyBatis,纯手工打造开源框架(第一篇:风云再起) 手写MyBatis,纯手工打造开源框架(第二篇:君临天下) 手写MyBatis,纯手工打造开源框架(第三篇:运筹帷幄) 前言        运

携程系统架构师带你手写spring mvc,解读spring核心源码!

讲师简介: James老师 系统架构师.项目经理 十余年Java经验,曾就职于携程.人人网等一线互联网公司,专注于java领域,精通软件架构设计,对于高并发.高性能服务有深刻的见解, 在服务化基础架构和微服务技术有大量的建设和设计经验. 课程内容: 1.为什么读Spring源码? 如果你是一名JAVA开发人员,你一定用过Spring Framework. 作为一款非常经典的开源框架,从2004年发布的1.0版本到现在的5.0版本,经历了14年的洗礼, 持久不衰 与其说现在是JAVA的天下, 不如

手写基于Promise A+规范的Promise

const PENDING = 'pending';//初始态const FULFILLED = 'fulfilled';//初始态const REJECTED = 'rejected';//初始态function Promise(executor){ let self = this;//先缓存当前promise实例 self.status = PENDING;//设置状态 //定义存放成功的回调的数组 self.onResolvedCallbacks = []; //定义存放失败回调的数组 s

58同城架构师带你手写Kafka流处理技术

Kakfa介绍 Kafka是什么 Kafka最初是LinkedIn的内部内部基础设施系统.它被认为是一个流平台,在Kafka上可以发布和订阅流数据,并把它们保存起来.进行处理.但是我们在使用Kafka中,最多的就是将它作为一个消息系统使用,类似于ActiveMQ.RabbitMQ等.但是Kafka与这些传统的消息系统又有着许多的不同点,这些差异使它又不同于消息系统. Kafka是一个分布式系统,以集群(支持自由伸缩)的方式运行.(所以我们总称为分布式消息队列) Kafka可以用来存储数据,数据存