网络与grpc
gRPC
rpc,远程过程调用,通过计算机网络从一个节点调用另一个节点的服务,就像本地调用一样。rpc是一个协议,遵循协议实现的框架为rpc框架,比较典型的有 Dubbo、Thrift 和 gRPC
rpc调用过程
rpc框架组成
rpc和http区别
-
RPC 是远程过程调用,其调用协议通常包括序列化协议和传输协议。序列化协议有基于纯文本的 XML 和 JSON、二进制编码的Protobuf和Hessian。传输协议是指其底层网络传输所使用的协议,比如 TCP、HTTP。
-
grpc使用的传输协议就是http2.0
有名的rpc框架:go rpc、grpc、Thrift
TCP/UDP
https://segmentfault.com/a/1190000038526729
https://blog.csdn.net/weixin_38586230/article/details/106604173
模型
物理层
传输0101比特流、遵循规范
数据链路层
数据链路=若干链路+协议(包含实现协议的硬件+软件)
-
封装成帧:最大传送单元MTU、做个首尾标记,也称为帧定界(确认帧的界限)
用什么标记做为定界符呢?不可打印的ASCII码占了33个(用这部分)
-
透明传输
数据部分中的部分字节的二进制代码恰好和帧的开始符与结束符一样,那么就会错误的找到帧的边界
解决方案:字符转义(俄罗斯套娃)、传给上层时删除即可
-
差位检测
检测数据是否出错:多数为CRC检测、但无法解决数据丢失、重复、乱序,交给传输层(tcp
点对点ppp协议(使用最广)
-
封装成帧
-
0x7E 标记开始、结束;字段A规定为0xFF,控制字段C规定为0x03
-
第四个为协议字段。0x0021:PPP帧的信息字段就是IP数据报。0xC021:则信息字段是PPP链路控制协议LCP的数据,而0x8021表示这是网络层的控制数据(NCP,如IPCP)。
-
信息字段的长度是可变的,不超过1500字节
-
尾部中的第一个字段(2字节)是使用CRC的帧检验序列FCS
-
字节填充
异步传输时,转义字符定义为0x7D(即01111101)
-
数据中出现帧标志字段,0x7E字节,那就转变成为2字节序列(0x7D,0x5E)
-
数据中出现一个转义字符,0x7D字节,则把0x7D转变成为2字节序列(0x7D,0x5D)
-
数据中出现ASCII码的控制字符,则在该字符前面要加入一个0x7D字节,同时将该字符的编码加以改变
-
0比特填充
-
工作流程
-
适配器
计算机的硬件地址MAC地址就在适配器的ROM中,而计算机的软件地址——IP地址则在计算机的存储器中
MAC地址
MAC地址一共6个字节,每个字节8位,一共是48位,前24位是买的
第一个字节的最低位为I/G位,0代表个人,1代表组地址(企业、学校等单位
第一字节的最低第二位规定位G/L位,0代表是全球管理,1是本地管理
剩下2的46次个MAC地址,超过70万亿个
网络层(IP
功能:分组或包传输、路由(不保证可靠性
IP协议
MAC地址与IP地址
IP分类
IP地址全0为保留位、全1位测试位(只有A类可能全0)
ARP协议
每一台主机有一个ARP高速缓存( ARP cache),存储本局域网上的主机、路由器的IP到MAC的映射
过程:
-
主机A广播ARP请求
-
局域网内其他主机收到ARP请求,查看ip和自己是否一致,一致则发送单播ARP响应,写入MAC地址到响应中
-
更有效率,主机A广播时加入自己的ip、mac地址,其他主机可以写入自己的ARP cache中
更全面的回答:
问题:如果不在一个局域网?
缓存的不是IP、MAC;而是IP、下一条路由器的MAC地址(经常变化),路由器去广播
路由器-路由表
IP包数据格式
-
版本:IPv4还是IPv6
-
首部长度:最大是15,但它的单位是4字节,也就是最大60字节,最常用的首部长度是20字节,(首部长度位0101)区分服务:一般情况不使用
-
总长度:首部和数据之和的长度,单位字节,最大长度为2的16次-1=65535字节,实际上以太网规定最大1500字节,否则分片
-
标识:切片后,相同标识字段的值使分片后的各个数据报片最后能重装起来
-
标志:虽然占3位,但只有后2位有意义,中间位DF,当DF=0允许分片,最低位MF,MF=1,表示后面还有分片的数据报,MF=0表示这个最后一片。
-
片偏移:分片后,表示该片在原分组中的相对位置。
-
生存时间:TTL,单位跳数,指明数据报在互联网最多可以经过多少个路由器。初始值为1,意味着只能在该局域网中传输。
-
协议:指出此数据报携带的数据使用的使什么协议,方便网络层交接
-
首部检验和:只检验数据报的首部,不包括数据部分。
-
源地址
-
目的地址
-
可选字段:用来支持排错、测量以及安全等措施,很少使用
划分子网
IP地址={<网络号>,<子网号>,<主机号>}
子网掩码:没有1、15、16 因为没有意义
怎么求子网地址?(ip地址与掩码做位与操作)
若不划分子网,则
A类地址的默认子网掩码:255.0.0.0 B类地址的默认子网掩码:255.255.0.0 C类地址的默认子网掩码:255.255.255.0
则路由表需要升级:(目的网络地址,子网掩码,下一跳地址)
构建超网(CIDR)
解决问题:自由分配IP
IP地址={<网络前缀>,<主机号>} IP/位数,位数代表不可更改的前缀
带来的问题:
-
子网掩码?就是IP/位数,位数为全1,/20地址块的地址掩码是:11111111 11111111 11110000 00000000(20个连续的1)
-
怎么确定网络号?对所有可能的前缀进行循环查找,给定一个IP地址D,对每一个可能的前缀长度M,路由器从D中提取前M个位当为网络前缀,去路由表中查找,找到的最长匹配就是
ping
协议类型:ICMP,没有经过传输层(TCP/UDP)
原理:把ICMP报文封装在IP数据包发送、确认响应失败原因
但是ICMP现在很多时候为了安全考虑,有时会禁用。下图就是黑客一种常用的手段。
路由选择协议
路由器:多个入口、多个出口、转发分组
路由表
一般的路由表都有10万条左右的路由项
路由算法
-
静态路由选择策略=纯手工,管理员自行设定
-
动态路由选择策略=自动更新,适应网络状态的变化,开销大(采用)
路由器会给相邻的路由器发送自己已知的网络连接信息,整个网络的路由控制表就制作完成了。
路由协议
-
内部网关协议IGP,使用多的如:RIP协议、OSPF协议
-
外部网关协议EGP,使用多的是:BGP-4
-
内部网关协议RIP
RIP属于距离向量型的路由协议,根据距离和方向决定目标网络或目标主机位置
这里的距离=跳数(就是经过的路由器数目)
-
内部网关协议OSPF
分布式的链路状态协议,而不是像RIP一样是距离向量协议。
最后所有的路由器会建立一个完整的链路状态数据库,相当于全网的拓扑结构图,而且这个图在全网范围内是唯一的。
问题?全球不现实,就对一个自治系统划分为若干个更小的范围
-
外部网关协议BGP
IPV6(16*8=128)
如何转化?
DNS返回的ipv4,则发送ipv4包,否则发送ipv6包
双协议栈问题:IPv6中的有些字段是无法恢复的
必须把IPv4首部的协议字段的值设置为41,表示数据报的数据部分是IPv6数据报
IP多播
多播组的标识符就是IP地址中的D类地址,只能用于目的地址,不能用于源地址,地址范围:224.0.0.0到239.255.255.255
传输层
功能:向它上面的应用层提供通信服务的。
网络层公用、传输层分端口(进程)使用
UDP
特点:不可靠的、无连接、报文形式、传输快、支持n对n
8字节
TCP(重点)
特点:tcp是可靠的、面向连接的、字节流服务、传输慢
三次握手
SYN 同步报文段
ACK 确认报文段
第二次连接是SYN+ACK
-
为什么不是两次?
-
考虑一种情况,A发给B的请求由于网络延迟了,A没收到响应超时重发,两次请求都会建立连接(因为没有第三次握手,A知道重复了,但是B不知道)
-
A是坏人,不停的发请求包,由于没有第三次握手,B会不停的建立连接
四次挥手
-
为何要等待2MSL
-
B如果没收到最后一个ack,会重新发送请求
-
保证所有的数据已经消失了
可靠性
可靠的原因
-
确认和重传机制
-
数据排序
-
流量控制
-
拥塞控制
TCP格式
-
源端口和目的端口: 端口号
-
序号: 文件报文编号
-
确认号,一般是序号+1
-
数据偏移
-
保留
-
紧急URG(URGent) 当URG=1时,表明此报文字段有紧急数据,应尽快传送,优先级高于普通数据,也就不会按照之前的排队顺序来传送
-
确认ACK ACK=1才表示确认号有效,所以在建立连接后所有的报文段的ACK都等于1
-
推送PSH(push)很少使用
-
复位RST(reset)当RST=1表示TCP连接中出现问题,需要释放连接重新建立连接
-
同步SYN(synchronization)在建立连接时来同步序号
-
窗口 :接收方的接收窗口,因为接收方的数据缓存空间是有限的。窗口字段动态变化
-
检验和:2字节
-
紧急指针:2字节。它只在URG=1的时候才有意义。
-
选项:长度可变,最大40字节。
发送窗口原则:
接收方:按序收到的数据中的最高序号+1给出确认
发送方:确认好了,发送窗口才能移动
超时重传(公式复杂、略过)
公式:RTO=RTTs + 4 X RTTd
当第一次获取RTTs的值时,就RTTs = RTT样本值
新的RTTs=(1-a) X (旧的RTTs)+ a X (新的RTT样本)
RTTd是RTT 的偏差的加权平均值,当第一次获取RTTd的值时,RTTd = RTT样本值/2
新的RTTd=(1-B) × (旧的RTTd) + B x |RTTs-新的RTT样本| (B推荐0.25)
问题:
-
如果是确认重传报文,被源主机当作是确认首次发送的消息,那就会RTT样本值增大,重传时间RTO偏大,这样的情况发送多次,就使得RTO越来越长
-
如果是确认首次发送的报文,但被源主机当作是确认重传报文,那就会使得RTT样本值偏小,重传时间RTO偏小,这样就会导致报文段过多的重传,使得RTO越来越短。
报文段每重传一次,新的重传时间为旧的重传时间的2倍。当不再发生报文段的重传时,才根据上面给出的公式计算超时重传时间
选择确认SACK
B收到的数据字节流的序号是断断续续的话,怎么办?
全部都发有些浪费,TCP首部的可选字段中,现在多出来了一个选择确认块,当然:其实目前大多数的实现还是重传所有未被确认的数据块。
流量控制(流量窗口)
让发送方的发送速率不要太快,要让接受方来得及接收
问题:目前A已经把窗口内的字节都发送完了,不能再发送了,除非等到B的确认号,这样A的窗口才能继续向后移动,但可恶的是B的确认信号却在半路上丢失了,那现在A在等B发确认,B以为A收到了,在等A发数据。形成了死锁。
解决:TCP为每一个连接都设有一个持续计时器,时间一到,发送一个探测报文段〔仅携带1字节的数据),接收方给出窗口值。如果窗口仍然是零,重新设置持续计时器。如果不为零,那么死锁的僵局就可以打破了。
如果窗口为一个字节,是否有必要重新发送?
解决:接收方等待,使得:
-
使得接收缓存已有足够空间容纳一个最长的报文段
-
或者等到接收缓存已有一半空闲的空间。
满足条件,接收方就发出确认报文,并向发送方通知当前的窗口大小
拥塞控制(拥塞窗口)
-
cnwd=1,开始慢开始算法(指数变大)
-
到达慢开始门限,进行拥塞避免算法(线性变大)
-
发生拥塞(不论是慢开始还是拥塞避免阶段),ssthresh=cwnd/2,重新开始慢开始&拥塞避免算法
问题:每次都要重新执行慢开始、影响性能
解决方案:
-
快重传算法(及时通知发送方有报文丢失)
-
快恢复算法(配合快重传算法)
- 收到重复确认之后,ssthresh=cnwd/2
- 不再开始慢开始,直接执行拥塞避免,cnwd=ssthresh(因为有三个重复确认,认为网络还未拥塞)
路由器、网关、交换机
-
交换机:数据链路层,转发数据
-
路由器:IP层、转发数据、路由表
-
网关:连接不同网络设备(可为不同协议)、路由器为IP网关
应用层
DNS
问题:浏览器输入网址后、发生了什么
-
查询DNS对应的IP
查询过程:
-
先查询本地是否有缓存(host文件),若没有则去本地DNS查询(电信、移动、联通)
-
本地DNS查询缓存,没有则请求根服务器
-
根服务器返回顶级服务器,则查询顶级服务器,如此循环
-
对IP发送http/https请求,获取页面内容
过程:
-
传输层:加入源端口、目的端口(对应进程)
-
ip层:加入ip源地址、目的地址,进行分组和路由
-
链路层:加入MAC地址、发送请求
-
浏览器解析页面内容
HTTPS
问题:加密过程
https://juejin.cn/post/6976905072584491021
-
客户端请求TLS链接(tcp)
-
客户端发送支持TLS版本号、对称加密算法、非对称加密算法、哈希算法(参与加密过程);客户端随机数
-
服务器选择TLS版本号、对称加密算法、非对称加密算法、哈希算法;服务器随机数
-
-
服务器发送证书、客户端确认证书
-
权威机构颁发、证书的生成过程:证书内容经过hash&CA机构私钥加密得到加密密文
-
客户端确认证书:
-
证书内容包含服务器公钥,
-
证书机构一般分为根证书机构、中间证书机构;根证书机构内嵌在操作系统中,保证可信
-
-
验证通过、协商对称加密秘钥
-
客户端发送pre master secret(是个随机数,公钥加密)、另外两个随机数 -》 master secret -》计算秘钥(4个)
-
加密密钥是用来加密,MAC Secret是用来验证身份的、其中服务器客户端用不同的加密主要是为了防止:别人截到他是看不懂,没关系我看不懂我给你捣乱,我不发给服务器,我原封不动地给你发回去,让你以为这是服务器给你响应的消息
-
-
使用对称秘钥开始通讯(只有这一步才是http,之前都是tcp)
HTTP
状态码:
状态码 | 类别 |
---|---|
1XX | 信息性状态码 |
2XX | 成功状态码 |
3XX | 重定向状态码 |
4XX | 客户端错误状态码 |
5XX | 服务端错误状态码 |
1XX
-
100 Continue:表示正常,客户端可以继续发送请求
-
101 Switching Protocols:切换协议,服务器根据客户端的请求切换协议。
2XX
-
200 OK:请求成功
-
201 Created:已创建,表示成功请求并创建了新的资源
-
202 Accepted:已接受,已接受请求,但未处理完成。
-
204 No Content:无内容,服务器成功处理,但未返回内容。
-
205 Reset Content:重置内容,服务器处理成功,客户端应重置文档视图
-
206 Partial Content:表示客户端进行了范围请求,响应报文应包含Content-Range指定范围的实体内容
3XX
-
301 Moved Permanently:永久性重定向
-
302 Found:临时重定向
-
305 Use Proxy:所请求的资源必须通过代理访问
-
307 Temporary Redirect: 临时重定向,与302类似,要求使用get请求重定向。
4XX
-
400 Bad Request:客户端请求的语法错误,服务器无法理解。
-
401 Unauthorized:表示发送的请求需要有认证信息。
-
403 Forbidden:服务器理解用户的请求,但是拒绝执行该请求
-
404 Not Found:服务器无法根据客户端的请求找到资源。
-
405 Method Not Allowed:客户端请求中的方法被禁止
-
408 Request Time-out:服务器等待客户端发送的请求时间过长,超时
5XX
-
500 Internal Server Error:服务器内部错误,无法完成请求
-
501 Not Implemented:服务器不支持请求的功能,无法完成请求
1.1 新特性:长连接、HOST域(解决同一个ip多个虚拟机问题)、支持请求资源一部分(状态码206)
2.0新特性:二进制格式、多路复用、header压缩(存储一份header fields表)、服务端推送(客户端在请求一个资源时,会把相关资源一起发给客户端)
Session、Token、Cookie区别
http是无状态的
-
Cookie:存储在客户端浏览器,服务器返回的,包含用户信息(session_id)
-
Session:存储在服务器,存储用户信息
-
Token:Session的升级方案、服务器无需存储用户信息,使用签名进行验证(cpu换存储)