正本清源rpc
先弄明白什么是RPC。
RPC(Remote Procedure Call)—远程过程调用,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。RPC协议假定某些传输协议的存在,如TCP或UDP,为通信程序之间携带信息数据。在OSI网络通信模型中,RPC跨越了传输层和应用层。RPC使得开发包括网络分布式多程序在内的应用程序更加容易。
RPC采用客户机/服务器模式。请求程序就是一个客户机,而服务提供程序就是一个服务器。首先,客户机调用进程发送一个有进程参数的调用信息到服务进程,然后等待应答信息。在服务器端,进程保持睡眠状态直到调用信息到达为止。当一个调用信息到达,服务器获得进程参数,计算结果,发送答复信息,然后等待下一个调用信息,最后,客户端调用进程接收答复信息,获得进程结果,然后调用执行继续进行。
有多种 RPC模式和执行。最初由 Sun 公司提出。IETF ONC 宪章重新修订了 Sun 版本,使得 ONC RPC 协议成为 IETF 标准协议。现在使用最普遍的模式和执行是开放式软件基础的分布式计算环境(DCE)。
这个解释挺复杂的,但是我们可以简单的理解一下,毕竟,现在已经不是以前那个年代了。
还是先来看一下,没有PRC的时候,会怎么样。
在过去是这样的,包括现在很多对企业服务可能也是这样的,只有一个包部署在Tomcat里。
那个时候,没什么需要用到RPC的场景。
然后当用户量大的时候呢?渐渐出现了负载均衡。
大概是这个样子。
负载均衡能解决的问题很多,但是还是不够好,比如说,只是某一个功能模块(假设是用户中心)被访问的次数特别频繁,我可不可以把这部分内容单独拿出去?用户中心的机器独立,给它单独的带宽,给他单独的服务器,给他单独的数据库?
不这么干其他的功能模块都干不下去了啊。
好比是原来是学校餐厅,可以同时供200个人用餐,但是修真院的饺子馆生意特别好,每次来吃饭的人都有5000人,占满了所有餐椅,排队几万米,餐厅的其他摊位肯定不乐意了吧?
比如说那个卖炒菜的,虽然我每天只有30来个人吃饭,那也是钱啊,你人这么多,想来我这边吃饭的人都找不着了。
大概的情景应该是这样的。
能理解么?
遇到这种场景怎么办?不可能不让修真院饺子馆开门啊,那最好的方式就是:
你可不可以搬出去?
你不搬我们搬也行!(哭泣脸,反正我们是再也不要和你家饺子馆开在一起了,必须给我们一个说法)
那么,搬家之后的样子可能是这样的。
嗯啊。分是分开了,然后餐卡什么的还是在一起,还是和其他摊位一样,给大家提供就餐的功能。这就是分而治之,哪怕你修真院饺子馆关门了,也不影响我,这又叫分布式。
说到分布式,就问题就来了。
可不可以互相调用?其实细分下去,买菜,切菜,结账这些都是独立的流程,我们能不能都把它们独立出来?
当然是可以的,但是带来的问题就是,如何通信?大家都不在一个进程里。
这种通信的方式,就叫做RPC,在今天,RPC已经不仅仅是远程,这个远程,确切来说,就是指不在一个进程内,只能通过其他协议来完成,通常都是TCP或者是Http。
好了,RPC讲清楚了,再看RPC的重点是什么。
不能太慢,对不对?如果太慢了,怎么办?
这种性能的要求,要做到什么程度?希望是和在同一个进程里,一致的体验。
Http能做到这种程度么?
不行。Http(TCP)本身的三次握手协议,就会带来大概1MS的延迟(emmm,这个数据其实我有点不确定了,也可能是几微秒,很早之前做过测试)。
每发送一次请求,都会有一次建立连接的过程,加上Http报文本身的庞大,以及Json的庞大,都需要作一些优化。
一般的场景下,没什么问题,但是对于Google这种级别的公司,他们接受不了。
几MS的延迟可能就导致多出来几万台服务器,所以他们想尽办法去优化,优化从哪方面入手?
1.减少传输量。
2.简化协议。
3.用长连接,不再每一个请求都重新走三次握手流程
Http的协议就注定了,在高性能要求的下,不适合用做线上分布式服务之间互相使用的通信协议。
而常见的几种高效的协议有:protocolBuffer,Thrift,Hessian,RMI等。
对我们而言,可能是使用Http就够了~~;但有些场景下极限的追求,是普通人一生都难达到的境界啊。