你以为,设计一个 RPC 框架很简单?应该从哪入手,深入剖析? Java 架构新资讯

RPC
我们即希望能够敏捷开发,不做重复的劳动,用别人的势能赋能自己;又要成为一名能够赋能别人的人,拥有自身的势能。

RPC 需要什么
想要实现一个基本的 RPC 框架,其实需要什么?
网络 IO,BIO\NIO\AIO,Socket 编程,HTTP 通信,一个就行。
序列化,JDK 序列化,JSON、Hessian、Kryo、ProtoBuffer、ProtoStuff、Fst 知道一个就行。
反射,JDK 或者 Cglib 的动态代理。
那一个优秀的 RPC 框架,还需要考虑什么问题?
一个服务可能有多个实例,你在调用时,要如何获取这些实例的地址?服务注册中心
多个实例,选哪个调用好?负载均衡
服务注册中心每次都查?缓存相关
客户端每次要等服务器返回结果?异步调用
服务是要升级的?版本控制
多个服务依赖,某个有问题?熔断器
某个服务出了问题怎么办?监控 ..
一、 从使用者考虑
定义过程接口

客户端使用生成的 stub 代理对象

二、设计客户端
客户端生成过程接口的代理对象 设计客户端代理工厂,用 JDK 动态代理即可生成接口的代理对象。

思考
1、在 ClientStubInvocationHandler 中 需完成哪些事情?

2、将请求的内容编组为消息这件事由谁来做?

3、消息协议是固定不变的吗?它与什么有关? 看框架对协议的支持广度,如果支持多种协议,就是会灵活变化的,它与具体的服务相关, A 服务提供者可能选用的是协议 1,B 服务提供者可能选用协议 2。
4、某服务是用的什么消息协议这个信息从哪来? 从获取的服务信息中来,因此需要一个服务信息发现者。
把发现者设计出来, 要求:可灵活支持多种发现机制


5、我们想要做到可以支持多种协议,我们的类该如何设计? 面向接口、策略模式、组合

问题:
➢ marshalling 和 unmarshalling 方法该定义怎样的参数与返回值? ➢ 编组、解组的操作对象是请求、响应,请求、响应的内容是不同的。编组、解组两个方法是否满足?
设计客户端协议层
定义框架标准的请求, 响应类

将协议层扩展为四个
消息协议独立为一层(客户端、服务端均需要)
网络层 发送请求,获得响应
要发起网络请求,则须知道服务地址

客户端完整类图

实现客户端 按照类图设计,填码! 看 ClientStubProxyFactory 核心类的代码示例!
在实现过程中,协议层涉及一个重要概念
参数序列化、反序列
三、设计服务端
3.1 RPCServer
客户端请求过来了,服务端首先需要通过 RPCServer 接收请求。


RPCServer

3.2 思考
RPCServer 接收到客户端请求后,还需要做哪些工作?

网络层在 RPCServer 中提供多线程来处理请求,消息协议层是用客户端设计的。 (设计一个 请求处理类 ,来完成网络层以上的事情。)
3.3 RequestHandler
RPCServer 接收到请求后,将请求交给 RequestHandler 来处理 RequestHandler 调用协议层来解组请求消息为 Request 对象,然后调用过程!

人性的拷问
➢ RequestHandler 如何得到过程对象? ➢ Request 中有什么? ➢ 服务名、方法名、参数类型、参数值 ➢ 是否需要一个过程注册模块?
看看之后的设计

➢ 过程注册模块 :让用户将他们的过程注册到 RPC 框架 ➢ 过程暴露模块 :想对外发布(暴露)服务注册、暴露可以由同一个类实现

RPCServer 中实现网络层: Netty, 使用 RequestHandler
ServiceRegister 模块实现服务注册、发布。
RequestHandler 中实现消息协议处理、过程调用
代码实现
首先,用户需要设置你的端口和协议哦


以上就是有关 RPC 框架的学习知识笔记,希望可以对大家学习 RPC 有帮助
评论