想开发IM集群?先搞懂什么是RPC!

本文引用了后端技术指南针公众号“浅谈RPC那些事儿1”和即时通信网的“即时通信新手入门:快速理解RPC技术——基本概念、原理和用途”两篇文章的部份内容。html

一、引言

常常有开发者在纠结怎么开发IM集群,虽然真正的使用人数,可能用我的电脑单机都能支撑。apache

你也许会说,明明不须要用到IM集群,干嘛要自找麻烦?答曰:“老板说这个得有!”、“万一产品作成了,用户量达到百万、千万级呢?”,各类回答,反此种种。总之,IM集群就是得整一个(先甭管用不用的上...)。编程

固然,玩笑归玩笑,真正要作到可投入到生产级别的IM集群系统,难度仍是至关大的。必竟IM这种长链接应用相比传统Http这种短链接应用太不标准。后端

咱们以一个典型的IM聊天消息传输为例:安全

假设存在两个正在聊天的用户(用户A和用户B),当A链接的是IM集群中的IM实例一、B链接的是IM集群中的IM实例2,此时当用户A向用户B发送一条聊天消息时,这条消息应该如何传递呢?服务器

咱们梳理一下上面这个例子的消息流转过程:网络

  • 1)IM聊天消息首先会由用户A发往IM实例1;
  • 2)IM实例1会将此条消息转交给IM实例2;
  • 3)IM实例2会将此条消息最终投递给链接在本实例上的用户B。

如上述流程所示,这就是一个IM集群系统中典型的聊天消息投递过程。数据结构

那么,这其中涉及到一个关键步骤:即第2)步中如何实现“IM实例1会将此条消息转交给IM实例2”?架构

此时,RPC技术出场了!并发

▲ 上图是个典型的分布式IM架构,注意中间的“RPC通讯”字样本图引用自《基于Go的马蜂窝旅游网分布式IM系统技术实践

本文将以通俗易懂的白话形式,帮你快速理解IM集群中的关键技术——RPC。

本文已同步发布于“即时通信技术圈”公众号。

二、正文概述

限于篇幅缘由,本文不会深刻展开RPC的底层技术原理,会尽可能用通俗白话的方式对概念性的东西进行讲解。

经过本文你将主要了解到如下内容:

  • 1)什么是RPC;
  • 2)为何须要RPC;
  • 3)RPC的重要组件;
  • 4)常见RPC框架和各自特色。

三、什么是RPC?

RPC 是1984年代由 Andrew D. Birrell & Bruce Jay Nelson 提出的(见二位大佬的论文《Implementing Remote Procedure Calls),因此它并非最近才有的技术概念。

关于RPC的介绍,正经的资料上大概是这样介绍的:

RPC(Remote Procedure Call)远程过程调用,它是一种经过网络从远程计算机程序上请求服务,而不须要了解底层网络技术的协议。也就是说两台服务器A,B,一个应用部署在A服务器上,想要调用B服务器上应用提供的方法,因为不在一个内存空间,不能直接调用,须要经过网络来表达调用的语义和传达调用的数据。

大白话理解RPC就是:RPC让你用别人家的东西就像本身家的同样。

看得我似懂非懂,因而我不得不问几个问题:

  • 1)为啥要用别人家的东西——请求其余服务);
  • 2)我怎么能够借到别人家的东西——其余服务调用;
  • 3)要是借用的话哪一种形式更好——肯定一个合适的调用方法);
  • 4)怎么让我用别人东西像本身的同样——屏蔽底层细节透明通讯)。

在解答这些问题以前,咱们必须达到一个共识问题:RPC只是一种通讯模式,和http并不冲突对立,相反http能够做为RPC传输数据的一种协议,把RPC看成一种模式和思想,咱们才能更好地理解它。

更严谨的RPC基础知识介绍,请阅读:《即时通信新手入门:快速理解RPC技术——基本概念、原理和用途》。

四、为何须要RPC?

以你们最熟悉的电商系统为例,这样规模的分布式系统,须要拆分出用户服务、商品服务、优惠券服务、支付服务、订单服务、物流服务、售后服务等等。这些服务之间都相互调用,这时内部调用最好使用 RPC ,同时每一个服务均可以独立部署,独立上线。 

