Hi,欢迎来到 卡瓦邦噶!我是 laixintao,现在生活在新加坡。我的工作是 SRE,喜欢在终端完成大部分工作,对各种技术都感兴趣。我从 2013 年开始写这个博客,写的内容很广泛,运维的方法论,编程的思考,工作的感悟,除了技术内容之外,还会分享一些读书感想,旅行游记,电影和音乐等。欢迎留下你的评论。

声明:本博客内容仅代表本人观点,和我的雇主无关。本博客承诺不含有 AI 生成的内容,所有内容未加说明均为博主原创,一经发布自动进入公有领域,本人放弃所有权利。转载无需本人同意。但是依然建议在转载的时候留下本博客的链接,因为这里的很多内容在发布之后会还会不断地继续更新和追加内容。 Not By AI

学习网络的一点经验

在网络抓包系列的最后,再来说一下网络学习的一些经验。毕竟,能通过抓包来解决问题的前提是具备网络协议的知识,不然的话 Wireshark 和 tcpdump 用得再熟练也看不懂抓到的包。

以下是我觉得一些比较好的学习方法,我从中获益良多。

和朋友讨论学到的东西

学到了一个新的知识点或者新的协议,可以尝试解释给朋友或者同事听。比如在吃饭的时候,「嘿,你知道吗?TCP 三次握手的第三个包实际上是可以携带数据的!」然后他们会想这个问题,问你「要是有些 Server 不能处理带数据的第三个包怎么办?」这样,你就要重新思考你学的知识,看它是否考虑周全。教是最好的学习方法。如果没有朋友的话,可以考虑写一个博客(像我一样?呵呵)。

认识实际的网络,也可以从公司的网络结构开始。平时总结一下自己的问题,多阅读一些内部的文档。在内部 traceroute 跑一下,看看每一个 hop 都是什么。找时间请网络团队的同事吃饭,然后问他们你的问题。

举一反三

要学会提问。网络协议的目的一部分是传输数据,更重要的,它需要处理各种异常情况,保证即使出现各种意外,也能尽最大努力工作。所以,我们在学习的时候可以经常问题自己:如果这时候出现 xx 会怎么样呢?

问自己问题,然后思考,尝试给自己解答。在思考的过程中,会产生很多解决方案,大部分可能都是有问题的,然后找到其中的问题,推翻自己的方案。比如,网络为什么要分开三层和二层?这个世界上只有 IP 层,没有链路层行不行?或者只有链路层,不要 IP 层了行不行,整个世界都是一个「大二层」,会有什么问题?

网络相关的知识常常是零碎散乱。我的经验是,不要一开始就跳到兔子洞里面去。面对一个新的概念的时候,可以这样来入门。举个例子说,比如 SOCKS5 协议:

  • 第一步是问:「这个东西是来解决什么问题的?」这个问题必须始终记在心里的,如果搞不清楚,后面会有更多的困惑。
  • 第二步,可以自己想出来一种方案来解决这个问题。方案一开始不必完美,只要解决问题即可。很多方案就是这样设计出来的,现有一个简单的方法,再想想有没有什么缺陷,然后试图优化方案来解决缺陷。
  • 如果觉得自己的方案应该没有问题了,就可以进行第三步了,去深入理解 SOCKS5 协议。可以直接去读 RFC1,不要害怕,RFC 读起来没有那么难!阅读 RFC,可以和自己的方案做对比,看看有哪些问题是还没有想到的。

其实我觉得,网络协议的设计在最开始的时候考虑并没有很周全,比如 TCP 的一些问题,HOL Blocking;比如 OSPF 协议的奇怪名字 NSSA 之类的。感觉是设计出来之后,然后发现在现实中会有问题,就会在给原来的东西打上补丁。

研究网络协议

很多网络协议设计的是很美的,我喜欢那些简单又能解决问题的协议。比如 VRRP,只有一种数据格式包。像 TCP,DHCP 这种就复杂许多,它们的魅力在于解决了复杂的问题,适应各种复杂的环境。

了解网络协议除了按照上面的方法自己来挑战设计,还可以格物致知,看协议的每一个字段,搞清楚这些字段都在解决什么问题。一般每一个字段都是为了解决某种问题或需求而存在的。

