石墨文档是如何通过websocket实现百万长连接的?(代码片段)

程序员成长指北 程序员成长指北     2022-11-28     743

关键词:


标准定义的 WebSocket 规范。

随着石墨文档的发展,现在日连接峰值达到了百万量级,日益增长的用户连接数和停止更新的架构设计导致了内存和 CPU 使用量急剧增长,因此我们考虑对网关进行重构,以适应发展需求。

基于 Socket.IO 进行修改开发的版本,很好的满足了当时用户量级下的业务场景需求。

内存的硬件条件下,单机 50w 连接数,进行以上包括用户上下线、消息回执等四个场景的压测,内存和 CPU 消耗都符合预期,并且在较长时间的压测下,服务也很稳定。满足目前量级下的资源节约要求,可在此基础上继续完善功能开发。

存在的价值是 Kafka 的消费者需要根据 socketID 找到对应的tcp 链接,既然你们已经有了自定义网关,那么引入 kafka 的意义是什么?消息的持久化?为什么不在网关层做负载均衡,让节点直接跟客户端通信。另外我猜测消费发送者需要根据 socketId 做 hash 然后发送到对应的 partition,一旦初始 partition 过小,进行扩容时,客户端和服务端都得进行重启或则升级,不知道引入 kafka 的意义在哪里,相反还极大的增加了架构的复杂度和维护成本,扩展性也没那么好,如果是 http 短链接还能理解。

回答:图中没画出 SLB,是有负载均衡的。我们没有采用 socket id hash 到对应 partition,kafka 的作用是在处理网关内部的不需要关心顺序和推送消息的流转,如果没有kafka,那么组件或者网关滚动更新,用户重连的过程中,就可能丢消息;对于需要顺序的消息,例如 ping pong 模式的是可以通过网关识别到 header 头里的 cmd 信息,找到对应后端,分发消息。

左右,业务场景简单固定,并且要兼容历史业务逻辑,最后选择了 Redis 进行消息广播。api 与网关交互不是通过 kafka 吗,这里是什么意思呢?

回答:网关节点对 kafka 的消费是集群模式。如果 kafka,在 k8s 条件下,使用广播模式比较麻烦。所以老的网关是用 redispub/sub 的广播,为了兼容老的逻辑仍然采用 redis 做广播。同时后续我们打算直接将 apiws 做两两互联,通过 grpc stream 做广播,有更好的扩展性。

