Go微服务网关(一)网络编程基础

Posted by YaPi on January 4, 2021

网络协议

avatar

经典协议与数据包

avatar

以太网首部,包含主机mac地址等信息

TCP的三次握手和四次挥手

avatar 为什么需要3次握手? 主要目的是保证连接是双工和可靠的,可靠更多是通过重传机制来保证的。

双工是指发送和接受是可以同时执行的。

avatar 为什么需要四次挥手? 因为连接是全双工的,双方必须都收到对方的FIN包及确认才可关闭。

avatar

为什么最大等待时间是2MSL?

MSL : Maximum Segment Lifetime, 30s~1分钟。最大的段的生命周期。

  • 保证TCP协议的全双工连接能够可靠关闭。

若主动关闭放发送最后一个ack包不等到2MSL的话:若这个ack包丢失了,主动发送放可以通过失败重传机制,再次 发送FIN包给主动关闭方,若没有2MSL,可能就收不到这个包,同时主动关闭方关闭了通道,那么被动关闭方就会一直 处于LAST-ACK状态,资源得不到释放。

  • 保证这次连接的重复数据段从网络中消失

若不等待的话,当关闭了这次会话过后,又建立了连接,恰好是同样的服务器,同样的端口。若不等待2MSL,在前一次最后一次 的请求接受失败,就会重传,那么新建立的连接就会收到不正确的消息。

为啥会出现大量的close_wait?

  • 首先,close_wait一般出现在被动关闭方
  • 并发请求太多导致
  • 被动关闭方未及时释放端口资源导致

TCP为啥需要流量控制?UDP不需要? UDP是不可靠的连接,发送了就不管了,不需要控制

TCP需要流量控制的原因:

  • 由于通讯双方,网速不同。通讯方任一发送过快都会导致对方消息处理不过来,所以就需要把数据 放到缓冲区中
  • 如果缓冲区满了,发送方还在疯狂发送,那接收方只能把数据包丢弃。因此我们需要控制发送速率
  • 缓冲区剩余大小称之为接受窗口,用变量win表示,如果win=0,则发送方停止发送。

avatar

TCP为啥需要用塞控制?

拥塞控制和流量控制是两个概念,拥塞控制是调整网络负载 产生的原因: 接收方网络资源繁忙,因未及时响应ACK导致发送方重传大量数据,这样将会导致网络 更加拥堵。 解决:拥塞控制动态调整win大小,不只是依赖缓冲区确定窗口大小,主要分为两个部分

  • 慢开始

    刚刚建立的时候一点点的提速,试探网络的速度。

  • 拥塞避免

avatar

初始的时候慢启动开始,每次传输过后,逐渐递增至特定阀值。然后采用拥塞避免方式加法增加传输。当发生网络拥塞的时候, 直接传输从最小开始,然后,再次指数增长,特定阀值变化为上次发生拥塞的值的一般,到达此值的时候再次加法增加,重复此动作。

这样有个缺点,从最高值直接降低为1会对传输有很大的影响,所以,有了下一种优化算法

avatar

不同点再发生网络拥塞的时候,不会直接变为1,而是从一半开始,加法增加

什么是粘包/拆包?为什么会发生?

产生粘包和拆包问题的主要原因是,操作系统在发送TCP数据的时候,底层会有一个缓冲区,例如1024个字节大小,如果一次请求发送的数据量比较小, 没达到缓冲区大小,TCP则会将多个请求合并为同一个请求进行发送,这就形成了粘包问题;如果一次请求发送的数据量比较大,超过了缓冲区大小, TCP就会将其拆分为多次发送,这就是拆包,也就是将一个大的包拆分为多个小包进行发送。 TCP 是一个面向字节流的协议,它是性质是流式的,所以它并没有分段。就像水流一样,你没法知道什么时候开始,什么时候结束。 粘包问题是因为接收方不知道消息之间的界限,不知道一次性提取多少字节的数据所造成的。

  • 应用程序写入的数据大于套接字缓冲区大小,这将会发生拆包
  • 应用程序写入的数据小于套接字缓冲区大小,网卡将应用多次写入的数据发送到网络上,这将发生粘包
  • 进行MSS(最大报文长度)大小的TCP分段,当TCP报文长度-TCP头部长度>MSS的时候将发生拆包
  • 接受方法不及时读取套接字缓冲区数据,这将发生粘包

如何获取完整的数据报文?

  • 使用带消息头的协议,头部写入包长度,然后再读取包内容
  • 设置定长消息,每次读取定长内容,长度不够时空位补固定字符
  • 设置消息边界,服务端从网络流中按消息边界分离出消息内容,一般使用 “ \n “
  • 使用更为复杂的协议,如:json、protobuf等