面对复杂的协议的时候,把它拆成一个一个小的部分,单独攻破。比如 BGP,状态,选路之类的太复杂了。方法就是 break down,一个一个来。

光学习 Wireshark 这种工具是不行的,工具是围绕网络协议设计出来的,网络协议设计出来是为了解决真实的问题的。所以学习网络协议,它们解决问题的方法,才是主要的。另外,只有懂网络协议才能用好工具。比如,精通 ICMP 和 IP 的 TTL 设计,才能精通 traceroute 的使用。

多读书

像 TCP 的书从协议设计到实现,有数不清的书来介绍。读一本是不够的,因为对于网络协议,不同的作者有不同的理解,有不同的比喻。读书就像和作者聊天一样,和不同的人探讨自己对一个东西的认识,有助于加深理解。

上面通过自己设计协议来理解协议的方式,就是 Computer Networking: A Top-Down Approach2 这本书作者用的,作者用从零开始设计 TCP 的方式来教授为什么 TCP 是今天这个样子的。

同一本书也可以读第二遍,所谓书读百遍,其义自见。

PS:不要看国内的大学讲课视频

如果一个视频明显是那种中国大学的讲课录屏,基本就没有必要看了。这些视频通常知识和现实脱节,讲的内容很多也在现实中见不到,照本宣科,避重就轻。除了磨灭读者的兴趣,把有趣变成枯燥,就没什么价值了。没有兴趣和热情,就学不好。


说到最后,兴趣是最好的老师,对我来说,根据自己的知识和工具拨开迷雾,解决一个一个的问题,是再有意思不过的了。每个人会在人生的一个时间,发现这个世界不是公平的。但是在计算机的世界里,是很公平的,多花一点时间,多思考一些,就会多一分收获,它与天分无关。技术会过时,自己辛苦习得的技能也可能被 AI 轻而易举取代,但是曾经在学习和进步中体会到的乐趣是真实存在的,那些经验运用到新的技术中也多少是有所帮助的。祝愿读者在自己的领域体会到平静和乐趣。

==抓包破案录==

这篇文章是抓包破案录系列文章(之前叫做《计算机网络实用技术》,后来改名了)中的一篇,这个系列正在连载中,我计划用这个系列的文章来分享一些网络抓包分析的实用技术。这些文章都是总结了我的工作经历中遇到的问题,经过精心构造和编写,每个文件附带抓包文件,通过实战来学习网络抓包与分析。

如果本文对您有帮助,欢迎扫博客右侧二维码打赏支持,正是订阅者的支持,让我公开写这个系列成为可能,感谢!

如果您正在阅读的是题目类的文章,这个目录内容正好用来隔离其他读者的评论。读完题目可以稍作暂停,进行思考,继续向下滑动,可能会被其他的读者剧透答案。

没有链接的目录还没有写完,敬请期待……

  1. 序章
  2. 抓包技术以及技巧
  3. 理解网络的分层模型
  4. 数据是如何路由的
  5. 网络问题排查的思路和技巧
  6. 不可以用路由器?答案和解析
  7. 网工闯了什么祸?答案和解析阅读加餐!
  8. 网络断断续续……答案和解析
  9. 延迟增加了多少?答案和解析
  10. 压测的时候 QPS 为什么上不去?答案和解析
  11. 重新认识 TCP 的握手和挥手答案和解析
  12. TCP 下载速度为什么这么慢?答案和解析
  13. 请求为什么超时了?答案和解析
  14. 0.01% 的概率超时问题答案和解析
  15. 后记:学习网络的一点经验分享
与本博客的其他页面不同,本页面使用 署名-非商业性使用-禁止演绎 4.0 国际 协议。
  1. 如果你感兴趣的话,socks5 的 RFC 是 https://datatracker.ietf.org/doc/html/rfc1928 ↩︎
  2. https://www.amazon.sg/Computer-Networking-Top-Down-James-Kurose/dp/0133594149 ↩︎
 

ARP 问题诊断

这是 网络断断续续 一文的答案。

答案是,在同一个子网内,同一个 IP 地址分配到了 2 个不同的设备上。