也就说当咱们的项目太大,须要解耦服务,扩展性强、部署灵活,这时就要用到 RPC ,这主要是解决了分布式系统中,服务与服务之间的调用问题。

 

▲ 上图中的分布系统内部,就是用RPC实现的本图引用自《重新手到架构师,一篇就够:从100到1000万高并发的架构演进之路

对于IM集群这样的分布式系统来讲,不一样IM实例间的用户聊天消息,就是经过RPC进行流转的。

五、为何不直接使用HTTP,而要搞RPC?

在平常业务中咱们能够把功能封装成静态库、动态库、sdk、独立服务等,最多见也最方便的仍是HTTP这种形式的调用。

HTTP服务把须要提供的服务暴露成接口(也就是一般所说的http rest接口啦),使用方直接按约定的HTTP方法和URI进行数据交互。

咱们都知道HTTP协议是应用层协议,是个很是标准的协议,在HTTP协议之下还有网络层、传输层、数据链路层等,一个数据包packet除了净荷payload以外还有不少header,因为标准和通用性的设计目标也使得HTTP一次数据交互真正传输的payload只是其中一部分。

 

HTTP是咱们用的最多最熟悉的交互模式,在系统内部各个服务之间接口较少,交互很少的状况下工做得还不错。

但若是在内部系统调用很复杂的前提下,HTTP调用的效率和安全性就不那么理想了。

 

以IM系统为例,单个IM实例的吞吐效率至少能够达到几万甚至数十万QPS,使用HTTP这种短链接(调用时创建socket链接,完成后释放链接)方式显的至关低效(每次调用都要从新经历TCP的3次握手、4次挥手过程),在分布式的状况下势必拉低整个IM集群的吞吐效率。而对于RPC,这种socket长链接方式对于高性能场景来讲,效果是显而易见的。

更重要的是面对众多的服务咱们须要的不只仅是一个通讯方式,而是一个内部服务的管理系统,这也就是咱们今天说的RPC框架。注意:RPC是一种模式策略和框架,并非单纯的通讯协议。

题外话:实际上,HTTP在RPC系统中,并非个你死我活的关系,必竟HTTP只是个通讯协议,而HTTP有某些性能要求不敏感的场景来讲,是彻底能够做为RPC的具体实现协议之一来使用的。

六、RPC的调用过程是什么样的?

 

▲ 典型的RPC调用过程

如上图所示,一个典型的RPC调用过程是这样(过程序号对应上图中的数字):

  • 1)客户端(client)以本地调用方式调用服务;
  • 2)客户端存根(client stub)接收到调用后,负责将方法、参数等组装成可以进行网络传输的消息体(将消息体对象序列化为二进制);
  • 3)客户端经过 sockets 将消息发送到服务端;
  • 4)服务端存根(server stub)收到消息后进行解码(将消息对象反序列化);
  • 5)服务端存根(server stub)根据解码结果调用本地的服务;
  • 6)本地服务执行并将结果返回给服务端存根(server stub);
  • 7)服务端存根(server stub)将返回结果打包成消息(将结果消息对象序列化);
  • 8)服务端(server)经过 sockets 将消息发送到客户端;
  • 9)客户端存根(client stub)接收到结果消息,并进行解码(将结果消息发序列化);
  • 10)客户端(client)获得最终结果。

RPC的做用,其实就是要把上述二、三、四、七、八、9 这些步骤都封装起来。是否是很神奇?

七、关于HTTP和RPC的一些争议

HTTP和RPC是两个很容易混淆的概念,对于刚开始接触RPC的人来讲,一般都会困惑:有HTTP了为何还要用RPC?

在知乎上看到了这个颇有趣的问题:《既然有http请求,为何还要用rpc?

其中一个大佬的回答感受颇有意思: 

