500亿网站建设,wordpress 买主题,网站管理后台如果在代理商那里接手会不会停掉,佛山网站建设公司分享微信营销的五个技巧既然有HTTP协议#xff0c;为什么还要有RPC#xff1f;
从TCP聊起
作为一个程序员#xff0c;假设我们需要在A电脑的进程发一段数据到B电脑的进程#xff0c;我们一般会在代码里使用socket进行编程。
这时候#xff0c;我们可选项一般也就TCP和UDP二选一。TCP可靠…既然有HTTP协议为什么还要有RPC
从TCP聊起
作为一个程序员假设我们需要在A电脑的进程发一段数据到B电脑的进程我们一般会在代码里使用socket进行编程。
这时候我们可选项一般也就TCP和UDP二选一。TCP可靠UDP不可靠。除非是马总这种神级程序员早期QQ大量使用UDP否则只要稍微对可靠性有些要求普通人一般无脑选TCP就对了。
类似下面这样。
fd socket(AF_INET,SOCK_STREAM,0);其中SOCK_STREAM是指使用字节流传输数据说白了就是TCP协议。
在定义了socket之后我们就可以愉快的对这个socket进行操作比如用bind()绑定IP端口用connect()发起建连。 在连接建立之后我们就可以使用send()发送数据recv()接收数据。
光这样一个纯裸的TCP连接就可以做到收发数据了那是不是就够了
不行这么用会有问题。
使用纯裸TCP会有什么问题
八股文常背TCP是有三个特点面向连接、可靠、基于字节流。 这三个特点真的概括的非常精辟这个八股文我们没白背。
每个特点展开都能聊一篇文章而今天我们需要关注的是基于字节流这一点。
字节流可以理解为一个双向的通道里流淌的数据这个数据其实就是我们常说的二进制数据简单来说就是一大堆 01 串。纯裸TCP收发的这些 01 串之间是没有任何边界的你根本不知道到哪个地方才算一条完整消息。 正因为这个没有任何边界的特点所以当我们选择使用TCP发送夏洛和特烦恼的时候接收端收到的就是夏洛特烦恼这时候接收端没发区分你是想要表达夏洛特烦恼还是夏洛特烦恼。 这就是所谓的粘包问题。
说这个的目的是为了告诉大家纯裸TCP是不能直接拿来用的你需要在这个基础上加入一些自定义的规则用于区分消息边界。
于是我们会把每条要发送的数据都包装一下比如加入消息头消息头里写清楚一个完整的包长度是多少根据这个长度可以继续接收数据截取出来后它们就是我们真正要传输的消息体。 而这里头提到的消息头还可以放各种东西比如消息体是否被压缩过和消息体格式之类的只要上下游都约定好了互相都认就可以了这就是所谓的协议。
每个使用TCP的项目都可能会定义一套类似这样的协议解析标准他们可能有区别但原理都类似。
于是基于TCP就衍生了非常多的协议比如HTTP和RPC。
HTTP和RPC
我们回过头来看网络的分层图。 TCP是传输层的协议而基于TCP造出来的HTTP和各类RPC协议它们都只是定义了不同消息格式的应用层协议而已。
HTTP协议Hyper Text Transfer Protocol又叫做超文本传输协议。我们用的比较多平时上网在浏览器上敲个网址就能访问网页这里用到的就是HTTP协议。 而RPCRemote Procedure Call又叫做远程过程调用。它本身并不是一个具体的协议而是一种调用方式。
举个例子我们平时调用一个本地方法就像下面这样。 res localFunc(req)如果现在这不是个本地方法而是个远端服务器暴露出来的一个方法remoteFunc如果我们还能像调用本地方法那样去调用它这样就可以屏蔽掉一些网络细节用起来更方便岂不美哉 res remoteFunc(req)基于这个思路大佬们造出了非常多款式的RPC协议比如比较有名的gRPCthrift。
值得注意的是虽然大部分RPC协议底层使用TCP但实际上它们不一定非得使用TCP改用UDP或者HTTP其实也可以做到类似的功能。 到这里我们回到文章标题的问题。
既然有HTTP协议为什么还要有RPC
其实TCP是70年代出来的协议而HTTP是90年代才开始流行的。而直接使用裸TCP会有问题可想而知这中间这么多年有多少自定义的协议而这里面就有80年代出来的RPC。
所以我们该问的不是既然有HTTP协议为什么要有RPC而是为什么有RPC还要有HTTP协议。
那既然有RPC了为什么还要有HTTP呢
现在电脑上装的各种联网软件比如xx管家xx卫士它们都作为客户端client需要跟服务端server建立连接收发消息此时都会用到应用层协议在这种client/server (c/s)架构下它们可以使用自家造的RPC协议因为它只管连自己公司的服务器就ok了。
但有个软件不同浏览器browser不管是chrome还是IE它们不仅要能访问自家公司的服务器server还需要访问其他公司的网站服务器因此它们需要有个统一的标准不然大家没法交流。于是HTTP就是那个时代用于统一 browser/server (b/s) 的协议。
也就是说在多年以前HTTP主要用于b/s架构而RPC更多用于c/s架构。但现在其实已经没分那么清了b/s和c/s在慢慢融合。很多软件同时支持多端比如某度云盘既要支持网页版还要支持手机端和pc端如果通信协议都用HTTP的话那服务器只用同一套就够了。而RPC就开始退居幕后一般用于公司内部集群里各个微服务之间的通讯。
那这么说的话都用HTTP得了还用什么RPC
仿佛又回到了文章开头的样子那这就要从它们之间的区别开始说起。
HTTP和RPC有什么区别
我们来看看RPC和HTTP区别比较明显的几个点。
服务发现
首先要向某个服务器发起请求你得先建立连接而建立连接的前提是你得知道IP地址和端口。这个找到服务对应的IP端口的过程其实就是服务发现。
在HTTP中你知道服务的域名就可以通过DNS服务去解析得到它背后的IP地址默认80端口。
而RPC的话就有些区别一般会有专门的中间服务去保存服务名和IP信息比如consul或者etcd甚至是redis。想要访问某个服务就去这些中间服务去获得IP和端口信息。由于dns也是服务发现的一种所以也有基于dns去做服务发现的组件比如CoreDNS。
可以看出服务发现这一块两者是有些区别但不太能分高低。
底层连接形式
以主流的HTTP1.1协议为例其默认在建立底层TCP连接之后会一直保持这个连接keep alive之后的请求和响应都会复用这条连接。
而RPC协议也跟HTTP类似也是通过建立TCP长链接进行数据交互但不同的地方在于RPC协议一般还会再建个连接池在请求量大的时候建立多条连接放在池内要发数据的时候就从池里取一条连接出来用完放回去下次再复用可以说非常环保。 由于连接池有利于提升网络请求性能所以不少编程语言的网络库里都会给HTTP加个连接池比如go就是这么干的。
可以看出这一块两者也没太大区别所以也不是关键。
传输的内容
基于TCP传输的消息说到底无非都是消息头header和消息体body。
header是用于标记一些特殊信息其中最重要的是消息体长度。
body则是放我们真正需要传输的内容而这些内容只能是二进制01串毕竟计算机只认识这玩意。所以TCP传字符串和数字都问题不大因为字符串可以转成编码再变成01串而数字本身也能直接转为二进制。但结构体呢我们得想个办法将它也转为二进制01串这样的方案现在也有很多现成的比如jsonprotobuf。
这个将结构体转为二进制数组的过程就叫序列化反过来将二进制数组复原成结构体的过程叫反序列化。 对于主流的HTTP1.1虽然它现在叫超文本协议支持音频视频但HTTP设计初是用于做网页文本展示的所以它传的内容以字符串为主。header和body都是如此。在body这块它使用json来序列化结构体数据。
我们可以随便截个图直观看下。 可以看到这里面的内容非常多的冗余显得非常啰嗦。最明显的像header里的那些信息其实如果我们约定好头部的第几位是content-type就不需要每次都真的把content-type这个字段都传过来类似的情况其实在body的json结构里也特别明显。
而RPC因为它定制化程度更高可以采用体积更小的protobuf或其他序列化协议去保存结构体数据同时也不需要像HTTP那样考虑各种浏览器行为比如302重定向跳转啥的。因此性能也会更好一些这也是在公司内部微服务中抛弃HTTP选择使用RPC的最主要原因。 HTTP原理 RPC原理
当然上面说的HTTP其实特指的是现在主流使用的HTTP1.1HTTP2在前者的基础上做了很多改进所以性能可能比很多RPC协议还要好甚至连gRPC底层都直接用的HTTP2。
那么问题又来了。
为什么既然有了HTTP2还要有RPC协议
这个是由于HTTP2是2015年出来的。那时候很多公司内部的RPC协议都已经跑了好些年了基于历史原因一般也没必要去换了。
总结 纯裸TCP是能收发数据但它是个无边界的数据流上层需要定义消息格式用于定义消息边界。于是就有了各种协议HTTP和各类RPC协议就是在TCP之上定义的应用层协议。 RPC本质上不算是协议而是一种调用方式而像gRPC和thrift这样的具体实现才是协议它们是实现了RPC调用的协议。目的是希望程序员能像调用本地方法那样去调用远端的服务方法。同时RPC有很多种实现方式不一定非得基于TCP协议。 从发展历史来说HTTP主要用于b/s架构而RPC更多用于c/s架构。但现在其实已经没分那么清了b/s和c/s在慢慢融合。很多软件同时支持多端所以对外一般用HTTP协议而内部集群的微服务之间则采用RPC协议进行通讯。 RPC其实比HTTP出现的要早且比目前主流的HTTP1.1性能要更好所以大部分公司内部都还在使用RPC。 HTTP2.0在HTTP1.1的基础上做了优化性能可能比很多RPC协议都要好但由于是这几年才出来的所以也不太可能取代掉RPC。