对于这种时而正常时而异常的「幽灵问题」,在没有思路的时候,可以通过对比的方法来寻找线索。

有的时候 TCP 能够连通,有的时候无法连通。那么正常的 TCP SYN 包和异常的 TCP 包之间肯定是有什么字段是不一样的。当然,也有可能 SYN 包一模一样,问题出在了其他的网络设备上或者 TCP 的另一端。但是既然题目出给读者了,那么问题的根源肯定是隐藏在抓包文件里面。

通过对比来寻找答案

正常的 TCP 连接可以完成 TCP 的握手和挥手。

异常的 TCP 连接,发出去的 SYN 直接收到了 RST。

通过对比可以发现,两个 SYN 包的 Dst MAC 是不一样的。

通过推理得出答案

如果不通过对比的方法,顺藤摸瓜,可以用下面的思路。

首先,Src IP 和 Dst IP 分别是 10.210.151.187 和 10.210.151.90,很大概率是属于同一个 /24 子网的 IP,不过要想确认的话需要看下服务器的 IP 地址是如何配置的,子网掩码是不是 /24,这点我们从给出的信息无从得知。

假设确实是属于同一个子网,那么 TCP SYN 包不经过网关,直接发给目的地址,二层的 Dst MAC 地址应该是目的 IP 的 MAC 地址。

假设不属于同一个子网,那么 TCP SYN 包经过网关,TCP SYN 包的目的地址应该是路由器的 MAC 地址。

无论是那种情况,正常情况下发送给同一个 Dst IP 的目的 MAC 应该是唯一且稳定的。通过 Conversation 统计可以看出,通讯的 IP 对只有一对,但是 MAC 的确有 2 对,这是不对的。

Statistics > conversation

原因分析

造成这种现象的原因是,IP 分配重复了,在同一个子网内,同一个 IP 地址 10.210.151.90 被分配给了多个机器。

发送 TCP 包之前,需要知道对应的 Dst IP 地址的 Dst MAC 地址,怎么知道呢?Src 机器会在整个子网内广播 ARP 询问,持有这个 IP 的机器会回复 ARP。现在子网内有两个相同的机器是相同的 IP 地址。这两台机器的 IP 地址一样,MAC 地址不一样。如果我们现在 arping 10.210.151.90 ,会得到如下的回复:

可以看到,我们发出去 3 个询问,却收到 6 个回复。说明每一个询问得到了 2 个答案。(其实,在诊断和验证这个问题的过程中,最快的方式就是用 arping 来测试一下,而不是抓包来分析。但是这里我们主要讨论抓包技术,所以拿来当作一个分析的案例。)

那么 Src 收到两个 ARP 应答,会以哪一个为准呢?答案是以先收到的为准。

但是 ARP 请求广播出去,这两个 ARP 应答哪一个先到是无法确定的,有的时候 5a:65:98:0c:82:02 先到,有的时候 c2:10:70:f2:ae:ab 先到,所以发送给 10.210.151.90 的包,有的时候发给了 MAC 地址为 5a:65:98:0c:82:02 的机器,有的时候发送给了 MAC 地址为 c2:10:70:f2:ae:ab 的机器。

补充一点,在实际的问题排查过程中,我们的 TCP 连接测试失败,最好的排查方法就是去对端进行抓包,看一下对端的机器是否收到了 SYN 包。以及在实际的现象中,客户端收到了 Connection refused ,通常意味着收到了 RST 报文(可能来自真实对端,也可能来自其他设备)。我们在对端抓包的过程中会发现即没有收到 SYN,也没有发出 RST,这说明包到别的地方去了。进而,我们可以发现字网内还有一个「李鬼」的问题。

那么,为什么 ping 的测试完全正常呢?

因为 ICMP 是无连接协议,,ping 的 ICMP 协议回复,是由 Kernel 负责的,所以无论 ICMP 包发送到哪一个机器上,由于它们都设置了这个 IP 地址,所以都可以做出回复。其实抓包中的回复是来自不同的机器,只不过 ping 不知道,只要是收到了回复,就认为一切正常。

