百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

10分钟实现RPC框架(rpc框架应用场景)

ccwgpt 2024-09-17 12:49 37 浏览 0 评论

其实整个流程是个很简单的rpc模型

1.服务端 接受客户端来的socket流, 接受约定为

1.1 方法名

1.2 参数类型

1.3 方法所需参数

2 客户端动态代理生成 代理service,调用该service的方法实则 交给invoke方法处理

逻辑,在该逻辑中实现远程连接,起多个线程。

一次完整的RPC调用流程(同步调用,异步另说)如下:

1)服务消费方(client)调用以本地调用方式调用服务;

2)client stub接收到调用后负责将方法、参数等组装成能够进行网络传输的消息体;

3)client stub找到服务地址,并将消息发送到服务端;

4)server stub收到消息后进行解码;

5)server stub根据解码结果调用本地的服务;

6)本地服务执行并将结果返回给server stub;

7)server stub将返回结果打包成消息并发送至消费方;

8)client stub接收到消息,并进行解码;

9)服务消费方得到最终结果。

RPC框架的目标就是要2~8这些步骤都封装起来,让用户对这些细节透明。


内容

RpcFramework核心类

import java.io.ObjectInputStream;

import java.io.ObjectOutputStream;

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Method;

import java.lang.reflect.Proxy;

import java.net.ServerSocket;

import java.net.Socket;

public class RpcFramework {

/**

* 暴露服务

*

* @param service 服务实现

* @param port 服务端口

* @throws Exception

*/

public static void export(final Object service, int port) throws Exception {

System.out.println("Export service " + service.getClass().getName() + " on port " + port);

ServerSocket server = new ServerSocket(port);

//一直轮询,相比while(true),这种方式性能更佳

for(;;) {

try {

//此处阻塞一直等到有consumer请求过来

final Socket socket = server.accept();

//每来一个消费请求就开启一个新的线程

new Thread(() -> {

try {

try {

ObjectInputStream input = new ObjectInputStream(socket.getInputStream());

try {

//consumer会分三次发送所需要的方法信息,这里的readUTF(),readObject()都会发生阻塞

String methodName = input.readUTF();

Class<?>[] parameterTypes = (Class<?>[])input.readObject();

Object[] arguments = (Object[])input.readObject();

ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream());

try {

//获取到目标方法

Method method = service.getClass().getMethod(methodName, parameterTypes);

//通过反射执行目标方法并返回结果

Object result = method.invoke(service, arguments);

//将执行结果返回给consumer

output.writeObject(result);

} catch (Throwable t) {

output.writeObject(t);

} finally {

output.close();

}

} finally {

input.close();

}

} finally {

socket.close();

}

} catch (Exception e) {

e.printStackTrace();

}

}).start();

} catch (Exception e) {

e.printStackTrace();

}

}

}

/**

* 引用服务

*

* @param <T> 接口泛型

* @param interfaceClass 接口类型

* @param host 服务器主机名

* @param port 服务器端口

* @return 远程服务

* @throws Exception

*/

@SuppressWarnings("unchecked")

public static <T> T refer(final Class<T> interfaceClass, final String host, final int port) throws Exception {

System.out.println("Get remote service " + interfaceClass.getName() + " from server " + host + ":" + port);

//通过JDK动态代理的方式直接返回给调用refer方法的调用者一个被动态代理处理过的 对象

return (T) Proxy.newProxyInstance(interfaceClass.getClassLoader(), new Class<?>[] {interfaceClass}, new InvocationHandler() {

@Override

//调用该对象的每个方法都会先去调用下面的逻辑

public Object invoke(Object proxy, Method method, Object[] arguments) throws Throwable {

//当方法真实被调用的时候才会发起RPC远程请求provider执行服务

Socket socket = new Socket(host, port);

try {

ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream());

try {

//分三次发送方法所需要的信息

output.writeUTF(method.getName());

output.writeObject(method.getParameterTypes());

output.writeObject(arguments);

ObjectInputStream input = new ObjectInputStream(socket.getInputStream());

try {

//得到服务执行的最终结果

Object result = input.readObject();

if (result instanceof Throwable) {

throw (Throwable) result;

}

return result;

} finally {

input.close();

}

} finally {

output.close();

}

} finally {

socket.close();

}

}

});

}

}

服务接口:

public interface HelloService {

String hello(String name);

}

服务接口实现:

public class HelloServiceImpl implements HelloService {

@Override

public String hello(String name) {

System.out.println("被调用了");

return "Hello" + name;

}

}

暴露服务类

public class RpcProvider {

public static void main(String[] args) throws Exception {

HelloService service = new HelloServiceImpl();

RpcFramework.export(service, 1234);

}

}

引用服务类:

public class RpcConsumer {

public static void main(String[] args) throws Exception {

//此时获取到的service是被JDK动态代理包装后的service,在调用方法的时候会进行远程调用

HelloService service = RpcFramework.refer(HelloService.class, "127.0.0.1", 1234);

for (int i = 0; i < Integer.MAX_VALUE; i ++) {

String hello = service.hello("World" + i);

System.out.println(hello);

Thread.sleep(1000);

}

}

}


总结

我觉得RPC的核心是动态代理和Socket 。

客户端看到的是接口的行为(这个行为没有被实现),服务端放的是接口行为的具体实现。

