面试精讲之面试考点及大厂真题 - 分布式专栏 05 公司使用什么RPC框架,聊聊你理解的RPC原理
05 公司使用什么RPC框架,聊聊你理解的RPC原理
引言
前些年我们在做一个规模不大的系统的时候,也就是单体架构,一台服务器部署上一个应用和数据库也就够了。但是现代化互联网公司业务逐渐扩大,服务逐渐细分,很多服务之间需要通过远程分布式接口调用通讯,即不同的服务不是部署在同一个服务器上,比如订单服务在 A 服务上,付款服务在另一个服务上,有同步调用、也有异步调用,这个时候我们就需要远程调用不同的服务,使用的时候调用远程服务就像调用本地服务一样,引入一个 jar 包,就能通过 this.xxx( ) 一样调用远程服务,这背后的机制就是通过 RPC 技术。
重点:RPC 技术一定是今后工作必备基础,熟练掌握其中一种,知道原理,阅读源码,甚至自己手写一个。
1. 面试官:公司使用什么 RPC 框架?,可以介绍一下 RPC 的工作原理吗?
问题分析: 面试官想了解基础设施是否和我们项目用的一样,一样最好了,能直接上手,不一样了解其它一个别的应该也问题不大,毕竟原理技术都大同小异,说你最熟悉的一个。
我:
RPC 是一个分布式计算的 CS 模式,总是由 Client 向 Server 发出一个执行若干过程请求,Server 接受请求,使用者客户端提供的参数,计算完成之后将结果返回给客户端。
使用最广泛的 Spring Cloud,基于 Spring Boot 特性整合了开源行业中优秀的组件,整体对外提供了一套在微服务架构中服务治理的解决方案。
国内开源的框架中,使用比较广泛的有阿里的 Dubbo,后来捐献给了 Apache。还有腾讯的 Tars 框架,还有 Thrift 框架,也有基于 Thrift 二次开发的 RPC 框架,比如美团的 Mtthrift。
这些 RPC 大致原理基本都是一样的。(这个时候,跟面试官要纸和笔,画图解释 RPC 原理)
这个图既不显得太过复杂给自己挖坑,也不会显得简单潦草。
1-5 逐行解释:
- 服务集成 RPC 后,服务(这里的服务就是图中的 Provider,服务提供者)启动后会通过 Register(注册)模块,把服务的唯一 ID 和 IP 地址,端口信息等注册到 RPC 框架注册中心(图中的 Registry 部分)。
- 当调用者(Consumer)想要调用服务的时候,通过 Provider 注册时的的服务唯一 ID 去注册中心查找在线可供调用的服务,返回一个 IP 列表(3.notify 部分)。
- 第三步 Consumer 根据一定的策略,比如随机 or 轮训从 Registry 返回的可用 IP 列表真正调用服务(4.invoke)。
- 最后是统计功能,RPC 框架都提供监控功能,监控服务健康状况,控制服务线上扩展和上下线(5.count)
有清晰的流程图,有每一步的解释,面试官表示很满意,继续追加提问。
2. 面试官:服务启动的时候服务基本信息被注册到注册中心,如果服务提供者挂了,注册中心如何知道服务不可用了呢?
我:
服务掉线分为主动下线和心跳检测,比如服务由于发版时,在重启之前先主动通知注册中心:我要重启了,有流量进来先不要分给我,让别的机器服务,等我重启成功后在放流量进来,或者是在管理后台手动直接摘掉机器,这个是主动下线。
心跳检测是处理服务非正常下线(如断电断网)的情况,这个时候如果注册中心不知道该服务已经掉线,一旦被其调用就会带来问题。为了避免出现这样的情况,注册中心增加一个心跳检测功能,它会对服务提供者(Provider)进行心跳检测,比如每隔 30s 发送一个心跳,如果三次心跳结果都没有返回值,就认为该服务已下线,赶紧更新 Consumer 的服务列表,告诉 Consumer 调用别的机器。
问题分析: 阐述了服务端挂了注册中心如何感知的问题,你以为此问题已经完事儿了?还没有,你成功给自己挖了个坑,面试官可能继续深挖,服务提供者(Provider)挂了注册中心能解决,那注册中心自己就不挂了吗?三连问继续。
3. 面试官:如果注册中心挂了,比如你用的是 Zookeeper,如果 Zookeeper 挂了,那服务之间还能相互调用吗?
我:
首先注册中心挂掉也要分两种情况,如果数据库挂了,ZK 还是能用的,因为 ZK 会缓存注册机列表在缓存里。
其次 ZK 本身就是一个集群的,一台机器挂了,ZK 会选举出集群中的其他机器作为 Master 继续提供服务,如果整个集群都挂了也没问题,因为调用者本地会缓存注册中心获取的服务列表。省略和注册中心的交互,Consumer 和 Provider 采用直连方式,这些策略都是可配置的。
问题分析: 面试是一个自由交流时间,任何一个点都可能被发散继续深入挖掘,刨根问题,总有你覆盖不到的知识盲区,目的不是为难你,是想了解你的技术沉淀深度。
4. 面试官:你对 RPC 了解的很透彻,那你能否自己写一个 RPC 框架?可以简答描述下思路也行。
我: 这个问题,虽然没有自己动手写过,但是我阅读过源码,大致实现思路是这样的。(画图给面试官)
- 客户端 invoke 方法编写,使用 JDK 的动态代理技术,客户端调用远程服务方法时调用的是 InvocationHandler 的 invoke 方法。
- 客户端 Filter 方法编写,完善的 RPC 框架少不了监控、路由、降级、鉴权等功能。
- 创建 Socket,在 Filter 方法中实现 Client.write 方法,其逻辑为从连接池(ChannelPool)中获取连接,然后将数据写进 Channel。
- 实现数据序列化、压缩,目的减少网络传输的数据量,向服务端发送 request 数据,这里可以使用 Netty 异步通讯框架。
- 服务端收到客户端发过的消息后,从 Channel 中将消息读出来之前,也会先经反序列化解压。
- 请求就到了服务端 Filter 中。请求依次经过监控、鉴权方法。
- 根据客户端传递来的服务信息和参数,通过反射调用相应的业务服务并拿到业务处理结果。然后在 ResponseFilter 中将返回结果写入 Channel。
- 服务端序列化、压缩等,发送给客户端。
- 客户端收到消息后,经过客户端反序列化、解压缩,后交给 ResponseThreadPoolProcessor 线程池处理。
- ResponseThreadPoolProcessor 收到消息后,就将结果返回给之前的方法调用,整个调用请求就结束了。
面试官: 可以可以,确实是看了,这个问题就到这。(面试官心理:虽然目前项目里不会让你真正去写一个 RPC 框架,知其然知其所以然,遇到这类 RPC 相关问题一定能搞定了,项目组正好缺一个这样的人)
深入分析
已经有 http 协议接口,或者说 RestFul 接口,为什么还要使用 RPC 技术?
在接⼝不多的情况下,使用 http 确实是一个明智的选择,比如在初创企业,我们不确定业务能顺利开展下去,可能面临随时倒闭,开发人员也不足,这个时候使用简洁高效的技术,先把东西做出来是最明智的选择,无需一步登天。
系统与系统交互较少的情况下,使用 http 协议优点显而易见:开发简单、测试也比较直接、部署方便,利用现成的 http 协议进行系统间通讯,如果业务真的慢慢做大,系统也慢慢扩大,RPC 框架的好处就显示出来 了,⾸先 RPC 支持长链接,通信不必每次都要像 http 一样去重复 3 次握⼿,减少了网络开销。
其次就是 RPC 框架一般都有注册中心模块,有完善的监控管理功能,服务注册发现、服务下线、服务动态扩展等都方便操作,服务化治理效率大大提高。
基于 TCP 协议实现的 RPC,能更灵活地对协议字段进行定制,相比 http 能减少网络传输字节数,降低网络开销(握手)提高性能。实现更大的吞吐量和并发数,但是需要更多的关注底层复杂的细节, 对开发人员的要求也高,增加开发成本。
总结
在面试官夺命三连问的攻击下,前三个题目一定要掌握,最后一个加分项徒手写 RPC 深入分析,可以大大拉升面试官对你的好感,只要有亮点,即使其他问题答得不好,那么问题也不大。
RPC 工作原理总结:
- Provider:服务提供方,CS 模型中的 Server。
- Consumer: 调用远程服务服务消费方,CS 模型中的 Client。
- Registry:服务注册与发现的服务管理中心。
- Monitor:统计服务的调用次数和调用时间的监控中心。
- Container:服务运行容器,如 jetty。
RPC 执行过程总结:
- 服务容器负责启动,加载,运行服务提供者。
- 服务提供者在启动时,向注册中心注册自己提供的服务,暴露自己的 IP 和端口信息。
- 服务消费者在启动时,向注册中心订阅自己所需的服务。
- 注册中心返回服务提供者列表给消费者,如果有变更,注册中心将基于长连接推送给数据消费者。
- 服务消费者,从提供这地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另外一台服务调用。
- 服务消费者和提供者,在内存中累计调用次数和调用时间,定时发送一次统计数据到监控中心。
面试精讲之面试考点及大厂真题 - 分布式专栏 05 公司使用什么RPC框架,聊聊你理解的RPC原理相关推荐
- 面试精讲之面试考点及大厂真题 - 分布式专栏 13项目中为什么要使用消息队列
13项目中为什么要使用消息队列 学习从来无捷径,循序渐进登高峰. -- 高永祚 引言 上个章节把Redis夺命连环问掰扯完,面试还没有结束,消息队列同样是面试中必问的,分布式构建三把斧:缓存+异步+数 ...
- 面试精讲之面试考点及大厂真题 - 分布式专栏 18 谈谈怎么理解幂等,接口如何保证幂等
18谈谈怎么理解幂等,接口如何保证幂等 时间像海绵里的水,只要你愿意挤,总还是有的. --鲁迅 引言 稳定性设计第一篇:这一小节开始讲设计系统稳定性保证的相关设计,谁都不想自己负责的系统三天两头就出故 ...
- 面试精讲之面试考点及大厂真题 - 分布式专栏 04 谈谈你对分布式的理解,为什么引入分布式?
04谈谈你对分布式的理解,为什么引入分布式? 引言 刚刚毕业第一份工作,没接触过分布式微服务相关的知识,后来换工作才了解到这些,面试官看了我简历里写了分布式相关,就开始揪住这个问题问,虽然一知半解地说 ...
- 面试精讲之面试考点及大厂真题 - 分布式专栏 02 了解大厂面试基本套路及每一轮的重点
02 了解大厂面试基本套路及每一轮的重点 自信和希望是青年的特权. --大仲马 引言 无论是刚刚毕业的学生,还是刚刚工作一两年面试经验比较少的同学,往往会比较困惑该如何准备面试.面对至少三轮面试(或更 ...
- 面试精讲之面试考点及大厂真题 - 分布式专栏 17 ElasticSearch解决大数据量检索难题
17 ElasticSearch解决大数据量检索难题 理想的书籍是智慧的钥匙. --列夫·托尔斯泰 引言 如果你的项目里有超过千万上亿级别的数据,且数据日增量较大需要高性能检索时,如订单数据,你该怎么 ...
- 面试精讲之面试考点及大厂真题 - 分布式专栏 03 阿里华为资深HR面试套路全揭晓
03 阿里华为资深HR面试套路全揭晓 HR 面试套路大全 如果你技术面试过了,进入最后一轮 HR 谈薪资,先别高兴太早,千万不要轻视 HR.BAT 大公司,HR 有一票否决权,即使你技术 OK,领导也 ...
- 面试精讲之面试考点及大厂真题 - 分布式专栏 10 Redis雪崩,穿透,击穿三连问
10 Redis雪崩,穿透,击穿三连问 能够生存下来的物种,并不是那些最强壮的,也不是那些最聪明的,而是那些对变化作出快速反应的. --达尔文 引言 关于Redis雪崩,穿透,击穿的问题,第一次接触名 ...
- 面试精讲之面试考点及大厂真题 - 分布式专栏 23 分布式系统下分布式锁的实现
23 分布式系统下分布式锁的实现 困难只能吓倒懦夫懒汉,而胜利永远属于敢于等科学高峰的人. --茅以升 引言 锁是开发过程中十分常见的工具,你一定不陌生,悲观锁,乐观锁,排它锁,公平锁,非公平锁等等, ...
- 面试精讲之面试考点及大厂真题 - 分布式专栏 01 开篇词:我是怎样带你通过大厂面试
01 开篇词:我是怎样带你通过大厂面试 自信和希望是青年的特权. --大仲马 学习编程是一场修行,要经历从 0 到 1,普通人从自己的错误中学习,聪明人从别人的错误中学习. 授人以鱼不如授人以鱼杆儿, ...
最新文章
- 详细解说 STL 排序(Sort)
- 预发布环境,Tag发布机制和可重复的部署过程
- codeforces 954C
- 面向视频的全新AI架构 —— 阿里云智能视觉技术全解
- cmd中输入net start mysql 提示:服务名无效或者MySQL正在启动 MySQL无法启动
- jboss6启动报错
- 服务器***处理三则
- 刷单之骗人先交钱QQ,如何从qq,找到他的ip
- 小区门禁卡可以复制到手机上吗_手机NFC可以复制小区用的门禁卡吗?步骤是什么?...
- 腾达W311MA无线网卡驱动安装 ubuntu16.04
- 编程的思想是什么,如何建立编程思想,如何训练和提高编程思想?
- 计划任务linux每天执行一次,linux 每天执行任务计划
- [高数][高昆轮][高等数学上][第一章-函数与极限]02.数列的极限
- 重庆OA办公系统目前推出PC端、移动终端(安卓、IOS、平板)- 上弦科技
- Android开发踩坑之旅
- Python生成汉字字符以及对应分辨率的图片
- CSS峰会亮点直击,大咖共议产业上云的安全“最优解”
- Swift 掌控Moya的网络请求、数据解析与缓存
- go1.57安装框架iris12.1遇到的坑及解决
- Spring Boot中的RSocket入门
热门文章
- 一个封装比较完整的FTP类——clsFTP
- 工行黄金递延业务AU(T+D)风险问题答案
- SQL函数 left()、charindex()的使用
- Asp.net+Jquery实现用户信息异步验证
- ASP.NET从字符串中查找字符出现次数的方法
- PHP 加密用户密码 How to store passwords safely with PHP and MySQL
- linux命令之less 命令
- Objective-C 2.0 with Cocoa Foundation--- 5,Class类型,选择器Selector以及函数指针
- Ajax Loading进度gif在线生成
- php:修改目录下文档权限(777,644 )