可以把 Src MAC 地址添加到 Column 显示,就可以发现其实 ping 的回复来自不同的设备。

最后一个问题,为什么会有 IP 重复的问题呢?

DHCP 可以用来动态分配 IP 地址给设备,但是一般只用于客户端,比如办公网、家用网络中的终端设备,这些设备一般作为连接的发起方,不需要 listen 一个固定的 IP 地址,IP 地址的动态变化对它们影响不大。但是在 IDC 的网络中,每一个服务器的软件都需要固定的 IP 地址,一般不用 DHCP 来动态分配,而是用中心化的 IPAM 系统1追踪 IP 地址的分配情况。如果里面记录的地址不正确,比如,一个地址已经在使用中了,但是并没有在 IPAM 记录,就造成 IP 地址重复的问题。

  1. https://en.wikipedia.org/wiki/IP_address_management ↩︎

==抓包破案录==

这篇文章是抓包破案录系列文章(之前叫做《计算机网络实用技术》,后来改名了)中的一篇,这个系列正在连载中,我计划用这个系列的文章来分享一些网络抓包分析的实用技术。这些文章都是总结了我的工作经历中遇到的问题,经过精心构造和编写,每个文件附带抓包文件,通过实战来学习网络抓包与分析。

如果本文对您有帮助,欢迎扫博客右侧二维码打赏支持,正是订阅者的支持,让我公开写这个系列成为可能,感谢!

如果您正在阅读的是题目类的文章,这个目录内容正好用来隔离其他读者的评论。读完题目可以稍作暂停,进行思考,继续向下滑动,可能会被其他的读者剧透答案。

没有链接的目录还没有写完,敬请期待……

  1. 序章
  2. 抓包技术以及技巧
  3. 理解网络的分层模型
  4. 数据是如何路由的
  5. 网络问题排查的思路和技巧
  6. 不可以用路由器?答案和解析
  7. 网工闯了什么祸?答案和解析阅读加餐!
  8. 网络断断续续……答案和解析
  9. 延迟增加了多少?答案和解析
  10. 压测的时候 QPS 为什么上不去?答案和解析
  11. 重新认识 TCP 的握手和挥手答案和解析
  12. TCP 下载速度为什么这么慢?答案和解析
  13. 请求为什么超时了?答案和解析
  14. 0.01% 的概率超时问题答案和解析
  15. 后记:学习网络的一点经验分享
与本博客的其他页面不同,本页面使用 署名-非商业性使用-禁止演绎 4.0 国际 协议。
 

网络断断续续……

各位读者新年好呀~ 最近比较忙,博客快要长草了。今天我们再来看一个实际的网络问题。

症状如下:

在一次服务扩容的时候,新扩容的虚拟机网络断断续续,它的 TCP 服务时而能连上,时而连不上。新扩容出来的虚拟机的 IP 地址是:10.210.151.90。

于是我们联系了虚拟机团队的负责人小马,小马一听说虚拟机的网络有问题,上来就是一顿 ping,结果呢,一个包都没丢。「网络肯定没问题,一定是你们自己服务的问题啦。」小马说。

「可是我们用这台虚拟机部署的服务确实不能用啊!」业务的同事可怜巴巴地说。却也没办法说服小马继续排查网络问题了。小马说:

When a problem is yours, own it. When a problem isn’t yours, prove it.

这时,业务团队里面正好有一个精通网络分析的同事(就是你!),这位网络大神随便找了一台机器,一边去用 ping 和 nc 做 TCP 连接测试,一边 tcpdump,得到下面的抓包文件。

网络大神把这个抓包文件下载到本地,分析起来,不一会儿,就得出了结论……

请分析这个抓包文件,回答:为什么 TCP 连接时而成功时而失败?

==抓包破案录==

这篇文章是抓包破案录系列文章(之前叫做《计算机网络实用技术》,后来改名了)中的一篇,这个系列正在连载中,我计划用这个系列的文章来分享一些网络抓包分析的实用技术。这些文章都是总结了我的工作经历中遇到的问题,经过精心构造和编写,每个文件附带抓包文件,通过实战来学习网络抓包与分析。

