大多数浏览器和
Developer App 均支持流媒体播放。
-
您的 App 和新一代网络
IPv6 正在呈指数增长,世界各地的运营商都在向纯 IPv6 APN 迁移。了解用于测试 app 兼容性的新工具,并获得关于确保 app 在所有网络环境中正常运行的专家建议。iOS 9 和 OS X 10.11 现在支持最新的 TCP 标准。从专家那里了解 TCP 快速打开和显式拥塞通知,并了解它对您 app 的益处。
资源
相关视频
WWDC21
-
下载
App与新一代网络
谢谢 上午好
欢迎参加“App与新一代网络”讲座 我是普拉巴卡尔·拉卡拉 另外还有我的同事斯图尔特·柴歇尔
今天的讲座分为两个部分
第一个主题关于IPv6 在第二个主题中斯图尔特将会介绍 如何让你的APP更快地运行
我们首先讨论IPv6
IPv6有哪些新特性呢?
在大约17年以前 IPv6 RFC就已经发表
你可能会想今天我们 为什么要讨论IPv6?
我们看到IPv6越来越多地 被部署到企业和蜂窝网络之中
你需要确保你的APP 能够在这些网络中运行
因此你的APP应该强制兼容IPv6
现在我们将讨论这个主题 以及它对于开发者的意义 但是在此之前 请让我们先回顾一下历史
在前些年客户端设备具有真实 唯一的IPv4 那是以前的事情了 你需要进行端对端网络连接
但是我们很快发现 IPv4地址就快要用完了 因此我们在中间加入NAT
这个方法是可行的 但是大规模的NAT设备 不仅昂贵而且脆弱
因此现在运营商 在他们的网络中部署IPv6
利用IPv6以继续提供 端对端网络连接, 不需要在数据路径中进行转换
现在 让我们来看美国三个主要 蜂窝运营商的IPv6部署情况
我们可以看到两个特点 首先所有趋势线都是上升的
其次一半以上的用户 现在通过IPv6连接到 蜂窝数据网络
看起来不错是吧 但是对于网络运营商来说 实际情况比以前更加糟糕 原因是他们的网络现在必须同时 支持IPv4和IPv6
他们真正需要的是消除通过IPv4 访问他们的网络
如果这样做将会导致 完全依靠IPv4 连接网络的设备和用户流失 但 他们仍然是主流
现在运营商在他们的网络中 部署NS64和NAT64 其实现方式是当客户端设备上的APP 进行主机名称查询 以获得IPv4-only服务器的 IPv6地址时 DNS64和网络 将合成一个IPv6地址 并提供给客户端设备
现在客户端设备可以 使用这个IPv6地址 发送流量至网络
网络的配置方式 使搜索数据包被发送给NAT64引擎 NAT64引擎 将IPv6流量转换成为IPv4流量 在客户端设备返回流量时 NAT64引擎将进行相反的转换
在这里 必须注意的是 对于客户端设备上运行的APP来说
你的IPv4-only服务器 看去就你是IPv6-only服务器 这个特性很重要
因为你们一些人可能会认为 我的服务器仅配置用于IPv4 因此我不需要针对通过IPv6进行 访问的客户端来测试我的APP
你的假设并不成立
我们很快就会转换到 到这种类型的网络 到那时
我们希望为用户提供无缝的用户体验 因此你的APP必须支持IPv6
APP必须符合这项要求
这是一项新的APP要求 你可能会想我应该如何针对此网络 来测试我的APP呢? 我可以在哪里找到这种 NAT64类型的网络?
我有一个好消息告诉你们
你可以使用基于 IPv4连接的Mac设备 创建你自己的NAT64网络 并可以开始测试你的APP
这项新功能供开发人员使用 它隐藏起来了 让我们来看清楚一点你只需要 点击“Sharing”选项 然后点击 “Internet Sharing” 选项其他保持不变 这里有一个新复选框显示 “create NAT64 network”
选中之后 可以选择 Internet共享接口 然后使用这个NAT64网络
开始测试你的APP
在这里举例来说我有一个 IPv4 Internet连接 我想要使用NAT64/DNS64 将这个连接作为 IPv6-only访问网络 在我的Wi-Fi 接口上进行共享 当我开始这样做时我看到 Wi-Fi图标变灰 并且变成箭头
这表明Wi-Fi接口 转为接入点模式 其意义在于它成为一个Wi-Fi热点 你可以连接其他客户端设备 并开始测试你的APP
典型的测试平台是这样的
在WAN侧 IPv4 Internet连接已经完成 我的iMac已经在运行 DNS64/NAT64引擎 成为使用Wi-Fi接口的 IPv6网络热点
你想要测试的APP 已经安装在一台客户端机器上 你也可以在其他Mac设备上 运行的模拟器上测试你的APP 这个Mac必须是 此Internet共享环境的客户端
现在 你已经可以 在这种类型的网络进行测试 你真正想做的事情是 确保这种网络成为开发流程的组成部分
也就是说在任何时候 当你编写新的APP 或者编写APP更新版本时 你需要在提交APP之前 确保在NAT64网络环境下 测试你的APP
现在对你们70%的人来说 这是一个好消息 你的APP运行正常 这很不错吧 你可以放心地测试 各个版本的APP 确保不会有功能受到影响
但是有将近三分之一的人 将会看到 在NAT64MQXT网络环境下 你的APP要么受到严重的限制 或者根本无法运行
幸运的是大多数问题都容易修复 这里是一个例子
现在如果你只使用 IPv4-only数据结构 或IPv4-only API 或者你使用同时支持 IPv4和IPv6的API 但是你传递一个参数 声明你只想获得IPv4结果
这会导致你的APP仅支持IPv4 这意味着 你的APP将无法在 IPv6-only网络环境下运行
对于这些无法运行的APP 我们看到另外一件有意思的事情
有时候在尝试连接之前 APP会预先选择IPv4连接
因此有时候你会看到这样的错误信息
在这种情况下我的iPhone 确实连接到我的Mac设备上 创建的NAT64网络 我可以使用Safari 浏览互联网内容 我可以观看视频 听音乐... 我的Internet连接正常 但是出于一些原因APP认为我没有 Internet连接 你会看到提示信息 说你的设备处于飞行模式 但是顶部信息栏却不是这样显示的
那么这是为什么呢? 这是因为APP预先 设置成为IPv4连接 但是在IPv6-only访问网络中 例如NAT64网络 并没有IPv4连接 整个网络对你来说 完全是一个IPv6-only网络 即使IPv4-only服务器 看上去像是IPv6-only服务器 因此如果选择这样的设置 将会发生失败 在这种情况下APP将会提示你重试 我进行重试但是仍然会 显示相同的错误信息 然后我再重试仍然显示相同的错误信息 这个信息不会消失因此 无法使用APP进行其他操作 对此有什么好方法吗?
应该尝试连接
如果能够连接成功当然是好了 如果不能应该巧妙地进行处理
第二个建议是 使用更高级别的网络框架 例如NSURLSession 或CFNetwork API 原因是像iPhone 和Mac等多址设备的 网络连接有一点复杂
比如iPhone 不仅有Wi-Fi接口 还有蜂窝网络接口 多于Mac设备可能有多个以太网接口 而且也有Wi-Fi接口 在特定的时间 所有这些接口可能有不同类型的连接
你需要考虑使用哪个接口 如何进行这种类型的连接 以连接到特定的目标 自已编写代码可能会费时费力 因此应该使用更高层次的网络框架 这会让你的APP代码更加简洁明了
如果出于某些原因 你不能使用更高层次的网络框架 而且你必须使用socket 我们建议你阅读RFC 4038 此RFC详细地介绍了如何在地址族 不可知的情况下编写APP
我们的最后建议是尽可能使用主机名 而不是直接使用IP地址 无论IPv4或IPv6 当你编写自己的专用协议 或者编写APP时 应确保不要直接使用IP地址 而应该优先使用主机名 其原因是 在NAT64/DNS64网络环境中
客户端设备首先会发出DNS查询请求 以获得IPv4服务器的IPv6地址 因此你必须使用主机名 如果你需要使用IPv4地址 客户端设备将不会进行DNS查询 DNS64网络将不会 为你合成IPv6地址
我们知道有时候可能 无法避免使用IPv4 例如使用Safari进行浏览时 你打开一个网页显示正常 但是在网页内可能有其他一些链接
这些链接可能具有嵌入的IPv4地址
在此之前在Safari浏览器中 如果你点击这样的链接 将不会打开网页
从iOS 9 和OS X 10.11开始 不仅Safari而且任何 NSURLSession或 CFNetwork API用户 将能够在NAT64/DNS64 网络中使用IPv4地址
其工作原理是当你使用主机名时 网络中的DNS64将会 为你合成IPv6 地址
但是当你直接使用IPv4地址 并且使用一个更高层次网络API时 操作系统将会发现网络行为 并确定它将如何为你 合成IPv6 地址 并在本地完成此工作 这也是你为什么应该使用更高层次 网络框架的另一个原因 因此应该这样做
希望你能够利用这些数据点 和新工具找到并解决APP中的问题
我们希望你做的事情是 在本讲座结束之后 在你们的Mac设备上 安装seed build 开始创建自己的NAT64网络 然后使用它们测试你的APP
请记住这是APP应该遵守的一项要求 请将这个信息传达给 未参加本讲座的其他开发人员 并且把这个消息带回你的公司确保使用 NAT64网络测试你的APP
现在请斯图尔特·柴歇尔上台 为大家介绍其他的网络功能 你们可以使用这些功能 更快速地开发APP 并且提高APP的响应速度 有请斯图尔特
谢谢普拉巴卡尔
我们想要讨论 如何让APP加快运行速度
在过去的几十年里 我们看到网络吞吐量飞速增长 我还记得在以前 56k调制解调器就已经 属于尖端科技而现在 50Mb/s网速已经很常见 但是我们并没有感觉到网速成千倍提升 我们仍然需要花大量的时间来 等待网页打开 这是为什么呢?
这是因为我们的行业专注于 提升吞吐量
但是却忽略其他资源延迟
光速不会变得更快 对此我们无能为力但是我们可以 消除其它方面的延迟 现在我们应该致力于这些工作 这就是我今天要讨论的主题
我想要讨论四种类型的资源延迟 当用户使用APP可能会遇到这些延迟
首先是当你遇到 信号较弱的WiFi连接 而且连接不成功时 会遇到的延迟
第二个是使用“显式拥塞通知” 即“Explicit Congestion Notification”技术 和智能队列功能来减少网络延迟
TCP NOTSENT Low-WaterMark选项 减少发送机器中的延迟 最后我们将了解 一种名为TCP Fast Open的 令人激动新的技术 我们先开始讨论如何进行 可靠的网络回退操作
我相信你们每个人都有这样的经历 下班之后离开办公室 走向你的汽车拿出手机 然后想要查看地图 天气预报和邮件等 你盯着手机但是 没有载入任何内容你走向汽车 但是仍然没载入内容你感到烦躁不安 于是你进入“设置“关闭Wi-Fi 使用LTE数据连接网页瞬间打开了
然后你忘记打开Wi-FI 一周之后你收到巨额的数据流量账单 这可不是你想要的 对于用户体验来说这是糟糕的事情
现在我们要做的事情是 设置并行连接数字逻辑 这样如果你的iPhone 检测到它在使用Wi-Fi
但是却无法建立TCP连接 这时它会很快地通过蜂窝数据网络 发起第二个并行连接 但是它不会完全中止Wi-Fi连接 并不会放弃Wi-Fi连接 它会并行尝试Wi-Fi连接 如果连接成功 将会转到Wi-Fi连接 如果连接不成功 蜂窝网络连接将率先完成 这样APP的网络连接延将
将会很短用户甚至不会发现
当然此功能仅用于 允许使用蜂窝网络的APP 如果用户进入设置 禁止APP连接数据网络 我们将不会进行这种回退
如果我们进行回退将 会隐藏Wi-Fi图标 让用户知道他们没有使用Wi-Fi
如果你使用更高层次的API 这并不会占用额外的资源 而且这并不会影响 用户获得良好的使用体验
你还需要做另外一件事情 也就是当你在蜂窝网络上运行时
无论你首先连接到蜂窝网络 还是回退到蜂窝网络 用户最后还可能会 回到Wi-Fi范围之内 那时,你将会看到 “Better Route”通知 然后你可以决定应该怎么做 你可能想要断开数据连接 重新连接到Wi-Fi
或者如果你的邮件 发送进度已经达到99% 你可能想要完成发送 但是 “Better Route”通知 让你能够进行 智能化的决定 从而尽量减少数据流量费用
下一个主题是网络中的延迟
这是我在Apple TV 开发中遇到的问题 我们努力提高Apple TV的 响应速度 和理解延迟来源 我期望你们在座的每个人都听说过 “bufferbloat”即“缓存膨胀”
我做过一些实验并且想和你们分享 这些实验的结果 让你们理解对于我们的 所有APP和产品来说 消除网络中的缓存膨胀问题是多么重要
我测试过一个10Mb下行速度 模拟网络环境, 这种网速对于观看视频来说已经足够了 我将显示使用代表性 网络设置所获得的结果 这是一种简单的先进先出队列 数据包被缓存直到队列变满 不能再容纳更多数据包 新到达的数据包将被丢弃 这是现今的家用网关的典型配置 我将介绍另外一种更智能的 队列处理方法和ECN机制并进行比较
我将介绍一些 使用tcptrace的方案 我期望你们 很多人都使用过tcptrace 如果你们没有使用过 我强烈建议你们访问 TCPtrace.org并下载它 如果你要编写网络代码 而且不使用tcptrace 来查看你的数据包 你将没有办法弄清楚 运行机制或理解APP 和协议的性能特征 在我们编写APP时 应该注意内存使用情况 应该分析代码 弄清楚哪些代码占用CPU 然后优化代码 以提高CPU效率 并且延长电池使用时间
为此应该多关注CPU 和内存使用情况 但是也不能忽略网络部分 Tcptrace是一个工具 让你能够方便地 进行网络分析分析网络流量
这是一个流媒体视频的 前10秒的TCPtrace 如果你们一些人 以前没有见过tcptrace 让我来简要介绍一下 这些白色的短线条表示数据包
白色线条所处的位置 表示数据包被捕获的时间
白色线条的高度告诉我们 数据包有多少字节线条的垂直位置 告诉我们在整个逻辑TCP序列, 数字空间内的哪些位置 收到这些数据包
在这里我们可以看到 正在按顺序向外发送数据包流 其间隔为数毫秒
在返回数据时 我们看到接收端的应答消息 声称它已经收到数据
绿色线条表示累积应答线条 所有数据包括绿色线条 都得到接收端的确认 因此没有任何白色数据包 位于绿色线条之下 那将表示存在bug 我们看到没有白色数据包 位于绿色线条之下这说明一切正常
黄色线条表示接收窗口 当你打开TCP连接时 接收端将指示它分配多少内存
来接收你的数据 不应该超过这个分配给你的内存量限值 如果你看到白色数据包位于黄色线之上 表示存在bug我们没有看到这种情况 这说明一切正常
数据传输看起来 显示为一条直线 这条曲线的斜率是10Mb/s 这正是我们所期望的但是每隔几秒 我们看到这种情况 让我们来放大仔细观察 发生了什么
这些TCPtrace 图形提供丰富的信息 我可以花上一个小时的时间 来讲解这些幻灯片 但是我们并没有时间这样做 我会讲解这个图形中的一些重要信息
首先白色数据包线看起来正在
偏离绿色应答线条 这意味着我们将数据发送到 网络的速度快于数据从另一侧被输出 和被应答的数据 如果数据被输入的速度 快于被输出的速度
情况就会变得不一样 数据将会进入缓存网络缓存中的 旧数据将会增大 由于缓存数据量增大 意味着数据包发送与 接收端应答之间的往返延迟增大
当缓存数据量达到一定程度时 网关将无法缓存更多数据 将开始出现丢包现象
将会发生混乱而且是非常严重的混乱 因此数据包进入队列末尾的速度 将会快于数据包出列的速度 我们收到数据包但是会丢失它们 其他数据包也会被丢失 队列被清空一点 我们获得一个数据包接受它 在队列的末尾是一片混乱 它获得一个数据包就会丢失一个数据包
但是在队列前部 有200个数据包依次排列等待 它们需要有序地 经过10Mb瓶颈链路 不能有间隔不能发生问题 只有在整个队列的数据 发送完之后我们才会看到 反映在发送端选择性应答消息中的 接收端的数据包丢失情况 然后开始进行补包 因此这是严重的混乱现象
由于网络传输API的工作方式 数据必须依次传输
如果一个数据包丢挡住 其后抵达的所有数据包 在内核中将被延迟 直到间隙被填满 这是有道理的 很多人曾经建议使用无序传输方法 但是结果发现几乎所有APP都很难 使用无序数据 如果你要解码H.264视频 只获得数据帧而无法获得它们 所依赖的I-Frame将不会有意义 因此顺序数据传输确实是 APP所需的传输模式
顺序数据传输导致 我们看到这些长时间的空白期 在此期间没有数据传输 对于Apple TV 视频回放流程来说 这相当于一个无信号时间段 在此期间将接收不到数据 我们不想要视频卡住 因此所有流媒体视频 都需要一个回放缓冲区
较大的回放缓冲区意味着 当你观看流媒体视频时 你会看到不断旋转的图标提示正在缓冲 因为缓冲区还有填满 因此当长时间没有数据到达时 可能会始终显示这个图标
当丢失的数据包到达时 我们开始填满间隙 并且立即播放视频
这将会给网络接收线程带来额外的负担 它需要将CPU时间分配给 视频播放线程之外的其他线程 从而造成视频播放卡顿 这不是我们想要的
这种不均衡的网络数据传输 给Apple TV等设备 造成不佳的用户体验在我们努力降低 设备的成本时 这种长时间的数据空白期 相当于我们需要增大设备内存 来缓存更多数据 并且推迟视频开始时间和降低用户体验
这种传输不均衡现象 还会导致设备需要更快的CPU 从而抬升设备价格 因此对于流媒体视频来说 这种不均衡的传输是十分有害的
一个有意思的事情是 如果你跟踪观察 黄色应答线条的斜率... 黄色窗口线和和绿色应答线条 你会发现如果不发生丢包在轨迹末端 线条会回到它们原本应该所在的位置 因为TCP协议能够高效率地 一次性填充需要重新传输的数据包 而不会传输其他不需要重新传输的数据 因此它将会返回原本应该所处的位置 如果使用Iperf测量网络速度 并且查看测量值 你将会看到它显示为10Mb/s 你会说很好我的网络一切正常
但是如果你探究这些信息 分析具体的数据 你就会发现实际的网络情况
现在我们知道是什么原因 造成网络性能下降 我决定使用智能网络进行实验 对于这个实验我使用 一种名为CoDel的智能队列算法 它是Controlled Delay的简称
其工作原理不是填充队列 直到队列溢出并丢失数据 相反它监测队列的状态 当队列快要变满时 将会把它视为一个拥塞信号 对于拥塞很多人认为
我说的是高峰时间出现的情况 实际上不是这样的 必须理解的是在网络数据传输中 拥塞始终存在 它是一种稳定的网络状态 TCP等传输协议的任务是 最大限度地利用网络 以确定网络的最大承载能力 并且最高效地利用网络 传输协议的工作原理是 它越来越快地传输数据 同时始终进行侦测 它尝试不断发送更多的数据 直到发生丢包这时它将 知道负载过大并开始削减流量 它始终进行这种尝试 以找到合适的传输速率 这意味着它始终在尝试 使网络进入拥塞状态 然后降低传输负载从而减少拥塞 CoDel的工作原理并不是 等待网络进入拥塞状态 然后发出拥塞信息 在发现第一个拥塞信号之后 它就会通知发送端
在这个实验中我做的另一事情 不是通过丢包来指示拥塞 这需要重新传输 相反我使用一种名为“显式拥塞通知” 即Explicit Congestion Notification的新技术 智能队列算法不会丢弃数据包 它设置IP标头中的一个位 声明遇到拥塞 这个消息被传回给发送端 发送端作出响应 降低传输速度 而不会造成破坏性的丢包后果
这是使用CoDel和ECN的 数据传输示意图如果我放大 前面看过的相同部分 你可以看到非常明显的差别 在我进行这些实验时 我计划用一周的时间 来完成这些工作和收集数据 结果只用了两个小时就全部完成了 一个方案使用标准配置来执行 一个方案使用CoDel来执行 这是我的第一个实验 我预计需要调整参数重试并返回实验 但是没有发生这种情况 差别很明显 只需进行一次试验就够了 好像有人在鼓掌 谢谢
我们没有看到传输中断现象 也没有出现高峰拥塞 每次出现轻微的队列拥塞时 CoDel算法就会发出信号 要求降低传输速度 这个方案的CWR标记 的含义是“减少拥塞窗口期” 这是TCP的应答消息 意思是消息已经被接收和理解 我已经降低传输速率 这确实很不错
总的来说CoDel 和其他队列算法非常有效 ECN十分有效 将它们组合在一起将会功效倍增
那么如果这么有效 应该在哪里使用它们? 从历史来看对于传统的网络应用来说 例如文件传输和发送电子邮件等 丢包和重新传输并不会造成严重的问题
当你传输文件时原则上传输层将会 最后发送第一个数据包 而且最先发送最后一个数据包 其间的所有数据包 将会随机发送 在数据包全部到达之后 将会按照文件的正确顺序重新进行组装 这就是你需要关注的所有事情
但是当你观看流媒体视频时 你并不想先看到结尾最后看到开头 你希望按顺序观看 这时按顺序发送数据 就成为一个更紧迫的问题 现在我们通过 Internet传输流媒体视频
这里的一个特点是在以前的应用中 例如点击发送电子邮件等 需要发送的数据量是预先确定的 而发送所需要的时间是可变的 基本上网络发送电子邮件 所需要的时间是越少越好 我们并没有邮件发送过快这样的说法 发送时间是可变的你希望它越快越好 现在的应用则有不同
比如你通过Internet 观看两个小时的电影
我们不应该半个小时 或八个小时内看完成 而必须是两个小时 现在我们的应用必须具有适应能力 时间是固定的但是必须调整 这段时间内发送的数据量 以适应网络状况
现在的情况是怎样的? 让人惊奇的是 Linux已经支持此功能 而且在世界性能最强的 一百万台Web服务器中 一半以上默认支持ECN 对于一项无人使用的技术来说 这种应用广泛性是惊人的
客户端并不请求ECN连接 它们不请求ECN在很大程度上 是因为Internet 不支持ECN标记 如果你启用这个选项 可能会带来暴露bug的风险 而且没有直接好处
那么路由器在做什么? 没有路由器进行标记 因为没有客户端请求它们 那么为什么要设计 这样具有风险而且无人使用的功能呢? 今天我高兴地宣布 Apple将首开先河 打破这个僵局 在所有的基本应用中默认情况下 所有应用的所有 TCP连接将支持ECN
我们将不会看到任何问题 在我们的测试中一切运行正常 我已经在我自己的 笔记本电脑上运行很长时间
当然我们希望倾听你们的体会 请接受这些基本应用在你的家庭网络 工作单位酒店和机场使用它们 和以前一样如果发现任何bug 请报告给Apple 如果我们取得成功几个月之后 将会有数百万设备运行ECN 这样ISP将有足够的动力 来提供这项服务
现在我们将主题从网络延迟 转移到终端系统延迟 许多技术进步的出发点是为了 克服我们自己遇到的不便之处 这里也同样如此
我使用屏幕共享功能 连接到我家里的Mac计算机 这种功能真不错 我能够远程控制计算机 能够访问计算机上的数据 能够开始费时的视频转码 在我到家时就已经完成转码 这些确实不错
在我进行这些实验时
我使用的是很慢的DSL线路 当然DSL是非对称的 一般来说下行速度比上行速度快十倍 当你进行屏幕共享时 数据传输方向是上行方向 因此速度会比较慢 这有一点像那个众人皆知的 关于熊跳舞的笑话 当你看到熊跳舞时 你不应该惊讶于熊跳舞跳得很好 而应该惊讶于熊会跳舞 多年人与很多人一样 我被这个让人难受的 勉强可用的功能所困扰 我发现当我点击一个菜单时 要花费三到四秒的时间 菜单才会显示出来 这样使用计算机几分钟之后 让人感到非常不舒服 有时候恨不得快点开车回家 亲自在计算机上操作
我曾经研究过 “bufferbloat” 和网络中的过度队列 很自然地我首先感到不满 并且开始研究 我最初认为罪魁祸首 应该是这个愚蠢的DSL调制解调器 产生过度的缓存膨胀 于是我ping计算机 ping时间为35ms 当我点击鼠标时 却需要3秒才能显示鼠标
我意识到情况可能 与我当初设想的不一样 那么延迟来自于哪里呢? 对此我进行了一些研究
当时默认socket发送的 缓存数据是120KB 我的网速率大约是50KB/s 用时约为2.5秒 这与我看到的延迟时间差不多
发送缓冲数据的socket 具有十分重要的意义
当我们使用TCP等协议时 它会发送一个数据包等待应答 然后再发送一个数据包再等待应答 这样的性能十分低下 我们需要一次发送多个数据包 我们需要足够多的数据包 以充分利目的地往返传输路径的带宽 而且必须缓存这些数据包 这样当它们丢失时可以重新进行传输。 最大限度利用连接吐吞率 是一个很好有用而且必要的方法 但于超过需求的缓存 仅仅会增加延迟而不会带来好处 它不会帮助提高吞吐率 而只会增大延迟 最终我们只会得到这样的结果 我们一次仅传输少量的数据 而且这些数据进入缓存 以备在需要时重新传输 而另一方面有大量的数据 在内核中等待被发送出去
这让我明白
不仅网络上存在延迟 而且主机之中存大量延迟
屏幕共享程序会抓取 一个画面帧将它送入缓存 再抓取一个画面帧将它送入缓存 内核将会让这些帧 像葡萄酒那样长时间陈酿然后才会在 特定时间将它们通过网络发送出去
为此我们引入了 TCP_NOTSENT-LOWAT 套接字选项 发送这个选项时
Socket_Send_Buffer 保持不变
区别在于kevent 或你的run loop不会报告 Socket正在被写入 直到未发送的数据量 达到很低的阀值 通常为8或16KB
当socket转为可写入状态时 你可以将单个有用的 基本数据块写入缓存 不需要循环操作中 内核中也不会积累过多的数据 因为现在内存已经很便宜 它可以容纳大量的数据
你只需写入一个感应单元 在屏幕共享程序中它是一个帧 现在的情况是这样的
有数据在等待发送它们位于缓存中 需要等待较短的时间让它们发送出去
在发送完毕之后中达到阀值 Socket转为可写入状态 我们写入一个数据块 在它发送完毕之后再写入更多数据块 现在我为你们演示这个过程
在这里我将要在这台计算机上 使用屏幕共享程序连接到这台计算机 我将使用一个运行 sarawert的网关 来模拟DSL连接
让我们调出终端窗口
看到了
我将移动这个窗口
你可以看到鼠标指针在移动 因为它是本地生成的 实际的图形更新是由远程计算机生成的 让我们窗口移动这里 不 不是这里 让我们移动它 不 我想让它回到原来的地方 双手离开键盘
让我们调出菜单:Shell
它出现了 让我们打开“Edit” 或者“View”
这个演示让人感觉很着急 看起来远程使用我的计算机 是非常费劲的事情 这需要很好的耐心
现在我一个新的方法
我启用 TCP_NOTSENT-LOWAT选项
然后重新进行连接 我可以随意拖动这个窗口
谢谢 多年来 在BSD网络应用中 我们一直忍受着这种极其 糟糕的屏幕共享连接
好消息是我们已经解决这个问题 现在此技术已经在
10.10.3最新版本中得到应用 如果发现屏幕共享得到越来越多的运用 背后的原因就在这里 此技术已经被AirPlay使用 而且也可以在Linux中使用 因为此选项应用于发送端数据源 因此如果你运行Linux服务器 此选项也可以用于你的服务器
对于实时应用来说 这种降低延迟的好处很明显的
在制作本讲座的幻灯片时 我将APP分为两类 一类APP应该使用 tcp_notsent-lowat选项 另一类APP不应该使用 但是我想不出任何APP 应归入不应该使用此选项的类别 每次我们想到哪些传统应用 可能不需要使用此选项例如文件传输 我们发现你们曾经有这样的经历 你想要取消文件传输 你按下Control-C 但是需要大约30秒的时间才能取消 这是因为程序将所有数据 过量载入内核而必须等待数据被清空 因为并没有方法来改变此操作 事实上文件传输 并不会受益于过量载入数据 我们想不出会任何APP 会受益内核中的过量数据堆积 在认识到这种情况之后 我们决定在下一个版本中 使用更高层次的SURLSession 和CFNetwork API 自动为所有连接启用此选项
为了最有效地利它需要做的事情是 当socket变为可写入状态时 在看到EWOULDBLOCK错误码之前 不要循环写入大量的数据 只需要写入合适大小的数据块 然后等待被告知可以写入更多数据块 这样如果用户改变主意 或者网络环境发生变化 下次socket变为可写入状态时 你可以做出明智的决定
你可以即进生成数据 根据当前的信息 而不是5或10秒前的信息 生成最新的数据
现在进入本讲座的最后一部分 让我们来窥探 一项名为TCP Fast Open的 全新技术
传统TCP工作原理是这样的 我们通过发送消息和获得应答 设置TCP连接 然后我们第二次发送消息和获得应答 以发送请求和获得响应
TCP Fast Open 将连接设置 与数据交换合并成为一个数据包交换
所有APP并不会默认启用此选项 而这是有原因的
你需要注意这个警告信息 提示说此功能仅对 幂等数据来说是安全的 我将解释这其中的含义
当你使用TFO操作时 握手与数据组合在一起
服务器将收到消息服务器 作出反应发送响应信息 然后你关闭连接
Internet的工作模式并不保证 不会重复发送数据包 Internet的成功得益于 其非常简单的工作模式 即快速低成本地发送数据包 你不需要考虑数据包的发送顺序 不需要担心数据包是否损坏或丢失 或者重复发送数据包 只需实现快速和低成本就可以了 终端系统非常智能化 能够适应这种网络模型
重复发送数据包的原因是多少方面的 可能是因为路由器有bug 也可能是因为Wi-Fi链路层 意外地发送数据包两次 终端系统可能重复发送: 如果你发送数据包 但是应答消息丢失 你将需要重新发送数据包 这样网络中就会出现两个相同的数据包 如果其中一个数据包发生延迟 并且在很久以后出现 对于服务器来说 这是一个完全有效的TFO请求 无论操作是什么都会再次执行此操作 如果操作是向你发送一幅JPEG图片 进行两次这样的操作 并不会带来严重的后果 但是如果操作是 发送一双Zappos鞋子 两次进行这样的操作可不是你想的 对于这种情况你必须做出明智的决定 哪些操作是合适和安全的 哪些对你的APP来说不合适
你可以通过connectx 系统调用来这样做 这是早期适配器的简要技术预览
让我们来看如何通过更高层API 来展示这个技术 但是目前还不能 使用connectx来实现 与你进行对话的服务器必须支持TFO APP必须选择加入对话
如果你运行Linux服务器 你必须具有几个星期以前 发布的最新Linux内核 此内核支持标准ITF、TFO、 TCP选项代码 OS X操作系统也同样如此
最后作为总结我希望你们 记住今天讲座的要点
即 你应该尽可能地 使用最高层次的网络API 这样你将能够获得 这些API所能提供的全部功能
你绝对必须在NAT64网络上 测试你的APP 幸运的是我们进行了大量的简化工作 你只需要点击“选项”就可以了
可靠的网络回退机制 能够让你的APP提供更好的用户体验
你需要做的是注意 “Better Route”通知 这样当Wi-Fi重新可用时 你可以返回到Wi-Fi连接
“显式拥塞通知” 是一项新的基本功能
它通过降低队列等待和减少丢包 大幅提高网络数据传输的响应速度 我希望你们测试这些功能 并且报告任何问题
利用 CPNOTSENT-LOWAT选项 你可以为自己设置一个 socket选项 在下一个版本中你将可以免费使用它 从而大幅减少发送机中 缓存的迟滞数据量
最后对于喜欢 TCP Fast Open的开发者 我们已经提供此功能
有很多不错的文档资源可供你查看 你们并不需要记下这些URL 可以点击PDF文档中的链接
还有一些不错的论坛 你可以提问并且讨论 与网络应用相关的问题
我鼓励你们观看 NSURLSession讲座 和Network Extensions讲座 在网络实验室午餐休息之后 也可以与我们讨论 我们将会回答你的所有问题 谢谢
-
-
正在查找特定内容?在上方输入一个主题,就能直接跳转到相应的精彩内容。
提交你查询的内容时出现错误。请检查互联网连接,然后再试一次。