前言

上一篇文章中我们已经知道了什么是 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 加线程测试一下。

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

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

    概述 首先这篇文章是要带大家来实现一个框架,听到框架大家可能会觉得非常高大上,其实这和我们平时写业务员代码没什么区别,但是框架是要给别人使用的,所以我们要换位思考,怎么才能让别人用着舒服,怎么样才能让 ...

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

    注册中心代码使用 zookeeper 实现,我们通过图片来看看我们注册中心的架构. 首先说明, zookeeper 的实现思路和代码是参考架构探险这本书上的,另外在 github 和我前面配置文件中的 ...

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

    在写代码之前我们先要想清楚几个问题. 我们的框架到底要实现什么功能? 我们要实现一个远程调用的 RPC 协议. 最终实现效果是什么样的? 我们能像调用本地服务一样调用远程的服务. 怎样实现上面的效果? ...

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

    上一章节我们已经实现了从客户端往服务端发送数据并且通过反射方法调用服务端的实现类最后返回给客户端的底层协议. 这一章节我们来实现客户端代理类的注入. 承接上一章,我们实现了多个底层协议,procoto ...

  5. C基础 带你手写 redis sds

    前言 - Simple Dynamic Strings  antirez 想统一 Redis,Disque,Hiredis 项目中 SDS 代码, 因此构建了这个项目 https://github.c ...

  6. C基础 带你手写 redis adlist 双向链表

    引言 - 导航栏目 有些朋友可能对 redis 充满着数不尽的求知欲, 也许是 redis 属于工作, 交流(面试)的大头戏, 不得不 ... 而自己当下对于 redis 只是停留在会用层面, 细节层 ...

  7. 第二篇 基于.net搭建热插拔式web框架(沙箱的构建)

    上周五写了一个实现原理篇,在评论中看到有朋友也遇到了我的问题,真的是有种他乡遇知己的感觉,整个系列我一定会坚持写完,并在最后把代码开源到git中.上一篇文章很多人看了以后,都表示不解,觉得不知道我到底 ...

  8. 第三篇 基于.net搭建热插拔式web框架(重造Controller)

    由于.net MVC 的controller 依赖于HttpContext,而我们在上一篇中的沙箱模式已经把一次http请求转换为反射调用,并且http上下文不支持跨域,所以我们要重造一个contro ...

  9. 基于Protobuf的分布式高性能RPC框架——Navi-Pbrpc

    基于Protobuf的分布式高性能RPC框架——Navi-Pbrpc 二月 8, 2016 1 简介 Navi-pbrpc框架是一个高性能的远程调用RPC框架,使用netty4技术提供非阻塞.异步.全 ...

随机推荐

  1. vue 配置CDN加速

    1.首先index.html 中配置cdn 引入 <!-- 引入样式 --> <link rel="stylesheet" href="//cdn.bo ...

  2. shiro框架的UsernamePasswordToken与对应Realm中的AuthenticationToken的一点比较(转)

    这里以简单的登陆为例子 控制器对应的登陆方法: @RequestMapping(value = "/login", method = RequestMethod.GET) publ ...

  3. 爬取前尘无忧python职位信息并保存到mongo数据库

    1.re实现 import re,os import requests from requests.exceptions import RequestException MAX_PAGE = 10 # ...

  4. 014_STM32程序移植之_L298N电机驱动模块

    更改注意: STM32程序移植之L298N电机驱动模块 引脚连接图 STM32引脚 L298N引脚 功能 PA6 ENA 马达A的PWM PA7 ENB 马达B的PWM PA2 IN1 控制马达A P ...

  5. 数值(Number,Math, 运算符)

    1.js中数字 1.数字存储 Javascript中所有数字的存储都是64位浮点数.整数也一样. 1 === 1.0 // true 2. 数字大小范围 可以表示的最大正数和最小负数 (-Math.p ...

  6. luogu 2114 [NOI2014]起床困难综合症 位运算+贪心

    感觉这个思路非常巧妙啊~ code: #include <bits/stdc++.h> #define ll long long #define setIO(s) freopen(s&qu ...

  7. bzoj 1924

    所用点的编号为输入顺序,因为只有在存在联通门的宫室中存在宝藏.其余点不考虑 对于每一行,选定一个横天门,向该行横天门连双向边,其余门单向边纵列同理自.由门用map判周围八个点是否存在,存在即连边 Ta ...

  8. [HNOI2008] 越狱 快速幂

    [HNOI2008] 越狱 快速幂 水.考虑不发生越狱的情况:即宗教相同的都不相邻,一号任意放\(m\)种宗教的人,此后\(n-1\)个房间都放与上一个宗教不同的人,有\(m-1\)种,所以共有\(m ...

  9. DRF-解析器组件源码解析

    解析器组件源码解析 解析器组件源码解析 1 执行request.data 开始找重装的request中的data方法 2 在dispatch找到重装的request def dispatch(self ...

  10. 以下是Direct 3d的安装步骤

    安装配置 真的是软肋 o( ̄ε ̄*)   我记录以下 步骤 防止下次忘记了 首先要安装到direct3d 之后在vs上配置  如下: 找到 安装direct3d的文件夹 复制路径(如下 我的路径为 G ...