iOS11开发新特性之网络部分
前言
网络优化技术进阶 为了给用户提供更好的用户体验,在网络优化和新技术使用方面,苹果一直都保持著很积极的态度,近两年也多次通过加强审核的方式大力推广 IPv6 和 https;每年的 WWDC 都有若干网络优化的 session,介绍和讨论新的网络技术和使用情况;
今年的 Advances in Networking 进一步分享了 ECN/IPV6/MPTCP 等几项技术带来的收益,以及苹果网络相关 API 的一些新特性;
主要内容:
- ECN 显式拥塞通知
- IPv6支持
- Networking stack changes 传输层 TCP/IPv6从内核剥离
- New NetworkExtension facilities 网络扩展:NEHotspotConfiguration、NEDNSProxyProvider
- Multipath protocols for Multipath Devices 多路径协议
- URLSession enhancements URLSession 增强
- waitsForConnectivity
- earliestBeginDate
- ProgressReporting
- Brotli compression
- Public Suffix List
- URLSessionStreamTask
- Best Practice 最佳实践
- 正在进行的开发-TLS 1.3 QUIC Bonjour
《[Diving into WWDC 2017] Advances in Networking, Part 1》
ECN
首先所有的网络协议都是为了最大化的使用网络资源,一直到网络出现拥塞; 出现拥塞时会导致丢包,而 TCP 默认的处理是对丢包进行重传;这种方法代价非常大,发送方持续重试可能导致耗电,设备的网络资源也会被无端占用,而网络也可能更加拥塞,需要很长时间才能恢复; 有效的优化拥塞和避免拥塞将减少重传,减少延迟,并极大提升用户体验;
重发为何会带来非常大的性能损耗:原因是因为 TCP 的慢启动与初始拥塞窗口(initial congestion window, initcwnd)。
好的传输协议必须最大限度地利用带宽,而 TCP 有启动速度限制,也就是初始拥塞窗口(initial congestion window, initcwnd),随着时间与稳定性的增加,才能最大限度地使用带宽。一旦发生拥塞重连,将带来非常大的性能损耗。重连时将采用初始拥塞窗口,这个值是连接中最慢的,窗口的限制也会拖慢整个传输过程:在拥塞窗口设置的较小时,对于 TLS 连接,TLS 握手消息消耗了宝贵的初始连接字节(当拥塞窗口较小时),如果拥塞窗口足够大,那么慢启动不会有额外的延迟。但是如果较长的握手消息超过了拥塞窗口的大小,发送方将必须把它拆分成两块,先发送一块儿,等待确认(一个往返),增加拥塞窗口,然后再发送剩下的部分。这也加剧了
扩展说明:
TCP 内置的拥塞控制(congestion control)机制,在一个新的连接开始时,你不知道对端有多快。如果有足够的带宽,你可以用最快的速度传送数据,但如果你正在处理一个缓慢的移动网络连接呢?如果发送的数据太多,你会压垮连接,导致连接中断。出于这个原因,每一个 TCP 连接都有一个拥塞窗口(congestion window)的速度极限。这个窗口的初始值非常小,在可靠性能保证的情况下随时间增长,这种机制被称为慢启动(slow start)。
这带来了反直觉的现象:所有的 TCP 连接,启动速度很慢,随着时间的推移速度增加,直到它们充分发挥其潜力。这对于 HTTP 连接而言,往往是坏消息;它们几乎总是在不理想的条件下工作。重发同理。
综上拥塞是 TCP 的性能瓶颈,TCP 设计之初检测拥塞的方式,只能在发生了丢包时才会发现发生了拥塞。仅从丢包来识别拥塞,代价过高。
优化的思路有两种:
前者有 quick 之类的协议替换 TCP 协议,Apple 也在积极开发中,iOS11暂时未支持。后者则是基于 TCP 做一些扩展、完善,ECN 就是一种,ECN 已经在 iOS 中全面支持。
什么是 ECN ?
全称:Advantages of Explicit Congestion Notification(显式拥塞通知),当网络拥塞发生时,因为发送方无法及时知晓网络情况,在发现丢包时会不断的重发,导致网络情况更加糟糕,而 ECN 的出现就解决了这个问题,ECN 是 TCP IP 协议的扩展,其实现是在 ip header 中加入 1 bit 的拥塞状态值,由接收方回传给发送方;发送方收到这个消息时既停止发送数据包,直到拥塞解除;
ECN 需要客户端、服务端和网络三方面的支持,但是得益于 ECN 隶属 Linux 内核,所以只需要运营商升级 Linux 即可支持,APPLE 给出了 Server 对 ECN 支持率:
数据:
时间 |
2013 |
2017 |
Server 对 ECN 支持率 |
35% |
74% |
客户端方面,iOS 10.3 开始,50% 的通过 Wifi 和少量通过移动网络进行的 TCP 连结已经打开了 ECN,没有收到相关问题的报告; 通过也收集到了一些国家出现网络拥塞的情况:
地区 |
网络拥塞情况 |
美国 |
0.2% |
** |
1% |
法国 |
5%、 |
阿根廷 |
30% |
综上,客户端从 iOS 11 开始,所有 TCP 请求都会支持 ECN(全部Wifi 和部分白名单移动运营商);服务端有 74% 的网站支持了 ECN,也会有越来越多的网络服务商开始支持 ECN 来进一步提升用户体验;(服务商只需要在你的网络接入点支持 ECN 即可);
显式标记连接拥塞,更加高效。
在使用 ECN 的同时,需要结合使用 SQM (Smart Queue Management) 算法 来进行数据缓存,他会保证是真正的拥塞出现前告知发送者当前的网络这块,最大程度上的避免拥塞出现;
ECN 的实现细节
ECN 是 TCP IP 协议的扩展,其实现是在 ip header 中加入 1 bit 的拥塞状态值,由接收方回传给发送方;发送方收到这个消息时既停止发送数据包,直到拥塞解除;
ECN flag 的位置,在 IPv4 中对应于 ToS ,IPv6对应于 Traffic Class。
更详细的位置:
参考链接:
15 年的 session 中 有一个实验对比图:没有 ECN 时 在传输初段出现了明显的网络拥塞,而且持续了很久才恢复正常;而在使用了 ECN + CoDel 算法优化后,没有出现明显的数据终端和因拥塞导致的丢包和重传;
Reference:
your app and next generation networks wwdc/2015/719
IPv6
IPv6 相比 IPv4, IPv6 有更大的地址空间,更小的路由表,更高安全性等优势。
World IPv6 Launch 始于 2016 年 6 月 6 日,包括**在内的若干国家开始启用 IPv6(事实上**进展缓慢)。支持 IPv6 的设备从 5 年前的不到 1% 提升到今天的接近 20%。欧美大多数的移动运营商也已同时支持 IPv6 和 IPv4。经过策略改进,HTTPS 请求在 IPv6 下提升了 15%-30%。
15 年的 session 里已经提到了 NAT64,如果服务端只支持 IPv4, 在 IPv6 环境下,可以通过 NAT64 DNS64 技术去正常访问。
16 年 6 月起,苹果也开始要求所有 App 提交时必须经过 NAT64 测试,支持 IPv6 网络;现在因为 IPv6 被拒的 App 已经很少了。
Networking stack changes 网络协议分层
Networking stack changes 传统的网络分层模型中,接口层和传输层 TCP/IP 都在内核态;剩下的协议处理在用户态;数据在这两者间传输时需要做一些上下文切换。
意义在于,
理想状态下:如果APP开发者想更新调整通信协议内容,比如参数、配置等内容,不用用户再升级系统,而是直接升级 APP 即可实现。比如提升入口初始带宽,目前在 iOS 中能够体现的部分是对于NSURLSession 可以调整 MutliPath TCP 的相应策略。
数据在这两者间传输时避免了一些上下文切换,效率更高。
可以预见,将来在 NSURLSession 中将开放更多的用于调整 TCP 传输的接口,让我们继续期待后续更新吧。
MutliPath TCP
Multipath protocols for Multipath Devices(适合多链路设备的多链路 TC P协议)
增加了对使用多个接口(如Wi-Fi和Cellular)的支持,通过扩展 URLSessionConfiguration
以支持 IETF、RFC 6824中定义的多路径TCP传输单个数据流。有关更多信息,请参阅URLSessionConfiguration.MultipathServiceType。
阶段 |
iOS10.3 |
iOS 11 |
客户端 |
50% |
100% |
不要使用 BSD 的 Socket,不要嵌入其他网络类库,优先使用 APPLE 的网络类库,底层网络通信在 CPU、内存、电量使用已经做了很多优化,在数据传输效率、动态链接通道切换都有优化,使用其他网络库,无法享受优化成果。
向网络扩展框架添加了新的 DNS 代理应用程序扩展类型。
Receives the system’s DNS query messages Handles them as it wishes
Can send to recursive resolver of its choice Can send using protocol of its choice
支持:
- DNS over TLS
- DNS over HTTP
仅仅适用于 VPN 类 APP
DNS Proxy provider: also for non-managed devices?
Reference:
WKWebView Cookie 管理
基本在这里面展示了他的特性
参考:《iOS 防 DNS 污染方案调研(四)--- Cookie 业务场景》
URLSession Adaptable Connectivity API
重大更新!现在可以通过 urlSession(_:taskIsWaitingForConnectivity:)
让请求等待网络正常后再自动尝试。
URLSessionTask Scheduling API
通过 URLSessionTask Scheduling API 可以在 App 没有运行的时候下载内容,而手机也会结合实际电量,使用状态去决定是否执行。