如果本文对您有帮助,欢迎扫博客右侧二维码打赏支持,正是订阅者的支持,让我公开写这个系列成为可能,感谢!

如果您正在阅读的是题目类的文章,这个目录内容正好用来隔离其他读者的评论。读完题目可以稍作暂停,进行思考,继续向下滑动,可能会被其他的读者剧透答案。

没有链接的目录还没有写完,敬请期待……

  1. 序章
  2. 抓包技术以及技巧
  3. 理解网络的分层模型
  4. 数据是如何路由的
  5. 网络问题排查的思路和技巧
  6. 不可以用路由器?答案和解析
  7. 网工闯了什么祸?答案和解析阅读加餐!
  8. 网络断断续续……答案和解析
  9. 延迟增加了多少?答案和解析
  10. 压测的时候 QPS 为什么上不去?答案和解析
  11. 重新认识 TCP 的握手和挥手答案和解析
  12. TCP 下载速度为什么这么慢?答案和解析
  13. 请求为什么超时了?答案和解析
  14. 0.01% 的概率超时问题答案和解析
  15. 后记:学习网络的一点经验分享
与本博客的其他页面不同,本页面使用 署名-非商业性使用-禁止演绎 4.0 国际 协议。
 

Piccolo P2P 镜像分发

我们遇到的 Harbor 的另外一个问题是 image 的下载瓶颈。在容灾的时候,我们需要在短时间内启动几万个容器。Harbor 这里就成了瓶颈,抛开所有的数据库和文件系统的瓶颈不说,网络这里就需要 Tib 级别的带宽。这是不现实的。

用户构建的 image 质量参差不齐,大于 10GiB 的 image 比比皆是,尽管这些 image 都有很大的优化空间,但是期望所有的用户都按照构建 image 的最佳实践1进行优化,也是不现实的。

于是问题就成了:如何才能够大量的 worker 节点迅速扩容上万的容器?

此外,在平时,遇到工作日多个系统发布的时候,或者整点的时候运行定时任务(定时任务每次都会下载 image),harbor 的压力也非常大,经常满载运行。如果能解决这个问题,平时的负载问题也可以缓解。

之前介绍过 Spegel 的下载方案2,Spegel 的想法很好,基本思想是,先去其他已经存在这个 image 的机器上去下载,如果找不到,再 fallback 到 Harbor 下载。可惜的是,Spegel 把 P2P 下载和 P2P 服务发现混为一谈了,导致服务发现的性能极低。

什么意思呢?去其他的机器上下载 image,需要的一个信息是:哪一个机器有这个 image?这就是下载源的服务发现。这个服务发现和 P2P 本质上没有什么关系,用什么都可以。P2P 技术解决的是下载上的瓶颈,只有能有一个方法记录每一个机器上现在都有什么 image 就可以,用 Etcd 也可以,不一定也得用 P2P 形式的。

但是 Spegel 这里是用 P2P (libp2p)做的服务发现。在我看来这是完全没有必要的。我们在实际的部署中遇到的问题有:

  • 服务发现的 latency 高,现在的配置是 30s,还是会有超时,P2P 本质上是在一个不稳定的分布式网络中寻找一个资源,效率不高;
  • 成功率低,在 P2P 网络里面,能否发现一个 key 是概率性问题,不是确定的3
  • 删除 image 不会分发到 p2p 网络中,必须有访问事件得到 404 然后触发清除,这是 libp2p 本身的设计决定的,这又会导致服务发现的错误率高;

在实际的部署中,Spegel 的缓存命中率在 25% 左右。

当然,使用 P2P 做服务发现也是有好处的,好处就是部署简单,不需要额外的存储依赖。只不过这个好处和它带来的问题相比就微不足道了。

我觉得如果解决服务发现的问题,使用 P2P 下载的方法,是可以解决资源的瓶颈问题的。

所以设计的方案是:使用中心化的,高性能的服务发现,去中心化的 P2P image 下载。

原本 Spegel 的代码,服务发现层是独立的模块,所以我从 fork 它的代码来添加一个新的服务发现方式开始。但是随着修改,发现问题越来越多,比如 subscribe containerd events 的时候没有正确 defer 关闭,没处理好 containerd 重启的情况,等等,最后开始了一个独立的仓库,叫 Piccolo。代码4依然是开源的,但是还没时间写文档和注释,这篇博客先写一下原理。