7 技术链接

  • 微服务框架:https://github.com/gotomicro/ego
  • Kafka、Redis、MySQL 客户端监控 SDK:https://github.com/gotomicro/ego-component
  • Node 社群


    我组建了一个氛围特别好的 Node.js 社群,里面有很多 Node.js小伙伴,如果你对Node.js学习感兴趣的话(后续有计划也可以),我们可以一起进行Node.js相关的交流、学习、共建。下方加 考拉 好友回复「Node」即可。


    如果你觉得这篇内容对你有帮助,我想请你帮我2个小忙:

    1. 点个「在看」,让更多人也能看到这篇文章
    2. 订阅官方博客 www.inode.club 让我们一起成长

    点赞和在看就是最大的支持❤️

    php如何实现websocket

    php有可用的websocket库,不需要php-fpm。目前比较成熟的有swoole(swoole.com),和workman(workman.net)swoole是c写的php扩展,效率比nodejs还要高,workman是纯php实现,两者都号称可以实现并发百万TCP连接。给你个例子:这个要通过cmd运行... 查看详情

    javanettynio如何突破65536个端口的限制?如何做到10万~50万长连接?

    现在看了很多帖子都在说java的nettynio实现长连接server可以做到在一个jvm上保持10万~50万的长连接。小弟java新手,对tcp编程了解一丢丢,我的知识范围告诉我,一个进程在linux上能打开的文件句柄数是有限的,因为内核用16位的short... 查看详情

    前端即时通信是怎么开发的?

    前端即时通信可以通过WebSocket协议进行实现。以下是一些开发的步骤:了解WebSocket协议:WebSocket是一种持久化的协议,它建立在HTTP协议基础上。在WebSocket连接建立后,服务器和客户端之间可以互相发送和接收数据,而无需进行... 查看详情

    springboot配置websocket

    ...于比较时效性(如聊天)或者需要推送的场景就可以使用WebSocket来实现,服务端不再是等待客户端的请求而可以主动推送消息给客户端。同时也减少了资源的开销,因为之前通过HTTP的做法通常都是轮询来实现时效性,这种做法... 查看详情

    如何从 mongoDB 读取文档并通过 java 中的 websockets 发送文档?

    】如何从mongoDB读取文档并通过java中的websockets发送文档?【英文标题】:HowtoreaddocumentsfrommongoDBandsendthedocumentsoverwebsocketsinjava?【发布时间】:2017-08-2911:24:41【问题描述】:我是java新手,想从mongoDB集合中读取随机数据,并通过webs... 查看详情

    java是如何实现客服在线聊天功能的?

    ...候,需要考虑客户端和服务端之间的通信协议。可以使用WebSocket协议,这是一种全双工通信协议,支持客户端和服务端之间的实时通信。Java提供了多个WebSocket实现,比如Tyrus、Jetty和Netty。实现服务端:在服务端实现在线聊天功... 查看详情

    通过websocket编程实现服务器和客户端长连接

    ...器间的请求响应一次,下一次会重新创建连接.2)实现基于webSocket的长连接的全双工的交互3)改变Http协议多次请求的约束,实现长连接了,服务器可以发送消息给浏览器4)客户端浏览器和服务器端会相互感知,比如服务器关闭了,... 查看详情

    websocket长连接接入支付宝消息服务,实现消息通知

    ...付宝的回调通知结果,才能处理业务逻辑。此文介绍通过WebSocket长连接接入支付宝消息服务,实现消息通知。包括五部分内容:问题、优势、配置、代码接入、总结。问题比如接入互联网平台直付通二级商户进件时,需要知道这... 查看详情

    如何通过Controller连接WebSocket?

    】如何通过Controller连接WebSocket?【英文标题】:HowtoconnecttoWebSocketthroughController?【发布时间】:2021-05-3105:44:39【问题描述】:我正在尝试使用Postman通过Controller连接到WebSocket,但isSocketRequest一直为false,我错过了什么?publicclassWeb... 查看详情

    石墨文档的云端表格实时压缩策略

    多人实时协作是石墨文档吸引人的一大特性之一。使用石墨文档,你可以和同事、朋友同时编写一篇文档或表格,每个人的修改都会实时的同步给其他人。你可以看到每个人光标的跳动,每一个键入的文字。一篇篇运营文案、一... 查看详情

    如何配置 WebSocket 服务器以接受安全连接请求

    】如何配置WebSocket服务器以接受安全连接请求【英文标题】:HowtoConfigureWebSocketServertoAcceptSecureConnectionRequest【发布时间】:2019-03-1107:51:43【问题描述】:在应用ssl(我从cloudflare获取)之前,我的网站是通过http加载的,我的套接... 查看详情

    微服务过时了-serverless了解一下|技术专题第七期征文

    一、2020年的服务端革命你知道吗我们天天使用的石墨文档、微博、芒果TV都在全部或部分使用Serverless技术。其实知乎也是用的leancloud。技术的发展使我们有可能不花一分钱、不雇佣一个只强大的后端团队也可以建立一个媲美大... 查看详情

    websocket的简单实现

    参考技术AWebSocket协议是基于TCP的一种新的网络协议。浏览器通信通常是基于HTTP协议,为什么还需要另一个协议?因为http只能由客户端发起,不能由服务端发起。而WebSocket浏览器和服务器只需要完成一次握手,两者之间就直接可... 查看详情

    WebSocket如何保持连接

    】WebSocket如何保持连接【英文标题】:HowdoWebSocketkeepconnection【发布时间】:2012-11-1615:04:12【问题描述】:上面写着websocket"使用ws通过单个TCP套接字进行通信(不安全)或wss(安全)协议..."这是否意味着客户端-服务器只需要一次... 查看详情

    如何使用 Django 连接和实现 websocket?

    】如何使用Django连接和实现websocket?【英文标题】:HowcanIconnectandimplementwebsocketswithDjango?【发布时间】:2017-09-2123:50:46【问题描述】:我想在我的项目中使用websockets,但我不知道我需要做什么。我使用django作为后端。我怎么能把... 查看详情

    如何清理石墨耳语的数据?

    】如何清理石墨耳语的数据?【英文标题】:Howtocleanupthegraphitewhisper\'sdata?【发布时间】:2012-03-2403:15:29【问题描述】:我想删除石墨的存储耳语数据,但石墨文档中没有任何内容。我做的一种方法是手动删除/opt/graphite...../whispe... 查看详情

    如何将 websocket 连接解码为 json 流?

    】如何将websocket连接解码为json流?【英文标题】:Howtodecodewebsocketconnectasajsonstream?【发布时间】:2017-11-2801:30:04【问题描述】:我的客户端正在连接到websocket服务器,并且通信都是json格式。我使用ClientWebSocket及其ReceiveAsync方法... 查看详情

    如何通过查询字符串轻松实现连接

    ...请求来确定是否填充了外键(即外键_id属性被替换为整个文档或部分来自另一个集合的文档)。我知道我可以发送类似的东西?populate=CollectionNam 查看详情