[转帖]websocket消息推送设计

websocket,消息,推送,设计 · 浏览次数 : 0

小编点评

**消息推送功能设计** **背景** 目前公司内的多个项目都有消息推送功能,实现分散式消息推送,与业务系统强耦合。 **特性** 1. **分布式消息推送:**消息中心是一个多节点集群部署,支持水平扩展,保证推送能力可用性。 2. **统一推送:**提供统一推送api供应用方调用,引入依赖,配置消息中心地址即可。 3. **性能优化:**使用mq进行异步处理,支持高并发。 4. **监控:**采用Prometheus+Grafana对推送服务的各项指标进行监控展示,并对异常进行报警。 **技术调研** * **web Socket:**是一种基于TCP的应用层协议,支持双向通信,服务器与客户端之间交换的数据包头信息很小。 * **Spring WebSocket:**是一个基于Spring框架的封装,可以简化WebSocket的开发。 * **Netty Socket.IO:**是一个基于Node.js的实时应用程序框架,支持多平台的WebSocket支持。 **整体设计** * 客户端向消息中心任一节点握手建立起WebSocket长连接,连接session保存在该节点的内存中。 * 当业务服务需要向客户端推送消息时,调用消息中心提供的api发送到消息中心。 * 消息中心收到需要推送的请求后,将消息发送到mq。 * 消息中心作为消费者,以广播模式消费消息,此时所有节点都会消费到消息。

正文

https://cloud.tencent.com/developer/article/2168088?areaSource=&traceId=

 

1. 背景

公司内目前有几个项目都有消息推送的功能,例如:某个业务操作之后需要推送消息给前端页面,让用户实时感知。

但是目前公司内的消息推送实现分散在在各个项目中,与业务系统强耦合,如果有其他项目需要集成消息推送功能,需要重复开发。故对消息推送功能进行公共抽取实现,提供一个通用的消息推送服务供各项目使用,减少重复开发,并且统一管控,做到降本增效。

消息推送是消息中心里重要的一环,会作为消息中心的一个模块进行设计开发实现。

主要定位是:致力于为公司各项目提供接入简单、可靠、安全稳定、快速实时推送服务。

2.特性

2.1 分布式

消息推送是消息中心里重要的一环,会作为消息中心的一个模块进行设计开发实现。

消息中心是多节点集群部署,支持水平扩展,保证推送能力可用性。

2.2 接入简便

消息中心提供统一推送api供应用方调用,引入依赖,配置消息中心地址即可。

2.3 统一实现

无需重复开发,统一消息推送技术栈,实现长连接管理和推送能力,便于功能迭代和维护,并作为基础技术能力沉淀。

2.4 解耦

业务系统和推送能力解耦,让业务方专注业务,不用关心推送实现细节。

2.5 监控

采用Prometheus+Grafana对推送服务的各项指标进行监控展示,并对异常进行报警。保证推送能力稳定性。

并且在线人数、连接数可观测。

2.6 可靠

提供心跳检测,及时重连和释放连接。保证消息不丢失,不重复推送,离线消息推送,消息补发。

2.7 并发

内部采用mq进行异步处理,支撑较高并发。

2.8 性能

内部采用forkjoin并发处理模型、缓存等手段避免耗时长的代码,提升推送效率。

3. 技术调研

下面主要介绍 web 端主要的四种消息推送方式。

3.1 短轮询

短轮询指的是前端页面每隔一定时间定时调用服务端的 HTTP 请求(如每1秒),之后由服务端返回最新的数据给前端页面。因为HTTP协议是一种无状态的、基于TCP的请求/响应模式的协议,请求只能由客户端发起然后服务端进行响应。

这种方式是实现最简单的。缺点是大部分请求是无效的,浪费了带宽和服务器资源。如果间隔很小,会对服务端造成比较大的压力。

3.2 长轮询

长轮询是前端页面向服务端发送一次 ajax 请求,服务端收到请求后保持连接,直到有新消息才返回响应并关闭连接,并且处理完响应信息后再向服务端发送新的请求

长轮询的优点很明显,在服务端没有消息的情况下不会频繁的请求,实现了服务端主动向前端推送的功能。但是服务端保持连接会消耗资源、返回数据顺序无保证、难于管理维护。(webQQ 就是使用了基于comet的长轮询技术)

