从零开始的高并发(七)--- RPC的介绍,协议及框架

7,748 阅读9分钟

前言

前情概要

上一篇中我们有简单提到master选举与代码实现,官网的一些模块划分和它们对于以往文章主题的帮助。毕竟不能只吃官网给出来的东西,所以还是要靠自己多找资料吧。

关于master选举的代码中,重点其实也就是最后通过一个线程去执行这个master的选举,我们在master的选举中要不停地监听我们的master,在master被抢到了以后,需要对这个线程,也就是负责抢master的线程进行阻塞操作,可是如果这时候主线程阻塞了,整个程序就不跑了,所以我们就使用了一个子线程去帮我们去抢master,此时就算抢不到master且阻塞了该线程,也能保证整个程序可以继续往下执行。

浏览官网的顺序很大程度上帮助了我们如何去了解这个框架,保证基础扎实的前提下,对于扩展类的知识也需要花挺多心思,比如paxos这些。对于这种知识官网就算无法提供一个最完美的学习方案,但是也给我们指示了方向,而且其实在很多情况下,我们并不是理解能力薄弱,而是苦于东西太多而无从下手。在知道了存在这些东西的时候去查阅一下很多大佬们的分享,相信一定不难学会。

以往链接

从零开始的高并发(一)--- Zookeeper的基础概念

从零开始的高并发(二)--- Zookeeper实现分布式锁

从零开始的高并发(三)--- Zookeeper集群的搭建和leader选举

从零开始的高并发(四)--- Zookeeper的分布式队列

从零开始的高并发(五)--- Zookeeper的配置中心应用

从零开始的高并发(六)--- Zookeeper的Master选举及官网小览

内容一:RPC理论

1.什么是RPC

① RPC简介

RPC(Remote Procedure Call Protocol)-远程过程调用协议。通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。它假定某种传输协议的存在,如TCP,UDP,为通信程序之间携带信息数据。在OSI网络通信模型中,RPC跨越了传输层和应用层,因分布式,微服务等而兴起

其实简单点来理解,就是比如有一个应用1,通过网络调用了应用2的服务,而不用关心应用2的协议。这就是最简单的示例。

② 为什么是远程过程调用协议?

这里的过程指的是业务处理,计算任务,更直白一点,就是程序,就像是在调用本地方法一样

与本地调用的区别可以用异地恋这个场景来理解,本地调用即是,大家同居了,都住在一起,而远程调用就像异地恋,想要见面就要不男坐车过来要不女坐车过来,而且也说异地恋一般没有好结果。远程调用中间需要网络,所以我们就可以明白

因为是通过网络通信的,所以
    响应会慢上几个数量级
    不像本地如此可靠

③ RPC的C/S模式

RPC采用client-server结构,通过request-response消息模式实现,如果服务器的程序进行了更新,那客户端方面也需要同步更新才能正常使用

④ RPC的三个过程

1.通讯协议:类似于在中国需要联系美国的朋友一样,我们会有多种联系他的方式,比如打电话,比如自己去美国等
2.寻址:我们需要知道怎么联系,比如打电话我们需要知道电话号码,自己去需要知道美国在哪儿这样的,
也就是,必须要知道一个具体的地址。
3.数据序列化:序列化的作用也很简单,比如我们已经拨通了这个外国人的电话,或者说已经去到他面前了
可我们说的是中文,他说英语,大家互相都听不懂大家说话,这就没法沟通了,所以序列化其实就是一个翻译作用

把这三个过程都做好之后RPC才能正常工作

⑤ 我们为什么要使用RPC

微服务,分布式系统架构的兴起,为了实现服务可重用或者说系统间的交互调用

⑥ RPC与其他协议的区别

RPC和RMI的区别,RMI远程方法调用是OOP领域中RPC的一种具体实现。也就是RPC是父,RMI是子,且RMI仅能存在Java中调用

WebService,restful接口调用其实都是RPC,只是它们的消息组织方式和消息协议不同而已

⑥ 与MQ的使用场景对比:

RPC就像打电话,需要一个迅速的回应(接通或者不接通),而MQ就像发微信QQ的消息,发过去了,不急着等回

架构上它们的差异是:MQ有一个中间节点Queue作为消息存储点

RPC是同步调用,对于要等待返回结果的实例,RPC处理的比较自然,由于等待结果时Consumer会有线程消耗,
如果以异步的方式使用,可以避免Consumer的线程消耗,
但它不能做到像MQ一样暂存请求,压力会堆积在服务Provider那

