一年前半,我们迈出了第一步,踏上了这条充满狂野与激动人心的旅程。对于那些不了解内情的外人来说,云服务提供商的存在可能显得平淡无奇。然而,任何曾经不懈地寻找那个能够一劳永逸地解决问题的平台调整的人;任何曾经追踪过难以捉摸的“吞吐量之河”的人;任何曾经勇敢地与“多头蛇”——又称“裂缝”——搏斗的人,都会讲述一个截然不同的故事。
我们的世界充满了奇妙与冒险,没有什么是确定的,只有一个真理:使用私有网络接口,也称为私有 DNS,始终是最佳选择。至少我们曾经是这么认为的。
我们后来发现并非如此,但首先让我们回到过去……在虚拟化的曙光和云计算的时代到来之前,服务器是实体,是由零件组成的机器,它们协同工作以实现计算的目的。随着网络的诞生和发展,私有网络和公有网络之间形成了鲜明的界限。私有网络的特点是使用自己的地址空间,只能由直接连接到它们的服务器访问,并且通常是本地化的。公有网络顾名思义,是全球性的,任何人都可以访问。
网络之间的这种基本差异很好地反映了它们各自扮演的角色。公有网络用于向消费者提供系统的服务,而私有网络用于在系统内部连接组件服务器。此外,考虑到它们的性质和位置,私有网络通常被认为比公有网络更安全、更快、更便宜、更可靠,并且带宽更大。然后,服务器升天,变成了“云”。
在它们新发现的无形存在中,服务器抛弃了它们的物理属性,用虚拟化的替代品来代替。不再有服务器,取而代之的是实例。真正的 CPU 和内核消失了,取而代之的是计算单元和 vCPU。硬盘驱动器消失了,让位于瞬时存储和“网络连接的持久存储”。甚至网络接口也被剥夺了实体,取而代之的是“与实例关联的 IP 地址”。但我们仍然相信,私有 IP 地址更适合用于系统内通信,而且就是很酷。但随着时间的推移,经验告诉我们并非如此。
在开发和测试我们服务的过程中,我们花了无数个小时试图定义和复制一个特别恼人的幽灵。我们终于捕捉到了它,并了解到以下内容:AWS 的私有地址有时比公有地址更糟糕!
一旦确定,我们就能轻松且重复地展示这种行为。上面的图表是 实时 记录的表示,展示了一个简单应用程序连接到我们 Redis Cloud 实例之一所需的时间。该应用程序使用两个线程,一个连接到公有地址,另一个连接到私有地址。一旦建立了两个连接,应用程序就会将每个连接完成所需的时间写入该实例,然后重新启动。
请注意,在每次客户端重启后,连接到私有地址在大多数情况下比连接到公有地址花费更多时间,数量级上更多,而且很少与公有地址一样快。虽然这些症状很容易展示,但这种行为的原因却难以解释。我们怀疑这种不受欢迎的行为至少部分是由私有接口获得的额外保护造成的。由于 AWS 使用基于软件的防火墙来保护私有实例,因此前者可能会因为有太多规则需要执行而迅速不堪重负。这种负载并不一定是由某个特定的 EC2 实例产生的(在我们的测试中,我们使用了不到 10 个安全组),而是由 AWS 网络中共享同一个防火墙的许多 EC2 实例产生的。
一旦防火墙负载过重,它们可能会引入延迟,甚至阻止连接尝试。如上所示,这种现象在使用 PaaS 运行应用程序时可以可靠地重现。有趣的是,对于独立的 EC2 用户来说,这种情况要少得多。
因此,我们的结论和对 PaaS 用户的建议是避免使用私有接口,而使用公有接口——后者可能会引入高达毫秒级的延迟,但至少它的性能比前者更稳定。所以,这就是我们的结论,又一天过去了,又一个神话被打破了。