客户端把行为和行为入参提供给服务端,然后服务端的接口实现执行这个行为,最后再把执行结果返回给客户端。 看起来是客户端执行了行为,但其实是通过动态代理交给服务端执行的。其中,行为和入参这些数据通过socket由客户端传给了服务端。

相关推荐

2025南通中考作文解读之四:结构框架

文题《继续走,迈向远方》结构框架:清晰叙事,层层递进示例结构:1.开头(点题):用环境描写或比喻引出“走”与“远方”,如“人生如一条长路,每一次驻足后,都需要继续走,才能看见更美的风景”。2.中间...

高中数学的知识框架(高中数学知识框架图第三章)

高中数学的知识框架可以划分为多个核心板块,每个板块包含具体的知识点与内容,以下为详细的知识框架结构:基础知识1.集合与逻辑用语:涵盖集合的概念、表示方式、性质、运算,以及命题、四种命题关系、充分条件...

决定人生的六大框架(决定人生的要素)

45岁的自己混到今天,其实是失败的,要是早点意识到影响人生的六大框架,也不至于今天的模样啊!排第一的是环境,不是有句话叫人是环境的产物,身边的环境包括身边的人和事,这些都会对一个人产生深远的影响。其次...

2023年想考过一级造价师土建计量,看这30个知识点(三)

第二章工程构造考点一:工业建筑分类[考频分析]★★★1.按厂房层数分:(1)单层厂房;(2)多层厂房;(3)混合层数厂房。2.按工业建筑用途分:(1)生产厂房;(2)生产辅助厂房;(3)动力用厂房;(...

一级建造师习题集-建筑工程实务(第一章-第二节-2)

建筑工程管理与实务题库(章节练习)第一章建筑工程技术第二节结构设计与构造二、结构设计1.常见建筑结构体系中,适用建筑高度最小的是()。A.框架结构体系B.剪力墙结构体系C.框架-剪力墙结构体系D...

冷眼读书丨多塔斜拉桥,这么美又这么牛

”重大交通基础设施的建设是国民经济和社会发展的先导,是交通运输行业新技术集中应用与创新的综合体现。多塔斜拉桥因跨越能力强、地形适应性强、造型优美等特点,备受桥梁设计者的青睐,在未来跨越海峡工程中将得...

2021一级造价师土建计量知识点:民用建筑分类

2021造价考试备考开始了,学霸君为大家整理了一级造价师备考所用的知识点,希望对大家的备考道路上有所帮助。  民用建筑分类  一、按层数和高度分  1.住宅建筑按层数分类:1~3层为低层住宅,4~6层...

6个建筑结构常见类型,你都知道吗?

建筑结构是建筑物中支承荷载(作用)起骨架作用的体系。结构是由构件组成的。构件有拉(压)杆、梁、板、柱、拱、壳、薄膜、索、基础等。常见的建筑结构类型有6种:砖混结构、砖木结构、框架结构、钢筋混凝土结构、...

框架结构设计经验总结(框架结构设计应注意哪些问题)

1.结构设计说明主要是设计依据,抗震等级,人防等级,地基情况及承载力,防潮抗渗做法,活荷载值,材料等级,施工中的注意事项,选用详图,通用详图或节点,以及在施工图中未画出而通过说明来表达的信息。2.各...

浅谈混凝土框架结构设计(混凝土框架结构设计主要内容)

浅谈混凝土框架结构设计 摘要:结构设计是个系统的全面的工作,需要扎实的理论知识功底,灵活创新的思维和严肃认真负责的工作态度。钢筋混凝土框架结构虽然相对简单,但设计中仍有很多需要注意的问题。本文针...

2022一级建造师《建筑实务》1A412020 结构设计 精细考点整理

历年真题分布统计1A412021常用建筑结构体系和应用一、混合结构体系【2012-3】指楼盖和屋盖采用钢筋混凝土或钢木结构,而墙和柱采用砌体结构建造的房屋,大多用在住宅、办公楼、教学楼建筑中。优点:...

破土动工!这个故宫“分院”科技含量有点儿高

故宫“分院”设计图。受访者供图近日,位于北京海淀区西北旺镇的故宫北院区项目已开始破土动工,该项目也被称作故宫“分院”,筹备近十年之久。据悉,故宫本院每年展览文物的数量不到1万件,但是“分院”建成后,预...

装配式结构体系介绍(上)(装配式结构如何设计)

PC构件深化、构件之间连接节点做法等与相应装配式结构体系密切相关。本节列举目前常见的几种装配式结构体系:装配整体式混凝土剪力墙结构体系、装配整体式混凝土框架结构体系、装配整体式混凝土空腔结构体系(S...

这些不是双向抗侧结构体系(这些不是双向抗侧结构体系的特点)

双向抗侧土木吧规范对双向抗恻力结构有何规定?为何不应采用单向有墙的结构?双向抗侧土木吧1.规范对双向抗侧力结构体系的要求抗侧力体系是指抵抗水平地震作用及风荷载的结构体系。对于结构体系的布置,规范针对...

2022一级建造师《建筑实务》1A412020 结构设计 精细化考点整理

1A412021常用建筑结构体系和应用一、混合结构体系【2012-3】指楼盖和屋盖采用钢筋混凝土或钢木结构,而墙和柱采用砌体结构建造的房屋,大多用在住宅、办公楼、教学楼建筑中。优点:抗压强度高,造价...

取消回复欢迎 发表评论: