面试题:如何实现一个RPC框架?

devtools/2024/9/23 8:15:13/

来源

滴滴二面

原问题

如何实现一个RPC框架?
考这个问题不是让你实现一个RPC框架,而是要看你对RPC框架的理解。

我的回答

我对RPC框架不太了解。

更好的答案

RPC概念

我们平时使用RPC框架时,可以在一个服务中,像调用本地方法一样,调用其他服务中的方法。

RPC需要用到哪些技术?

以服务A调用服务B为例进行讲解。

架构图

在这里插入图片描述
ProcessOn链接:RPC调用架构

动态代理

但是这其中,框架为我们封装了很多功能。我们只是引入并调用了接口,所以,需要使用到动态代理技术,可以使用JDK动态代理,javassist,dubbo就是使用javassist来生成代理对象,由代理对象来执行一系列的请求。

序列化

我们在A中调用B时,需要让B知道A调用了哪个方法,就需要对B的接口信息进行序列化,对参数进行序列化。
可以使用现有的序列化协议进行序列化,除了下面的图中提到的序列化协议,还可以使用fastJson进行序列化,不过序列化的效率没那么高,对数据的压缩程度也没有那么好。
在这里插入图片描述

通信协议

我们可以使用现有的通信协议进行通信
在这里插入图片描述

实现自定义的协议,可以参考:
基于注解和Spring实现一个RPC框架
主要是:魔数+协议版本+消息长度+消息内容:
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

服务注册与发现

可以使用Zookeeper或者Nacos这种现成的注册中心。
Zookeeper是CP系统,Nacos既可以CP,也可以AP,具体可以通过连接Nacos的配置ephemeral参数决定。可以参考我的另一篇文章:
Eureka、Nacos、Zookeeper、Redis等应用是AP还是CP?

使用Zookeeper,对于服务,一般是创建持久节点,服务和ip、端口的映射,可以在服务节点下面创建临时节点,服务调用者可以对关注的节点创建watch事件,当服务提供者列表有变动时,调用者就可以接收到,就可以更新元数据。

使用Nacos,也是需要去实现类似的接口。

负载均衡策略

服务A获取到服务提供者列表之后,需要根据某种负载均衡策略,来选择某个ip、端口进行调用,常见的负载均衡策略,有以下几种:
随机、轮询、距离最近等。
随机和轮询又可以带上权重(不知道权重是什么,可以查询以后,补充到这里)

用户可以根据配置选择需要的负载均衡策略。

熔断机制

客户端请求服务端时,当B服务出了问题之后,需要对B服务进行熔断,避免B服务的问题扩大到整个系统。
熔断策略可以实现为:当过去10秒内,请求大于20个,但是请求失败率为50%,则熔断该服务。每隔5秒,放行一定的流量对该服务进行尝试,如果失败,则保持熔断状态,如果成功,则关闭熔断状态,放开所有流量。

降级机制

客户端请求服务端时,当B服务抛出异常,或者B服务被熔断之后,需要提供降级策略,根据降级策略,直接返回固定的数据或者抛出异常。
可以使用反射,根据降级工厂或者用户配置的降级的类,创建响应的示例,并设置到我们创建的动态代理中,当发生降级时,就使用反射对降级的方法进行调用。
可以先把降级的类的相关方法存储成一个Map<方法签名,降级方法> 降级方法缓存,降级时,使用反射获取原始方法的方法签名,然后从降级方法缓存中获取到降级方法,就可以对降级方法进行调用了。
使用反射获取原始方法的方法签名:已经像GPT求证过,可以做到。

隔离机制

客户端请求服务端时,对下游的服务进行请求时,需要一定的隔离策略,防止下游服务故障导致整个系统故障。
可以实现为:基于线程池或者信号量进行隔离,对每个用户配置的key进行隔离,当key不存在时,则创建新的线程池或者信号量。
如果线程池或者信号量满了,则抛出异常。

限流机制

