前言
哎,本来今天是想写一篇关于go语言的学习笔记的,但是想想还是算了吧,本来自己领域里面的东西都还是半吊子,还是先把一门做深入了来吧 /摊手 。于是乎想起了之前上家公司用的dubbo和现在在做的spring cloud,两者的传输协议默认是rpc和http,要理解这两种协议,还得从OSI七层模型说起。记得当时在自考时还学过计算机网路原理这门科目,现在看来,真是考试完就忘了,重新系统的学一遍吧。
七层模型
自底向上,物理层为最底层
OSI七层模型 | 功能 | 相关协议 |
---|---|---|
应用层 | 最终提供出来的接口。也就是终端应用,这一层是最直观展现给终端用户的。【比如浏览器,QQ】 | HTTP、TFTP, FTP, NFS, WAIS、SMTP |
表示层 | 数据的表示、安全、压缩。将计算机识别的东西解析成人能识别的东西。【比如声音,图片】 | Telnet, Rlogin, SNMP, Gopher |
会话层 | 通过传输层建立数据传输通路实现建立、管理、终止回话。继而最终表现形式为,本地主机与远程主机会话【比如本地主机请求‘百度’本质上是本机ip请求‘百度’服务器ip,这种过程即为一次会话】 | SMTP, DNS |
传输层 | 定义了一些传输数据的协议和端口,如TCP和UDP,主要将下层接收的数据进行分段和传输,到达目的地址后进行重组,当数据包一旦离开以太网卡即进入网络传输层 | TCP, UDP |
网络层 | 选择合适的网间路由和交换结点,确保数据的即使传送,将从下层接收到的数据进行ip地址的封装和解封装。 | IP, ICMP, ARP, RARP |
数据链路层 | 主要将从物理层接收的数据进行MAC地址的封装和解封装。常把这一层的数据叫做帧,主要设备是网卡和交换机 | FDDI,PPP,STP,帧中继 |
物理层 | 主要定义物理设备标准,如网线的接口类型、各种传输介质的传输速度等,主要作用是传输bit流【二进制数据】 | IEEE 802.1A, IEEE 802.2到IEEE 802. |
- OSI模型对应TCP/IP模型
由上图,我们可以引出,在实际应用过程中,五层协议结构里面是没有表示层和会话层的,也就是说表示层和会话层合并成了应用层。所以平时我们为什么说RPC服务要比HTTP服务效率更高,是应为HTTP是属于应用层协议,RPC是属于传输层协议;就像存汇编要比Java快一个道理,因为人家更底层。
RPC服务与HTTP服务
【备注】本节内容转载自CSDN
【原链接】https://blog.csdn.net/wangyunpeng0319/article/details/78651998
【原作者】wangyunpeng0319
RPC服务
从三个角度来介绍RPC服务:分别是RPC架构,同步异步调用以及流行的RPC框架。
RPC架构
先说说RPC服务的基本架构吧。允许我可耻地盗一幅图哈~我们可以很清楚地看到,一个完整的RPC架构里面包含了四个核心的组件,分别是Client ,Server,Client Stub以及Server Stub,这个Stub大家可以理解为存根。分别说说这几个组件:
- 客户端(Client),服务的调用方。
- 服务端(Server),真正的服务提供者。
- 客户端存根,存放服务端的地址消息,再将客户端的请求参数打包成网络消息,然后通过网络远程发送给服务方。
- 服务端存根,接收客户端发送过来的消息,将消息解包,并调用本地的方法。
RPC主要是用在大型企业里面,因为大型企业里面系统繁多,业务线复杂,而且效率优势非常重要的一块,这个时候RPC的优势就比较明显了。实际的开发当中是这么做的,项目一般使用maven来管理。比如我们有一个处理订单的系统服务,先声明它的所有的接口(这里就是具体指Java中的interface
),然后将整个项目打包为一个jar
包,服务端这边引入这个二方库,然后实现相应的功能,客户端这边也只需要引入这个二方库即可调用了。为什么这么做?主要是为了减少客户端这边的jar
包大小,因为每一次打包发布的时候,jar
包太多总是会影响效率。另外也是将客户端和服务端解耦,提高代码的可移植性。
同步异步调用
什么是同步调用?什么是异步调用?同步调用
就是客户端等待调用执行完成并返回结果。异步调用
就是客户端不等待调用执行完成返回结果,不过依然可以通过回调函数等接收到返回结果的通知。如果客户端并不关心结果,则可以变成一个单向的调用。这个过程有点类似于Java中的callable
和runnable
接口,我们进行异步执行的时候,如果需要知道执行的结果,就可以使用callable
接口,并且可以通过Future
类获取到异步执行的结果信息。如果不关心执行的结果,直接使用runnable
接口就可以了,因为它不返回结果,当然啦,callable
也是可以的,我们不去获取Future
就可以了。
流行的RPC框架
目前流行的开源RPC框架还是比较多的。下面重点介绍三种:
- gRPC是Google最近公布的开源软件,基于最新的HTTP2.0协议,并支持常见的众多编程语言。 我们知道HTTP2.0是基于二进制的HTTP协议升级版本,目前各大浏览器都在快马加鞭的加以支持。 这个RPC框架是基于HTTP协议实现的,底层使用到了Netty框架的支持。
- Thrift是Facebook的一个开源项目,主要是一个跨语言的服务开发框架。它有一个代码生成器来对它所定义的IDL定义文件自动生成服务代码框架。用户只要在其之前进行二次开发就行,对于底层的RPC通讯等都是透明的。不过这个对于用户来说的话需要学习特定领域语言这个特性,还是有一定成本的。
- Dubbo是阿里集团开源的一个极为出名的RPC框架,在很多互联网公司和企业应用中广泛使用。协议和序列化框架都可以插拔是及其鲜明的特色。同样 的远程接口是基于Java Interface,并且依托于spring框架方便开发。可以方便的打包成单一文件,独立进程运行,和现在的微服务概念一致。
偷偷告诉你
集团内部已经不怎么使用dubbo啦,现在用的比较多的叫HSF,又名“好舒服”。后面有可能会开源,大家拭目以待。
HTTP服务
其实在很久以前,我对于企业开发的模式一直定性为HTTP接口开发,也就是我们常说的RESTful风格的服务接口。的确,对于在接口不多、系统与系统交互较少的情况下,解决信息孤岛初期常使用的一种通信手段;优点就是简单、直接、开发方便。利用现成的http协议进行传输。我们记得之前本科实习在公司做后台开发的时候,主要就是进行接口的开发,还要写一大份接口文档,严格地标明输入输出是什么?说清楚每一个接口的请求方法,以及请求参数需要注意的事项等。比如下面这个例子:POST http://www.httpexample.com/restful/buyer/info/share
接口可能返回一个JSON字符串或者是XML文档。然后客户端再去处理这个返回的信息,从而可以比较快速地进行开发。但是对于大型企业来说,内部子系统较多、接口非常多的情况下,RPC框架的好处就显示出来了,首先就是长链接,不必每次通信都要像http一样去3次握手什么的,减少了网络开销;其次就是RPC框架一般都有注册中心,有丰富的监控管理;发布、下线接口、动态扩展等,对调用方来说是无感知、统一化的操作。
优缺点对比
【备注】本节内容转载自简书
【原链接】https://www.jianshu.com/p/b61695e6b473
【原作者】JouyPub
传输协议
- RPC,可以基于TCP协议,也可以基于HTTP协议
- HTTP,基于HTTP协议
传输效率
- RPC,使用自定义的TCP协议,可以让请求报文体积更小,或者使用HTTP2协议,也可以很好的减少报文的体积,提高传输效率
- HTTP,如果是基于HTTP1.1的协议,请求中会包含很多无用的内容,如果是基于HTTP2.0,那么简单的封装以下是可以作为一个RPC来使用的,这时标准RPC框架更多的是服务治理
- 性能消耗,主要在于序列化和反序列化的耗时
- RPC,可以基于thrift实现高效的二进制传输
- HTTP,大部分是通过json来实现的,字节大小和序列化耗时都比thrift要更消耗性能
- 负载均衡
- RPC,基本都自带了负载均衡策略
- HTTP,需要配置Nginx,HAProxy来实现
- 服务治理(下游服务新增,重启,下线时如何不影响上游调用者)
- RPC,能做到自动通知,不影响上游
- HTTP,需要事先通知,修改Nginx/HAProxy配置
三次握手四次挥手
【备注】本节内容转载自阿里云
【原链接】https://www.aliyun.com/jiaocheng/1367320.html
【原作者】阿里云
摘要:HTTP是一个属于应用层的超文本传输协议(HTTP,HyperTextTransferProtocol)是互联网上应用最为广泛的一种网络协议。所有的WWW文件都必须遵守这个标准。TCP(TransmissionControlProtocol传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议。采用三次握手确认建立一个连接。我们说的http的三次握手,其实是TCP的三次握手:TCP通过发送位码来判断一个连接建立的状态,位码就是一个标识位,有6种:SYN(synch
HTTP是一个属于应用层的超文本传输协议(HTTP,HyperText Transfer Protocol)是互联网上应用最为广泛的一种网络协议。所有的WWW文件都必须遵守这个标准。
TCP(Transmission Control Protocol 传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议。采用三次握手确认建立一个连接。
我们说的http的三次握手,其实是TCP的三次握手:
TCP通过发送位码来判断一个连接建立的状态,位码就是一个标识位,有6种:- SYN(synchronous建立联机)
- ACK(acknowledgement 确认)
- PSH(push传送)
- FIN(finish结束)
- RST(reset重置)
- URG(urgent紧急)
三次握手
第一次握手:主机A发送位码为SYN = 1,同时随机生成一个seq number=1253234的数据包到服务器,主机B由SYN=1知道,A要求联机;
第二次握手:主机B收到请求后要确认联机信息,向主机A发送 ACK number = (主机A的seq+1),SYN = 1,ACK = 1,随机产生seq = 7867867的包;
第三次握手:主机A收到后检查ACK number是否正确,即第一次发送的seq number+1以及ACK是否为1,若正确,主机A会再发送ACK number= (主机B的seq+1),ACK=1,主机B收到后确认seq值与ACK=1则建立连接。
至此三次握手完成,连接建立成功。
这一过程内部大概是这样的,第一次握手,主机A发送SYN(SYN=J)包到服务器,并进入SYN_SEND状态,等待服务器确认;
第二次握手,服务器收到SYN包,必须确认主机A的SYN值为1,即要建立连接,同时自己发送一个SYN包给主机A,SYN(SYN = K),即SYN+ACK包,此时服务器进入SYN_RECV状态,
第三次握手,客户端收到客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ACK = K+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手,开始传送数据。
例子:
ip 192.168.1.21:3685 –> 192.168.1.122:6656 S 456523354
ip 192.168.1.122:6656 –> 192.168.1.21:3685 S 348983483: 348983483 ACK 456523355
ip 192.168.1.21:3685 –> 192.168.1.122:6656 ACK 348983484,ACK 1
第一次握手:192.168.1.21发送位码 SYN = 1,随机产生seq number = 456523354
的数据包到192.168.1.122 由SYN = 1知道192.168.1.21要求建立联机
第二次握手:192.168.1.122收到请求后要确认联机信息,向192.168.1.21发送ACK number = 456523355,SYN = 1,ACK = 1,随机产生的seq = 348983483的包
第三次握手:192.168.1.21收到数据包检查 ACK num是否等于第一次发送的seq+1,以及ACK是否为1,若正确,会再次发送ack number = 348983484,ack =1的包给192.168.1.122
192.168.1.122收到后确认seq = seq+1,ack=1则连接建立成功。
四次挥手
其实 就是对应的断开的过程:
1.客户端请求断开连接:FIN = 1, seq = u;
2.服务端对客户端的请求响应:ACK = 1,seq = v,ack = u+1;
3.服务端请求断开连接:FIN = 1,ACK =1,seq = w,ack = u+1;
4.客户端对服务端的请求响应:ACK=1,seq = u+1,ack = w+1;
总结
现在回想起来,当初学计算机网络原理的时候,简直就是死记硬背应付考试。以上大多是转载留作自己的学习资料,懒得以后到处翻。嘛,就这样吧