3.3 Server-Sent Events

服务器发送事件是 HTML5 规范中提供的服务端事件 EventSource,浏览器在实现了该规范的前提下创建一个EventSource 连接后,便可收到服务端的发送的消息,实现一个单向通信。它类似于长轮询的机制,但是它在每一次的连接中,不只等待一次数据的更动。客户端发送一个请求到服务端 ,服务端保持这个请求直到一个新的消息准备好,将消息返回至客户端,此时不关闭连接,仍然保持它,供其它消息使用。

该方式的优点就是重复利用一个连接来处理每一个消息,缺点是只能服务端向客户端推送,并不是所有浏览器都支持。

3.4 WebSocket方案

webSocket 是 HTML5 下的一种新协议,是基于TCP的应用层协议,只需要一次连接,便可以实现全双工通信,即客户端和服务端可以相互主动发送消息。

该方式是目前服务端推送技术的主流方案,优点是双向通信,服务器与客户端之间交换的数据包头信息很小,缺点就是编码相对来说会多点,服务端处理更复杂。

最终决定采用 webSocket 方案来实现。然而websocket方式也有众多解决方案。

3.4.1 Java Websocket 规范

JavaEE 提供的规范,代码在包javax.websocket下,包含客户端 API 和服务端 API,服务端 API 完全依赖于客户端 API,只是在其基础上添加了一些功能,所以只需要导入服务端依赖即可。

优点:集成起来简单,原生的Java支持。

缺点:和 Web 服务器等共享容器耦合度高,广播、组播需要自行控制。并发量较低,调优麻烦,存在兼容性问题。

3.4.2 Spring Websocket

websocket 已经被springboot很好地集成封装了,所以在springboot上开发 websocket 服务非常方便。

该方案用到了还要用到SockJs+STOMP。

SockJS 是 WebSocket 技术的一种模拟。为了应对许多浏览器不支持WebSocket协议的问题,设计了备选SockJs。开启并使用SockJS后,它会优先选用Websocket协议作为传输协议,如果浏览器不支持Websocket协议,则会在其他方案中,选择一个较好的协议进行通讯。

STOMP是面向消息的简单文本协议。使用STOMP的好处在于,它完全就是一种消息队列模式,你可以使用生产者与消费者的思想来认识它,发送消息的是生产者,接收消息的是消费者。而消费者可以通过订阅不同的destination,来获得不同的推送消息,不需要开发人员去管理这些订阅与推送目的地之前的关系。

优点:性能良好,社区活跃,技术成熟,协议栈丰富,有全套 Spring 解决方案,兼容性强。

缺点:需要对 SockJS 和 STOMP 进行学习,断线重连、心跳检测、二进制支持不好,需要自行实现。

3.4.3 netty Socket.IO