换个角度来讲:HTTP 与 RPC 的关系就比如普通话与方言的关系。要进行跨企业服务调用时,每每都是经过 HTTP API,也就是普通话,虽然效率不高,可是通用,没有太多沟通的学习成本。可是在企业内部仍是 RPC 更加高效,同一个企业公用一套方言进行高效率的交流,要比通用的 HTTP 协议来交流更加节省资源。整个中国有很是多的方言,正若有不少的企业内部服务各有本身的一套交互协议同样。虽然国家一直在提倡使用普通话交流,可是这么多年过去了,你回一趟家乡探个亲什么的就会发现身边的人仍是流行说方言。

若是再深刻一点说,普通话本质上也是一种方言,只不过它是官方的方言,使用最为普遍的方言,相比而言其它方言都是小语种,小语种之中也会有几个使用比较普遍比较特点的方言占比也会比较大。这就比如开源 RPC 协议中 Protobuf 和 Thrift 同样,它们两应该是 RPC 协议中使用最为普遍的两个。

总之:RPC是一种编程模式和概念,并非很是具体的一种技术,实际上和HTTP没有明确的冲突,HTTP能够做为RPC传输协议,缘由仍是RPCpid际上是一种内部服务框架而不是一个具体的通讯协议,它能够涉及服务注册、服务治理、服务发现、熔断机制、负载均衡等。

八、典型的RPC框架

一个典型RPC框架中,包含了服务发现、负载、容错、网络传输、序列化等组件,其中“RPC 协议”就指明了程序如何进行网络传输和序列化。

▲ 一个典型的 RPC 架构原理图本图引用自《即时通信新手入门:快速理解RPC技术——基本概念、原理和用途

▲ 著名RPC框架Dubbo的架构图本图引用自《即时通信新手入门:快速理解RPC技术——基本概念、原理和用途

一个 RPC 最重要的功能模块,就是上图中的”RPC 协议”部分: 

其中的序列化和反序列化的意思是:

  • 1)序列化:将数据结构或对象转换成二进制串的过程;
  • 2)反序列化:将序列化中所生成的二进制串转换成数据结构或者对象的过程。

在网络消息传输中能够基于TCP、UDP、http来实现,各自都有各自的特色。

基于 TCP 实现的 RPC 调用,可以灵活对协议字段进行定制,减小网络开销提升性能,实现更大的吞吐量和并发数,但要关注底层细节,在进行数据解析时更加复杂一些(好比最受欢迎的Protobuf的使用)。

基于 HTTP 实现的 RPC 可使用 JSON 和 XML 格式的请求或响应数据,解析工具很成熟,在其上进行二次开发会很是便捷和简单。可是 HTTP 是上层协议,所占用的字节数会比使用 TCP 协议传输所占用的字节数更高。

对于其余部分,本文再也不展开。

九、市面上常见的RPC框架及其特色

常见 RPC 技术和框架有:

  • 1)应用级的服务框架:阿里的 Dubbo/Dubbox、Google gRPC、Spring Boot/Spring Cloud。
  • 2)远程通讯协议:RMI、Socket、SOAP(HTTP XML)、REST(HTTP JSON)。
  • 3)通讯框架:MINA 和 Netty。

目前流行的开源 RPC 框架仍是比较多的,有阿里巴巴的 Dubbo、Facebook 的 Thrift、Google 的 gRPC、Twitter 的 Finagle 等。

下面重点介绍当前最流行的三种RPC框架主要特色:

  • 1)gRPC:是 Google 公布的开源软件,基于最新的 HTTP 2.0 协议,并支持常见的众多编程语言。RPC 框架是基于 HTTP 协议实现的,底层使用到了 Netty 框架的支持;
  • 2)Thrift:是 Facebook 的开源 RPC 框架,主要是一个跨语言的服务开发框架。用户只要在其之上进行二次开发就行,应用对于底层的 RPC 通信等都是透明的。不过这个对于用户来讲须要学习特定领域语言这个特性,仍是有必定成本的;
  • 3)Dubbo:是阿里集团开源的一个极为出名的 RPC 框架,在不少互联网公司和企业应用中普遍使用。协议和序列化框架均可以插拔是极其鲜明的特点。(本文同步发布于:http://www.52im.net/thread-2996-1-1.html