AnyCable Goes Pro:为Ruby提供快速的WebSockets,规模庞大

148 阅读6分钟

作者。 Vladimir Dementyev, Evil Martians的首席后端工程师

AnyCable的1.0版本发布一年后,我们推出了专业版本。它为我们的高性能和可扩展的实时配方添加了特殊成分,保留了熟悉的Rails Action Cable API,用于全双工消息传递,并为WebSocket连接提供了极快的Go服务器支持。使用专业版可以将你的内存占用率降低40%,节省带宽成本,并获得优先支持。在测试阶段,这一切都是免费的。

AnyCable的核心一直是并且将一直是一个开源项目。半年前,它从一个单一的库开始,发展成为目前GitHub组织下的一个工具家族。然而,随着AnyCable在Rails和Ruby生态系统中不断获得牵引力,在开发新功能的同时保持所有工具的更新不再是一种爱好,而是变成了一个独立的企业,只有通过适当的支持机制才能受益。

由于AnyCable的设计是为了缓解那些依赖于与成千上万的始终连接的客户进行实时、全双工通信的应用程序的成长之痛,它的采用者往往是在大联盟中打拼。他们的需求往往超过了社区驱动的开源开发的悠闲节奏。虽然AnyCable背后的核心代码将始终保持免费、开源,并对社区公关开放,但我们将在上面增加商业功能,以帮助专业用户达到更大的规模。

我们将在现有代码库的基础上增加专业的商业功能,以帮助客户处理额外的高负荷。

如果你还不熟悉AnyCable,请花时间阅读原始的介绍性文章,其中描述了架构和开放核心的性能特点。请务必保持当前标签打开,回来了解全新的商业特性。

在这篇文章中,我们将重点介绍AnyCable Pro的三个方面:内存占用,对二进制协议的支持,以及毫不费力的GraphQL兼容性。

更有效的内存使用

Rails开发者选择AnyCable而不是内置的Action Cable的主要原因之一是大量减少内存成本。

AnyCable的Go服务器使用的内存比Action Cable的默认后端少3倍。尽管如此,我们还是发现了更大的改进空间--当客户端主要作为消费者而不是生产者的时候(发送到服务器的消息数量比服务器广播到客户端的消息数量少得多)。想想你的 "社交媒体 "实时通知系统。

对于专业版,我们重写了底层的客户-服务器通信机制,从万无一失的 "每个连接两个goroutines "到更细致的 "goroutines池加epoll/kqueue "技术,这给我们带来了进一步的提升。

AnyCable Pro vs. AnyCable vs. Action Cable memory usage handling 20k idle clients

处理2万个空闲连接

对于非空闲连接,差异不那么明显,但仍然很明显。

AnyCable Pro vs. AnyCable vs. Action Cable memory usage running broadcast benchmark for 5k clients

运行5k连接的广播基准测试

这一改进对于容器化或其他封闭式部署(Kubernetes、Heroku)特别有用,在那里你更愿意通过添加新的小实例来扩展,而不是升级到更强大和昂贵的 "机器"。以下是在单一的Heroku 1X动态器上对不同的AnyCable版本与Action Cable进行基准测试的结果。

AnyCable Pro vs. AnyCable vs. Action Cable memory usage handling 9k idle clients on Heroku

在Heroku 1X dyno上处理9k空闲连接

我们已经将处理连接所需的实用内存量从O(N)减少到O(1),但我们仍然需要保持客户端状态--因此整体内存增长仍然是线性的。我们计划在未来的Pro版本中对状态的减少和压缩做更多的工作。

对二进制协议的支持

Action Cable协议在客户端与服务器通信期间在WebSocket消息中使用JSON有效载荷。JSON是一种简单的、人类可读(和可写)的格式;程序员喜欢它。然而,机器更擅长消化人类无法阅读的二进制格式:它们更紧凑,处理速度更快。

AnyCable Pro增加了对两种最流行的二进制格式的支持。Msgpack和Protocol Buffers。

使用二进制通信大大减少了网络上发送的数据量。你可以在AnyCable Pro的文档中找到一些数字。例如,请看Websocket Shootout基准测试期间发出数据的差异(5k连接,1.5m消息)。

Protobuf vs. Msgpack vs. JSON

带宽比较

目前,采用二进制协议需要对客户端JavaScript库进行猴子式修补。这种方法运行良好,但我们已经开始实施我们自己的AnyCable JS SDK,这将使我们在未来更容易引入协议级功能。敬请期待!

不费吹灰之力的Apollo GraphQL兼容性

最后但并非最不重要,我们将展示Apollo GraphQL协议支持。

目前,使用GraphQL订阅与 graphql-ruby后台和Action Cable作为传输,需要使用一个自定义的Apollo "链接"。然而,这种方法有几个问题。首先,大多数以GraphQL开发者经验为目标的开发者工具对Action Cable没有任何概念,但却支持极其流行的Apollo,而且是开箱即用。其次,为Apollo找到一个有效的、最新的客户端库要容易得多(例如,React Native并没有正式提供Action Cable库)。

有了AnyCable Pro,你可以享受到Apollo的所有工具,而无需在客户端代码中提及Action Cable!你只需将你的WebSocket传输器与Apollo的GraphQL协议连接起来。只需将你的WebSocket传输连接到<anycable-pro-go>/graphql 端点,就可以了。AnyCable将传入的Apollo消息翻译成相应的Action Cable动作,反之亦然。

例如,你可以在Apollo Studio中使用订阅。

阿波罗工作室遇到AnyCable

使用Apollo Studio与AnyCable

早期访问计划

我们只是在AnyCable进入商业开源的新的和令人兴奋的旅程的最开始,我们渴望与你分享我们到目前为止建立的一切--在功能仍处于测试阶段时,不收取任何费用。

在这里注册AnyCable Pro免费早期访问计划,成为第一个尝试新功能的人。

我们正在启动一个早期访问计划:在联系表格中给我们留言,告诉我们你对AnyCable的使用情况以及你想解决的电缆问题--我们会让你提前免费访问专业版2个月!你也可以期待我的优先支持。你也可以期待我和这个项目背后的火星人的优先支持。