1 以太网能不丢包吗
大家天天上网语音、视频、聊天、追剧……,有没有感觉到网络丢包呢?可能有的会说有,有的会说没有。说有的可能会说感觉到语音或追剧时有卡顿,说没有的可能会说我聊天内容好友都毫发无损的收到了。其实大家都没错,有的应用基于TCP来传输,TCP自己有一套丢包重传机制来保证应用交给它的数据没有磕碰的传给对端;还有一部分应用基于UDP来传输,UDP本身不承诺应用交给它的数据能否完整的到达对端,一切就看应用交给它的这些数据的"造化"了,如果网络发生拥塞或一些物理故障,亦或是其他可能的原因,导致丢包了,那么应用交给udp的数据就丢了,这种情况下用户就会感觉到自己的业务不正常了(语音卡了,视频花了……)。这时候会有同学举手说,别忽悠,我用过一些应用是基于UDP来传输的,网络不好的时候我也没感觉到丢包。首先为这些细心的同学点个赞,确实,有些基于UDP传输的应用用户也感觉不到丢包,因为有些应用自己会在UDP协议之上采用一套自己的丢包重传机制,来保障业务承载在UDP上面也不会被"丢弃"(UDP丢了应用重传,对用户来说感觉不到丢包)。

那么,有没有办法让以太网(这里的以太网指TCP/IP模型中的网络层,刚才说的TCP、UDP在这个模型中的传输层)本身就不丢包呢(物理损坏除外啊,那说明该换设备了~),答案是有的。下面我们就来揭开它不丢包的神秘面纱。
2 如何做到以太网不丢包
以太网不丢包的技术可能有很多,今天给大家介绍几种标准化了的技术,毕竟标准即代表主流嘛,学技术得学主流的,要不这个技术咱还没整明白可能就成为古董了。
2.1 PFC技术
PFC(Priority-based Flow Control,基于优先级的流量控制)能逐跳提供基于优先级
的流量控制,可以实现在以太网链路上运行多种类型的流量而互不影响。设备在进行报文转
发时,根据报文的优先级进入对应映射关系的队列中进行调度转发。当某一优先级报文发送速率超过接收速率,导致接收方可用数据缓冲空间不足时,设备通过PFC PAUSE 帧反馈给上一跳设备,上一跳设备收到PAUSE 帧报文后停止发送本优先级报文,直到再收到PFC XON 帧或经过一定的老化时间后才能恢复流量发送。通过使用PFC 功能,使得某种类型的流量拥塞不会影响其他类型流量的正常转发,从而达到同一链路上不同类型的报文互不影响。
大白话就是某个端口感觉自己快发不动了就向他的上游大吼"发慢点或别发了,再发给你扔掉,不信发一个试试"然后它的上游就的这样做很酷,感觉发不动时也来这么一嗓子,就这样,从下游到上游,一个吼一个,最终的数据源只好默默的降低或暂停数据包的发送,毕竟都怒吼了,再发万一挨揍怎么办。下面这个图,可以说一目了然。如果大家有想不通的地方,欢迎后台或留言。

2.2 ECN技术
ECN 定义了一种基于IP 层及传输层的流量控制及端到端拥塞通知机制。ECN 功能利用IP 报文头中的DS 域来标记报文传输路径上的拥塞状态。支持该功能的终端设备可以通过报文内容判断出传输路径上发生了拥塞,从而调整报文的发送方式,避免拥塞加剧。
ECN 功能对IP 报文头中DS 域的最后两个比特位(称为ECN 域)进行了如下定义:
• 比特位 6 用于标识发送端设备是否支持ECN 功能,称为ECT 位(ECN-Capable Transport)
• 比特位 7 用于标识报文在传输路径上是否经历过拥塞,称为CE位(Congestion Experienced)

ECN在IP报文头中的位置如上图红色虚线框所示。
ECN域各比特的含义如下图所示。

在设备上开启ECN 功能后,拥塞管理功能将按如下方式对报文进行处理:
• 如果队列长度小于下限,不丢弃报文,也不对 ECN 域进行识别和标记。
• 如果队列长度在上限和下限之间,当设备根据丢弃概率计算出需要丢弃某个报文时,将检查该报文的ECN域。如果ECN域显示该报文由支持ECN的终端发出,设备会将报文的ECT位和CE位都标记为1,然后转发该报文;如果ECN域显示报文传输路径中已经经历过拥塞(即ECT和CE位都为1),则设备直接转发该报文,不对ECN域进行重新标记;如果ECT位和CE位都为0,设备会将该报文丢弃。
• 如果队列长度超过上限,将队列中所有报文的ECN 域都标记为11,当队列长度达到队列尾丢弃门限后,报文将被丢弃。