而MQ会把请求的压力暂缓,让处理者根据自己的节奏处理,但是由于消息是暂存在了它的队列中,
所以这个系统的可靠性会受到这个队列的影响,它是异步单向,发送消息设计为不需要等待消息处理的完成,
所以如果有需要设计为同步返回的功能的话,MQ就会变得不好使用

所以如果是非常着急需要等待返回结果的,又或者说是希望使用方便简单,RPC就比较好用,它的使用基于接口,类似于本地调用,异步编程会相对复杂,比如gRPC。而不希望发送端受限于处理端的速度时,就使用MQ。随着业务增长,也会出现处理端的处理速度不够,从而进行同步调用到异步消息的改造

2.RPC的流程及其协议

① RPC的流程

1.客户端处理过程中调用client stub(就像调用本地方法一样),传入参数
2.Client stub将参数编组为消息,然后通过系统调用向服务端发送消息
3.客户端本地操作系统将消息从客户端机器发送到服务端机器
4.服务端操作系统将接收到的数据包传递给client stub
5.server stub解组消息为参数
6.server stub再调用服务端的过程,过程执行结果以反方向的相同步骤响应给客户端

stub:分布式计算中的存根是一段代码,它转换在远程过程调用期间Client和server之间传递的参数

② 整个流程中需要注意处理的问题

1.client stub和server stub的开发问题
2.参数如何编组为消息,以及如何解组
3.消息如何发送
4.过程结果如何表示,异常情况如何处理
5.如何实现安全的访问控制

③ 核心概念术语

client和server,calls调用,replies响应,services,programs,procedures,version,Marshalling和unmarshalling编组和解组

关于services,programs,procedures,version

一个网络服务由一个或者多个远程程序集构成,而一个远程程序实现一个或多个远程过程。过程与过程参数,结果在程序协议说明书中定义说明,而为兼容程序协议变更,一个服务端可能支持多个版本的远程程序

④ RPC协议

RPC调用过程中需要将参数编组为消息进行发送,接收方需要解组消息为参数,过程处理结果同样需要经过编组解组。消息由哪些部分构成及消息的表示形式就构成了消息协议。RPC调用过程中采用的消息协议成为RPC协议

RPC是规定要做的事,RPC协议规定请求响应消息的格式,在TCP之上我们可以选用或自定义消息协议来完成我们的RPC交互,此时我们可以选用http或者https这种通用的标准协议,也可以根据自身的需要定义自己的消息协议(较多)

RPC框架

RPC框架封装好了参数编组解组,底层网络通信的RPC程序开发框架,让我们可以直接在其基础之上只需要专注于过程代码编写

Java领域的比较常见的RPC框架:webService,Apache的CXF,Axis2,Java自带的jax-ws,微服务常见的dubbo,spring cloud,Apache Thrift,ICE,google的GRPC等

① RPC框架的服务暴露

远程提供者需要以某种形式提供服务调用相关的信息,包括但不限于服务接口定义,数据结构,或者中间态的服务定义文件,例如Thrift的IDL文件,webService的WSDL文件,服务的调用者需要通过一定的途径或者远程服务调用的相关信息,其实简单点说,就是需要告诉别人怎么调用服务

② RPC框架的远程代理对象

代理处理技术:服务调用者用的服务实际是远程服务的本地代理,其实就是通过动态代理来实现

Java里至少提供了两种方式来提供动态代码生成,一种是jdk动态代理,另一种是字节码生成,动态代理相比字节码生成使用起来更方便,但动态代理方式在性能上比字节码要差,而字节码生成在代码可读性上要差很多,所以我们一般都是牺牲一些性能来获得代码可读性和可维护性的提高

③ RPC框架的通信

RPC框架通信和具体的协议是无关的,它可基于HTTP或TCP协议,webService就是基于http协议的RPC,具有更好的跨平台性,但性能却不如基于TCP协议的RPC

NIO其实不一定会比BIO性能要高,NIO只是为了支持高并发而已,特点就是非阻塞的,适合小数据量高并发的场景,大数据包情况下,BIO会更为合适

④ RPC框架的序列化

两个方面会直接影响RPC的性能,一是传输方式,二是序列化

Finally

这一篇全是理论,我们简单过了一遍RPC是什么,三个过程,为什么我们需要它,它的特性和适用场景,RPC的流程及协议定义还有它的框架的一些小知识。也是为了方便下一篇上代码的时候会比较方便阐述

下一篇:从零开始的高并发(八)--- RPC框架的简单实现