服务端对客户端进行响应时,也可以制定一定的限流机制,防止一个客户端请求占用太多资源,也可以防止请求者恶意攻击。
具体的限流机制可以参考Nacos的限流,可以对单个接口进行限流,可以对接口的热点key进行限流。限流算法还需要再查一下,然后补充到这里。我记得好像有什么漏桶算法之类的。

通信模块

在编写代码时,可以使用Netty框架,Netty框架对NIO和AIO都进行了封装,开发者可以很方便的编写代码。
服务端对客户端进行响应时,具体可以使用Netty的主从Reactor多线程模式来实现服务之间的通信。
客户端请求服务端时,就是使用隔离策略中的线程池来发送请求,或者使用信号量时,使用信号量来限制请求。

参考

基于注解和Spring实现一个RPC框架

Dubbo协议讲解

各种RPC协议对比


http://www.ppmy.cn/devtools/22787.html

相关文章

排序算法(总结)-C++

排序算法 篇幅较长请耐心看完冒泡排序 ( B u b b l e S o r t Bubble Sort BubbleSort)选择排序 ( S e l e c t i o n S o r t Selection Sort SelectionSort)插入排序 ( I n s e r t i o n S o r t Insertion Sort InsertionSort)希尔排序 ( S h e l l S o r t Shell Sort She…

Elasticsearch实现hotel索引库自动补全、拼音搜索功能

Elasticsearch实现hotel索引库自动补全、拼音搜索功能 在这里边我们有两个字段需要用拼音分词器&#xff0c;一个name字段&#xff0c;一个all字段。 然后我们还需要去实现自动补全&#xff0c;而自动补全对应的字段必须使用completion类型。目前我们酒店里面所有的字段都采用的…

Day27:阻塞队列、Kafka入门、发送系统通知、显示系统

阻塞队列BlockingQueue BlockingQueue 解决线程通信的问题。阻塞方法:put、take。 生产者消费者模式 生产者:产生数据的线程。消费者:使用数据的线程。 &#xff08;Thread1生产者&#xff0c;Thread2消费者&#xff09; 实现类 ArrayBlockingQueueLinkedBlockingQueuePr…

PDF高效编辑器,一键转换将PDF文件转换成HTML文件,开启文件处理新篇章!

文件格式的转换与处理已成为我们日常工作中不可或缺的一部分。为了满足广大用户对高效、便捷文件处理的需求&#xff0c;我们荣幸地推出了全新的PDF高效编辑器——PDF到HTML一键转换工具&#xff01;这款工具将为您带来前所未有的文件处理体验&#xff0c;让您轻松驾驭文件格式…

不同状态空间模型的实验对比(二)

对五个下游任务进行了实验比较&#xff0c;包括单/多标签分类、视觉对象跟踪、像素级分割、图像到文本生成和人/车辆再识别。 论文&#xff1a;https://arxiv.org/abs/2404.09516 作者单位&#xff1a;安徽大学、哈尔滨工业大学、北京大学更多相关工作将在以下GitHub上不断更新…

All in One mini主机搭建全屋主路由方案----自己实现自己的路由器,实现路由器自由!

1 接线 首先&#xff0c;需要保证家里当前状态是有网的状态&#xff08;路由器有网并正常工作&#xff09; 将鼠标键盘接在mini主机的USB口&#xff0c;HDMP/DP/VGA等接上显示器。从路由器的lan口接一根网线出来接在mini主机的ETH0上&#xff0c;接在mini主机上保证mini主机在…

短期动态IP介绍

IP代理作为一门新兴的网络技术&#xff0c;备受市场与用户的青睐。主要是帮助用户解除地域限制&#xff0c;登录海外网站&#xff0c;浏览海外用户信息。 代理商实际上是依托于海外服务器&#xff0c;将国内IP地址通过代理服务器隐匿后替换为海外IP地址&#xff0c;再由代理服…

每天一个数据分析题(二百九十七)

帮助了解当前每个维度项的业务行为结果的整体情况的是哪种指标计算方法&#xff1f; A. 常规求和 B. 累计求和 C. 常规计数 D. 非重复计数 题目来源于CDA模拟题库 点击此处获取答案 cda数据分析考试&#xff1a;点击进入