项目主要分两部分:

Pi – 安装在每台机器上的 daemonset,负责:

  • 作为 containerd 的本地 mirror,当 containerd 需要下载 image 的时候,会先尝试本地的 Pi 端口,如果得到 404 (或者 5xx),再尝试下一个下载 mirror,一般是 dragonfly,最后是 harbor source;
  • 连接本地的 containerd,跟踪本地的 image 状态,本地的 image 增加或者减少,报告给 Piccolo server;
  • 连接本地的 containerd,其他的 Pi 发送来下载 image 请求的时候,上传本地有的 image。

Piccolo Server 是服务发现的源,全局只有一组(几个实例就够用了),提供 3 个接口:

  • Advertise:其他 Pi 上报的 image 列表,存储到 MySQL;
  • Findkey:Pi 来询问一个 image(实际上是 image 的 manifest 和 blob)在哪里有的时候,回复地址列表;
  • Sync:其他 Pi 可以用这个接口做全量同步(定时,以保证 image 总是最终一致的);
Piccolo 的架构图

部署之后,97% 的下载请求可以在 Pi 完成而不必请求 Harbor。

Harbor 的流量对比,绿色的线是逐步发布 Piccolo 的流量,黄色线是之前的日常流量。

从这个监控可以看出,随着 Piccolo 的发布,Harbor 的流量骤降。而且每个小时的峰值流量也几乎没有了。

Pi 部署在每一个机器上,使用的资源也非常少,平均 CPU 用了一个 core 的不到 1%,可以忽略不计。平均内存用了 22M 左右,也可以忽略不计。

Piccolo 为集群提供了大约 8Tib 的下载带宽,没有消耗额外的资源,几乎是免费的 8Tib 带宽。

Piccolo server 方面,性能也很高,一台 8C8G 的 instance 足以支撑 5 万个 Pi (实际的物理机 worker 节点)。秘诀就是注重细节的性能优化。

比如全量同步的资源消耗较大,一起部署的机器会定时发送 keeplive,通过对这些定时执行的 API 加随机偏移,可以保持这些 API 的频率几乎是均匀的,解决了资源的峰值问题。

服务发现的核心,是用一张 MySQL 表,存储了 blob 和 IP 的对应关系。服务发现请求主要是通过这张表的查询完成的。Piccolo 支持把不同的 group(同一个 group 的 Pi 可以互相发现,不同的 group 的 Pi 不可以互相发现。其实这个功能也可以通过部署多个 Piccolo Server 来实现)放到不同的数据库中,加上索引优化(极致的索引优化,所有的查询都是 index-only 的),每一个库 2千万的数据,请求在 200 QPS,耗时在 10ms 以内,已经足够使用了。

Piccolo server 在服务发现接口返回的时候,会根据请求者的 IP 地址,把所有的资源拥有者的 IP,根据和请求者的 IP 相似度(距离)排序,返回。这样 Pi 在下载的时候,会从距离和它最近的邻居开始尝试,这样可以最大程度减少跨网络设备的带宽流量。

所有的 API 接口都有重试和指数时间退让,这样在大规模部署的时候,可以分散一些请求,不至于大家一起失败。

在高可用方面,由于 Piccolo server 是无状态的,所以部署多个实例即可。在预防未知的 bug 上,系统的每一个阶段都是可以降级的:

  • 如果 containerd 从 Pi 下载失败,会 fallback 到下一个下载源;
  • 如果 Pi 从一个 Pi 下载失败,会继续尝试下一个 Pi,直到超时;
  • 如果 Pi 访问 Piccolo 失败,会等待并重试,直到超时;

  1. 这里是之前 blog 过的一些技巧 Docker 镜像构建的一些技巧 ↩︎
  2. Spegel 镜像分发介绍,也讨论了一些其他的可能方案,比如 dragonfly,或者 lazy loading ↩︎
  3. https://en.wikipedia.org/wiki/Kademlia ↩︎
  4. Github 地址:https://github.com/laixintao/piccolo ↩︎
 