ECN 功能工作机制:
(1) 发送端设置 ECN 域为10,告知路径上的设备及接收端,发送端设备支持ECN 功能。
(2) 中间设备发生拥塞并达到门限,拥塞设备将发生拥塞的报文ECN 域设置为11,报文正常转发。
(3) 接收端收到 ECN 置位为11 的报文,由传输层发送CNP(Congestion Notification Packet,拥塞通知报文)通知发送端。
(4) 发送端收到 CNP 报文,对对应的优先级的队列进行降速处理。
(5) 经过一段可配置的时间或者发送一定数量数据,发送端恢复原来的速率。
温故而知新,我们来用一个表格对比一下PFC和ECN:

2.3 DCBX技术(限于篇幅先不展开了)
它是基于LLDP(Link Layer Discovery Protocol)的扩展协议,用于在设备间自动协商并配置PFC、ETS及CN等。
2.4 ETS技术(限于篇幅先不展开了)
用于避免一种流量类型的大规模流量猝发影响其它流量类型,为不同的流量类型提供最小带宽保证。一种流量类型只有在其它流量类型带宽不占用的情况下,才能使用分配带宽之外的额外带宽。这使多种流量类型可在同一网络中和谐共存。
3 以太网不丢包的好处
如果以太网本身能做到不丢包,那好多原来想都不敢想的事情就可以动手干了,这种例子很多,比如:
1) 数据中心存储网和业务网融合
在数据中心网络当中,典型的存在着以下两种流量:
· 存储数据流:要求无丢包;
· 普通数据流:允许一定的丢包和时延。
很显然两种数据流对服务的要求是不同的,因而传统的数据中心也往往会部署两个网络来满足对数据中心的这些需求。这种网络在一定意义上来说是冗余的,会造成资源的浪费,当数据中心规模扩大时,这种方案就变的不可接受了。因此急需一种可以将两种网络统一起来的网络技术。
当将这两个网络进行融合时,需要对两个网络进行考察:
普通数据流:它没什么特殊要求
存储数据流:存储网一般采用FC协议,存储也是传统数据中心最主要的业务,因而对两个网络进行融合,最重要的就是要保护客户在存储上的投资。为此一些IT厂商提交了一个协议规范FCoE,FCoE(Fibre Channel over Ethernet)技术标准可以将光纤通道映射到以太网,从而可以在以太网上传输SAN数据。它能够在保护客户在现有FC-SAN上的投资(如FC-SAN的各种工具、员工的培训、已建设的FC-SAN设施及相应的管理架构)的基础上,提供一种以FC存储协议为核心的I/O整合方案。由于FC不允许丢包,因而在采用FCoE时,必须对以太网进行增强以使得以太网不丢包。
2) 利用以太网实现RDMA
DMA大家都知道,在不麻烦CPU的情况下快速进行数据搬移的一种技术(一般单芯片内不同外设或外设与内存间搬移),在DMA前面加个R,也就是Remote,它就可以跨机器远程快速搬移应用程序的数据了。当然,RDMA也不需要CPU和操作系统的参与,"脏活累活"自己干,给CPU大哥留出更多的算力做更有意义的事情。RDMA最开始是基于Infiniband来实现的,网卡和交换机都需要用支持Infiniband的,因为Infiniband可以做到不丢包,基于以太网或UDP实现RDMA其实也有相应的标准,分别是RoCEv1和RoCEv2,

当然他们对以太网都有一个共同的要求,那就是不丢包。限于篇幅就先不展开了,我们抽时间再聊。
3) 给TCP/IP协议栈减肥
TCP/IP协议栈中的TCP协议,为了做到对交给它的数据不丢包这个承诺做了很大的努力,什么滑动窗口啊、三四次握手呀、慢启动啦、拥塞控制之类的很多机制,复杂的机制就决定了TCP/IP协议栈发福的体态,这无形中就提高了实现TCP/IP协议栈的门槛,让一些小微型嵌入式设备望而怯步,然而物联网要联网呀,没有TCP/IP协议栈怎么联网,所幸已经有一些类似uIP之类的袖珍型开源TCP/IP协议栈解决方案了,不过哪个嵌入式物联网设备不希望拥有一个功能完备健壮的TCP/IP协议栈呢, 所以TCP/IP协议栈要能减肥,载它的嵌入式小设备们还是会乐开怀的。