[http://Socket.IO][http_Socket.IO] 基于 Node.js 的实时应用程序框架。虽然主流浏览器都已经支持WebSocket,但仍然可能有不兼容的情况,为了兼容所有浏览器,给程序员提供一致的编程体验。它将WebSocket、AJAX和其它的通信方式全部封装成了统一的通信接口,也就是说,使用SocketIO时不用担心兼容问题,底层会自动选用最佳的通信方式。而netty-socketio是一个开源的[http://Socket.io][http_Socket.io]服务器端的一个java的实现,它基于Netty框架,同时支持Websocket和长轮询。除了Websocket的常用场景外,可以通过该组件实现安卓和IOS的消息推送。

优点:性能良好,支持广播、组播,断线重连、心跳检测、二进制。支持安卓和 IOS 平台。

缺点:有一定的学习成本,需要自行封装同 Spring 的集成,资源消耗大。

3.4.4 ReactiveStream

一些反应流规范和框架也对Websocket进行了实现。Spring Webflux和RSocket就是其中的代表,目前官方已经放出了一些相关的 DEMO。

优点:高吞吐量、高性能。

缺点:技术比较新、学习资料少,学习成本高。

总结:之前的项目采用spring websocket实现,线上已经平稳运行一段时间。坑也踩的七七八八。决定采用spring websocket技术方案。

4.整体设计

 

  1. 客户端向消息中心任一节点握手建立起WebSocket长连接,连接session保存在该节点的内存中。此时客户端定时向服务端发送心跳消息,如果超过设定的时间仍没有收到心跳,则认为客户端与服务端的长连接已经断开,然后服务端会关闭连接并清理内存中的会话信息。
  2. 当业务服务需要向客户端推送消息时,调用消息中心提供的api发送到消息中心
  3. 消息中心收到需要推送的请求后,将消息发送到mq
  4. 消息中心作为消费者,以广播模式消费消息,此时所有节点都会消费到消息。
  5. 节点消费消息后判断推送目标对应的session是否保存在自己维护的内存中,如果不存在直接忽略,否则通过长连接推送数据

消息中心目前以双节点方式构成集群,每个节点负责一部分长连接,可以实现负载均衡,当连接数达到瓶颈时,也可以增加节点实现水平扩展。如果某一个节点出现宕机时,客户端通过心跳检测发现后会尝试重新与其他节点建立长连接,保证消息中心服务的可用性。

与[转帖]websocket消息推送设计相似的内容:

[转帖]websocket消息推送设计

https://cloud.tencent.com/developer/article/2168088?areaSource=&traceId= 1. 背景 公司内目前有几个项目都有消息推送的功能,例如:某个业务操作之后需要推送消息给前端页面,让用户实时感知。 但是目前公司内的消息推送实现分散在在各

[转帖]websocket的一点笔记

https://zhuanlan.zhihu.com/p/35568719 因为工作中没有用过websocket,所以对这个协议也不是很了解。但是网上经常看到这个协议,感觉不去了解一下,也不合适。 以前自己基础功不扎实的时候,我一直不知道所谓的网络协议到底是个什么意思?到底和TCP有什么区别?因为基

[转帖]Nginx支持WebSocket反向代理

https://www.cnblogs.com/zhengchunyuan/p/12923692.html WebSocket是目前比较成熟的技术了,WebSocket协议为创建客户端和服务器端需要实时双向通讯的webapp提供了一个选择。其为HTML5的一部分,WebSocket相较于原来开发这类

[转帖]Real-Time Web Applications with WebSocket and NGINX

https://www.nginx.com/blog/realtime-applications-nginx/ In the blog post NGINX as a WebSocket Proxy we discussed using NGINX to proxy WebSocket applic

[转帖]Nginx的热加载

https://www.zhihu.com/question/531861487/answer/2850763798 有websocket 时并不能立即生效.. 这段时间在 Reddit 看到一个讨论,为什么 NGINX 不支持热加载?乍看之下很反常识,作为世界第一大 Web 服务器,不支持热加载?

[转帖]

Linux ubuntu20.04 网络配置(图文教程) 因为我是刚装好的最小系统,所以很多东西都没有,在开始配置之前需要做下准备 环境准备 系统:ubuntu20.04网卡:双网卡 网卡一:供连接互联网使用网卡二:供连接内网使用(看情况,如果一张网卡足够,没必要做第二张网卡) 工具: net-to

[转帖]

https://cloud.tencent.com/developer/article/2168105?areaSource=104001.13&traceId=zcVNsKTUApF9rNJSkcCbB 前言 Redis作为高性能的内存数据库,在大数据量的情况下也会遇到性能瓶颈,日常开发中只有时刻

[转帖]ISV 、OSV、 SIG 概念

ISV 、OSV、 SIG 概念 2022-10-14 12:29530原创大杂烩 本文链接:https://www.cndba.cn/dave/article/108699 1. ISV: Independent Software Vendors “独立软件开发商”,特指专门从事软件的开发、生产、

[转帖]Redis 7 参数 修改 说明

2022-06-16 14:491800原创Redis 本文链接:https://www.cndba.cn/dave/article/108066 在之前的博客我们介绍了Redis 7 的安装和配置,如下: Linux 7.8 平台 Redis 7 安装并配置开机自启动 操作手册https://ww

[转帖]HTTPS中间人攻击原理

https://www.zhihu.com/people/bei-ji-85/posts 背景 前一段时间,公司北京地区上线了一个HTTPS防火墙,用来监听HTTPS流量。防火墙上线之前,邮件通知给管理层,我从我老大那里听说这个事情的时候,说这个有风险,然后意外地发现,很多人原来都不知道HTTPS防