请选择 进入手机版 | 继续访问电脑版

默认
打赏 发表评论 1
一个基于长连接的安全可扩展的订阅/推送服务实现思路

1、导语


提起设计一个基于 HTTP/WebSocket 的长连接订阅/推送服务,大家马上能想到市面的不少开源产品,像 Socket.io、Faye 等产品已经提供了相当成熟的实现(有关Socket.io的文章请见《Socket.IO介绍:支持WebSocket、用于WEB端的即时通讯的框架)。但是,这类服务出于其通用性和方便上手考虑,往往只包含推送服务的基本模型。

但是当我们将其应用于具体业务时,会发现还是有以下问题需要解决:

  • 如何保证连接的业务安全(禁止非业务认证的连接订阅消息);
  • 如何扩展能够支持更多的消息和连接。

本文将从以上两点展开分析。

2、更多资料


[1] 有关推送技术的文章:
iOS的推送服务APNs详解:设计思路、技术原理及缺陷等
Android端消息推送总结:实现原理、心跳保活、遇到的问题等
扫盲贴:认识MQTT通信协议
一个基于MQTT通信协议的完整Android推送Demo
IBM技术经理访谈:MQTT协议的制定历程、发展现状等
求教android消息推送:GCM、XMPP、MQTT三种方案的优劣
移动端实时消息推送技术浅析
扫盲贴:浅谈iOS和Android后台实时消息推送的原理和区别
绝对干货:基于Netty实现海量接入的推送服务技术要点
移动端IM实践:谷歌消息推送服务(GCM)研究(来自微信)
为何微信、QQ这样的IM工具不使用GCM服务推送消息?
极光推送系统大规模高并发架构的技术实践分享
从HTTP到MQTT:一个基于位置服务的APP数据通信实践概述
魅族2500万长连接的实时消息推送架构的技术实践分享
专访魅族架构师:海量长连接的实时消息推送系统的心得体会
深入的聊聊Android消息推送这件小事
基于WebSocket实现Hybrid移动应用的消息推送实践(含代码示例)
>> 更多同类文章 ……

[2] 有关WEB端即时通讯开发:
新手入门贴:史上最全Web端即时通讯技术原理详解
WebSocket详解(一):初步认识WebSocket技术
WebSocket详解(二):技术原理、代码演示和应用案例
WebSocket详解(三):深入WebSocket通信协议细节
Web端即时通讯技术盘点:短轮询、Comet、Websocket、SSE
SSE技术详解:一种全新的HTML5服务器推送事件技术
Comet技术详解:基于HTTP长连接的Web端实时通信技术
socket.io实现消息推送的一点实践及思路
LinkedIn的Web端即时通讯实践:实现单机几十万条长连接
Web端即时通讯技术的发展与WebSocket、Socket.io的技术实践
>> 更多同类文章 ……

3、订阅/推送模型


首先,我们先来铺垫背景,一个简单的订阅推送模型应该是什么样的呢?

客户端订阅指定的主题(Topic),生产者将消息推送到该主题时,所有订阅主题的客户端都将收到该消息。很简单对吧?对,基于这个简单的模型,我们开始着手解决问题。

1.png

客户端订阅指定的主题(Topic),生产者将消息推送到该主题时,所有订阅主题的客户端都将收到该消息。很简单对吧?对,基于这个简单的模型,我们开始着手解决问题。

4、建立安全的业务连接


我们总是希望,当连接者对主题有查看权限时,才能订阅主题,否则应该拒绝其连接。如何实现呢,我们先介绍第一种实现方式。

5、临时的通道


我们引入一个新的概念:通道(Channel)。通道是一种临时的订阅凭证,只有内部服务才允许创建,并且会在一段时间后失效。为了让订阅更有效率,同一个通道将可以绑定多个主题。

假设,我们拥有有业务的鉴权服务器。鉴权服务器负责验证访问者对主题的权限,并且向订阅/推送服务请求创建通道。整个模型是下图这样的:

2.jpeg

这里有一点需要注意,通道是有被伪造的可能性。通道标识的随机和通道有限的使用时间,都可以极大地减少了通道被伪造的风险。

6、搭建网关过滤


除了使用临时通道,我们还可以通过引入网关(Gate)来创建安全连接。网关不同于通道,可以在连接建立之前(逻辑上的连接而非指 TCP 连接),对连接进行处理。比如,在订阅主题之前,验证是否有权限。

在上述的场景下,我们可以在网关拦截订阅请求,转发到鉴权服务器,得到确认答复后才订阅主题。网关模型如下图:

3.jpeg

7、模型对比


两种设计模型都能实现业务的安全连接,作用于不同流程,各有利弊:

  • 通道模型相对复杂,需要推送服务维护更多的对象,处理更加复杂的应用场景,而网关模型就相对简单得多;
  • 接入多个业务时,网关模型需要维护不同业务的不同鉴权方式,增加了推送服务与其他业务的耦合度,而通道模型总是能保持自身服务的独立性。

8、实现服务的扩展


我们来思考第二个问题。当网站的用户越来越多时,当需要订阅的主题越来越大量时,对稳定性有着更高的要求时,单一节点就已经无法提供有效的服务。这时,我们就需要分布式的推送系统,应该如何设计呢?

我们将订阅与推送看成两个不同的模块。订阅端有天然的可分布性,我们可以很容易地将连接分发到集群的不同的节点(通过负载均衡服务就可以实现)。这样一来,推送端就需要关心:本次推送的主题都有哪些节点订阅了。所以,我们需要引入一个负责调度的网关。

当客户端订阅主题时,需要通知网关,哪个节点订阅了哪个主题。推送时,消息会经过网关,由网关负责分发到对应节点。整体的设计模型如下:

4.jpeg

9、故障转移


分布式系统不仅需要高扩展性,同时还需要保证服务的高可用。当某个节点发生故障时,我们需要保证提供的推送服务不被中断。如何设计呢?我们还是区分订阅端和推送端来设计。

当节点故障时,订阅端的连接会断开,这时只需要客户端支持断开重连机制。一般的负载均衡服务都会提供心跳检查,自动摘除后端不可用的节点,重连的订阅会被分配到新的可用节点上。

这时,网关会收到有新的节点订阅了主题,而故障的节点发生了什么,网关并不知情(进程异常退出或者服务器网络中断通常无法发出通知)。当有消息需要推送到故障节点时,网关会发觉节点出现故障。这时,需要标记该节点状态为异常:
5.jpeg

故障恢复后,节点会重新加入到负载均衡器的后端。当有新的订阅到来时,节点会通知网关,这时,网关可以标记该节点状态为正常:
6.jpeg

10、本文结语


至此,一个分布式的订阅/推送系统算是初具雏形了。然而系统设计并非一蹴而就,在不断迭代完善系统的过程中还会面临各种各样的问题。其中关于技术选型,客户端连接分发等等细节,还有不少值得研究,我会在将来单开话题探讨分享。

(原文链接:点此进入

即时通讯网 - 即时通讯开发者社区! 来源: - 即时通讯开发者社区!

上一篇:基于WebSocket实现Hybrid移动应用的消息推送实践(含代码示例)下一篇:实践分享:如何构建一套高可用的移动端消息推送系统?

本帖已收录至以下技术专辑

推荐方案
评论 1
文中的实现思路偏理论化,稍欠说服力,但有一定的参考价值
签名: 国庆长假还没有缓过来,请让我静一静,产品狗死远点...
打赏楼主 ×
使用微信打赏! 使用支付宝打赏!

返回顶部