一起看电影

我和欣都很喜欢看电影,我们一起看了很多电影。我最喜欢的导演是韦斯·安得森,现在最喜欢的电影是《布达佩斯大饭店》,看了很多遍。欣最喜欢的电影是《沙丘》,也看了很多遍。科幻电影是我们共同喜欢的类型。

《布达佩斯大饭店》每一帧都很美,故事性也很强,台词简洁但是话又很多。和其他的电影很不一样,后来我才知道,这属于「艺术电影」的范畴。导演的个人特色太鲜明,有一次我在看《腓尼基计划》,欣看了一眼,就问,「这又是那个怪导演拍的?」

《沙丘》作为老牌科幻,背景世界构建的宏大而又符合逻辑,导演 Denis Villeneuve 实力很强,把这么难拍的电影也拍的像艺术一样。每一帧也都很美。

我们在一起看了很多电影。用过各种各样的设备和方法一起看。

高铁从上海到山东需要 5 个小时,看电影是最好的消磨时间的方法了。问题是,一直没有找到比较好的可以两个人一起看电影的方案。即两个人一起看,但是各自用自己的降噪耳机。

在网上找到了一个 Mac 可以使用的方法1,原理是用 Audio MIDI 创建一个新的输出设备,实际输出的物理设备是 2 个耳机,步骤如下:

  1. First, on your Mac, go to System Preferences > Bluetooth. Turn it on and pair the two pair of AirPods with your Mac. Now only one pair of AirPods can be connected.
    Now open Finder and click on Applications > Utilities > Audio MIDI Setup.
  2. Look for the plus sign and click on it to create multi-output device.
  3. Check the box next to the two pairs of AirPods and check the Drift Correction box next to the second pair of AirPods.
  4. Click on System Preference > Sound, followed by Multi-Output Device.
  5. Once done, the audio of your Mac will be sent to both pairs of AirPods. So this how to connect multiple AirPods to Mac.

有的时候不想拿出来 Mac,或者有时候没有带,就用下面这个万能的办法,不过仅适用于提前下载好的电影:

  1. 两个人的各自用个自己的设备(2个 ipad),以及各自的耳机观看;
  2. 调整进度条到同步的位置。

这样也算一起看了。

近几年大部分时间都是在家里一起看,买过 HBO,Amazon Prime,Disney+,Netflix 等等,在电视上看了不少电视和剧,简单也方便,体验很不错。《克拉克森的农场》,《Severance》,《浴血黑帮》,《大西洋帝国》,《For All Mankind》,等等。

去年买了一个新的电视,型号是三星的 S95F,可能是最近几年买过的最满意的电子产品了,OLED 屏幕非常惊艳,这一款还有一个不反光的特性,白天看也不用拉窗帘。最近又发现一个惊艳的功能。

有天家里有人睡觉了,我戴着耳机在客厅里看电视,欣过来问我,你看电视怎么没有声音?我说用的耳机。欣惊讶到,这电视居然能连接蓝牙耳机。我觉得这是很正常的功能。

于是她拿出来自己的耳机要和我一起看,我说不能连接两个耳机。她说可以,这是正常的功能。

我觉得肯定不行,因为之前用的所有的设备在不 hack 的情况下都不支持同时输出到 2 个蓝牙设备(实际上,iOS 在 2019 年好像就支持 audio share 了)。但是决定还是用事实证明。于是我打开蓝牙,连接上她的耳机。预期是之前连接的我的耳机会断开。结果两个耳机都连接成功。

然后打开声音输出,预期是只能选择一个耳机。结果电视自动弹出来对话框,问是否要切换到 multiconnect 功能?选择「是」之后,两个耳机都完美地有了声音。

三星的 dual audio 功能,不光可以输出声音到两个设备,屏幕居然也可以分割成两部分,同时看2个甚至多个节目。电视也支持虚拟化了。

后来一想,这个功能确实挺符合直觉并且实用的。现在的问题是,为什么之前那么多设备反而不支持?

  1. 详细教程:https://www.tenorshare.com/iphone-tips/how-to-connect-two-airpods-to-one-phone.html ↩︎