一个请求过来都经过了什么?(Thrift版)

简介: 一个请求过来都经过了什么?(Thrift版)

一、背景


最初遇到这个问题是去58面试。部门领导是原同事,所以面试比较水。水到什么程度呢?


面试就是走个形式而已,不会不过的。


一面面试官就问了一个问题:“一个请求过来都经过了什么?”  剩下的全是闲聊。顺便展示一下公司和部门的优势。期待加入的意思。


声明

面试如此之松是基于两点:


第一点,与原同事多年的共事已经展示了能力和综合素质,比几个小时的面试得到的结论靠谱的多。


第二点,原同事本身认人识人的能力得到了其他人的认可,所以大家放心他推荐的人。

毕竟没人愿意让一个不合适的人加入自己团队拉低整体水准。


二、问题考察点


深度和广度的综合考察


三、静儿的答案


建立虚拟场景


☆ 项目


容器调度服务(根据用户传入的机房、CPU、内存等信息给用户创建所需要的机器)。


项目所用技术栈:SpringBoot、Thrift、缓存、mysql、k8s


☆ 需求


程序中需要用thrift(RPC调用)请求基础服务取所有的机房信息。


☆ 设计


基础服务提供了「傻瓜式」客户端给调用方。客户端只需要引入jar包,就可以像调用本地接口一样进行访问。


微信图片_20220426225447.jpg


客户端实现方法


因为机房信息是低频的、对变更一定时延不敏感的资源信息。所以客户端首先RPC去远程取结果放到本地JVM缓存中。每次调用直接返回JVM缓存信息。客户端有定时任务定时将最新结果刷新到JVM缓存。


微信图片_20220426225527.jpg


设计特点:


1、对thrift接口做封装,封装包括设定了远程获取异常的重试次数、重试间隔、远程服务信息等。原因:基础服务提供方自己最清楚自己服务的响应时间、服务可用性等信息,自己设置更为精确,避免对使用方造成困扰。


2、每次返回本地JVM存的机房信息。信息更新通过自带定时任务。原因:基础服务提供方自己最清楚自己的资源被更新频率如何,提供数据的实时性重要性如何。怎么保持数据一致性。怎样更高效。这些难题不应该抛给调用方。


3、懒加载处理。原因:不能因为jar包被引用就直接占用内存、CPU等资源。要按需提供。


服务端实现方法


服务端收到请求,考虑到这个是基础服务,使用方多。为了防止压力直接作用于数据库,上面加了一层集中式缓存。不穿透的情况下,直接返回缓存信息。


数据库中的所有机房信息是从k8s标签中获取过滤的。有变化直接刷缓存。即数据库中存的是所有的标签信息,其中一个小功能是从所有标签中过滤机房标签。这种设计是区别于有个机房管理系统录入这种管理,机房信息永远是实时准确的。(这块涉及到内部系统的设计问题,如果看不懂直接忽略即可。)


☆ 请求过来经过了什么


微信图片_20220426225559.jpg


从程序设计上,大体经过的如上图。限于篇幅(如果你想了解不限于篇幅是个什么状态,可以阅读下面一篇《一个请求过来都经过了什么?(2017年http版)》),本篇不讲JVM经过了怎样的过程,主内存和工作内存交互,内存可能的分页,numa绑核、定频非定频等等。深度上只介绍thrift调用这一层。


微信图片_20220426225635.jpg


笼统的过程如上图。大体分为三个部分:


1、有IP直接访问IP,没有IP通过其他信息获取到IP。


在此部分中,第一次连接需要根据环境和服务标识获取机器列表。客户端一般会有本地进程代理。对于美团OCTO来说,就是Sg_Agent(服务治理代理)。代理会和OCTO服务器进行通信,及时获取最新信息。连接建立后,下次访问就是直接IP访问了。


2、通过IP访问服务端,根据类名+方法签名获取方法。


3、通过拦截器认证的请求被服务端处理后返回结果。


Thrift内部的架构是分层次的。客户端和服务端都可大体分为代码层、协议层、传输层、IO处理层四部分。客户端和服务端的IO处理层直接交互。


微信图片_20220426225718.jpg


代码层:


代码在美团OCTO体系中MtThrift中会直接由框架自动从java代码转成IDL文件,框架再根据IDL文件生成代码实现数据的读写。


协议层(实现Tprotocol接口):


将数据编码、解码。最三种的三种传输格式支持是:二进制格式、压缩格式、Json格式。


传输层(实现Ttransport接口):


提供从网络等媒介读取和写入数据的方式。常用的有:向文件进行读写、从内存上读写、压缩读写。


IO处理层:


这层所做的就是阻塞、非阻塞,单线程、多线程这些。一般像获取所有机房信息这样的读操作用的是多线程阻塞方式。写操作一般用多线程非阻塞方式。


再往下linux系统层的东西也是可以讲讲的,内容有点多,大家自己做思考题吧。还有涉及网络传输的信道、全双工传输模式这些,大家可以自己想一想,查一查。


四、总结


本次文章共三篇《一个请求过来都经过了什么?(Thrift版)》《一个请求过来都经过了什么?(2017年http版)》《思维发散的双刃剑》。首篇是刚写的,第二篇是17年写的。最后一篇是一些总结思考。


 


相关文章
|
13天前
|
Java Apache C++
别再手写RPC了,Apache Thrift帮你自动生成RPC客户端及服务端代码
Thrift 是一个轻量级、跨语言的远程服务调用框架,由 Facebook 开发并贡献给 Apache。它通过 IDL 生成多种语言的 RPC 服务端和客户端代码,支持 C++、Java、Python 等。Thrift 的主要特点包括开发速度快、接口维护简单、学习成本低和多语言支持。广泛应用于 Cassandra、Hadoop 等开源项目及 Facebook、百度等公司。
别再手写RPC了,Apache Thrift帮你自动生成RPC客户端及服务端代码
|
1月前
|
负载均衡 API 数据格式
RPC和HTTP的区别?
RPC和HTTP的区别?
77 0
Netty Http服务器接收请求
Netty Http服务器接收请求
75 0
|
自然语言处理 负载均衡 安全
HTTP那么强大,RPC为啥还有用武之地?
HTTP那么强大,RPC为啥还有用武之地?
124 0
|
开发框架 负载均衡 监控
既然有了HTTP,为什么还要RPC?
既然有了HTTP,为什么还要RPC?
|
负载均衡 Dubbo 前端开发
HTTP 与 RPC 接口区别
HTTP 与 RPC 接口是两种常见的接口通信协议。本文将会介绍它们的定义,区别和相同之处,应用场景以及目前的技术发展趋势,并给出接口代码示例和开发常用工具。
HTTP 与 RPC  接口区别
|
JSON 负载均衡 网络协议
rpc和http的区别?
rpc和http的区别?
147 0
|
JSON Java 编译器
Thrift的日常—协议
Thrift的日常—协议
Thrift的日常—协议
|
网络协议 Unix 编译器
Thrift—构建一个RPC实例(一)
Thrift—构建一个RPC实例(一)
Thrift—构建一个RPC实例(一)
|
Java 编译器 API
Thrift-构建一个RPC实例(二)
Thrift-构建一个RPC实例(二)
Thrift-构建一个RPC实例(二)