消息系统介绍及选型依据

 

消息系统介绍及选型依据

消息系统目前已经广泛使用于互联网企业,各类业务系统都有它的身影,一方面是其传统的功能特点:系统间调用的异步解耦,减低系统的复杂度、流量的削峰填谷,便于业务弹性伸缩、易于实现最终一致性系统,避免分布式事务对性能的影响、支持P2P(点对点的调用)和pub/sub模式减少RPC的多次调用(广播通知机制)等。另外随着业务的快速增长,企业内部需要大量数据的同步传输,流式计算等应用都需要非常稳定高效的传输通道给予支持,消息系统在其中充当了重要的角色。

目前使用较为广泛的消息中间件(MOM)主要有:rabbitmq、kafka、RocketMQ(MetaQ)、ActiveMQ或ZeorMQ等产品;

 

1.        系统功能介绍

 

n  消息系统对企业异构系统集成有着重要的使用场景,各系统遵循协商的数据规范进行生成和消费消息,系统间通讯从传统RPC服务接口调用方式转换到数据协议的通讯方式,使得系统耦合度降低,责任边界更明确,同时有利于系统升级发布,可持续集成部署;

n  消息通知机制使得系统异步处理变得简单,同步调用需要阻塞当前线程等待结果返回,会影响系统的并发能力;而消息通知方式是由上游业务将请求转化为消息的形式发往消息中间件(MOM)即可返回,无需等待后续业务处理,下游获取消息后异步的处理后续逻辑。

n  业务流量的削峰填谷;传统RPC同步调用(PUSH模型)在应对突增性流量时,一般采用扩容/降级/熔断等机制来保护下游核心服务的正常运行; 而消息系统在调用中间层增加了一道缓冲机制,暴增流量发生时,通过消息积压的方式存储在broker中,下游服务根据自身处理能力,量力而行的拉取消息进行消费,不会给后续服务带来毁灭性冲击;

n  消息系统易于业务实现最终一致性场景;传统的强一致性的事务,一般通过二阶段或三阶段提交方式来实现,但是性能较差容易造成性能瓶颈;通过消息系统的消息通知机制和补偿手段来达到分布式系统的数据一致,很大程度上改善了系统性能和吞吐能力;

n  支持P2P和pub/sub模型;点到点的调用类似RPC的行为;另外一种是广播机制,比如缓存通知,需要更新所有本地缓存;RPC的方式实现,每接入一个新业务方需要调一次方法,难以动态接入和灵活性较差;消息系统绝大多数支持广播的方式,极大简化业务逻辑处理和提供灵活接入的能力;

n  快速数据传输,为在线流式计算提供可靠的数据通道。分布式环境中各类异构数据源分散杂糅,高效快速的归集数据,并为实时数据分析模型高效地传导数据,对现代互联网企业有着至关重要的作用。

 

2.        核心技术剖析

1.        消息协议支持

消息协议分为即时通信协议和延迟通讯协议;

Ø  即时通信协议常用于RPC通信系统,端到端的进行传输采用push的方式,发送方需立即得到消费方的响应;如RMI,Thrift,Avro等协议;

Ø  延迟类通讯协议,消息一般经由中间层broker存储后,当条件满足时再分发至消费端;常见通信协议如:xmpp, stomp, mqtt, amqp或 binary私有协议;消息中间件采用的便属于此类延迟性协议;

xmpp, stomp, mqtt, amqp属于标准化通讯协议,被广泛使用在消息中间件设计之中,这类标准协议通常基于消息的状态机模型而设计,消息投递过程中的各种状态都从协议层面进行了精心设计和可靠性处理,有的协议在可靠性方面设计过于复杂,冗余信息也多,交互频率高,性能上会有大量损耗;因此在追求高性能大并发的消息系统中,也常见采用私有协议来进行交互,尽管在扩展性和灵活性上有所下降,但协议设计更紧凑,通信负载更轻量级;比如kafka或rocketmq等消息系统均采用自定义协议来进行设计;

2.        通信系统设计

消息系统处于星型调用关系的中间节点,起着承上启下的关键作用;如何支持单节点达到高的连接数(cps)和高的吞吐量(qps)对通讯层的设计有很高的要求;常常从以下角度来进行考虑:

Ø  建立TCP长链接,减少频繁握手的开销;

Ø  链路空闲(idle)和检活(heartbeat)处理, 回收空闲和非活的链接资源;

Ø  多路复用及非阻塞IO方式提高单链接多通道的通讯方式;

Ø  io线程池隔离机制,io线程只负责req/resp的读写,各类业务线程池进行隔离避免重业务逻辑的资源池复用;

Ø  通讯协议设计,比如选用protocolbuf或者私有协议以降低包体大小;

Ø  对请求进行合并和批量发送的方式;

Ø  基于jvm的设计时,减少堆内存回收对网络io的影响,比如采用zero-copy的方式避免堆内存的申请;

Ø  具体实现上可选择netty框架(java语言)降低开发的复杂度。

3.        存储系统设计

存储系统需要考虑:

Ø  消息物理存储格式设计

优秀的存储格式的设计,一方面节省存储资源,比如利用位域存储来实现字节的复用,利用族群分块和相对位移/增量存储降低存储开销;另一方面,存储格式的边界对齐考虑也有利于高效的读写性能;

同时要考虑数据的完整性检查,各类索引的创建以及如何快速检索定位消息;

Ø  消息存储介质选择

n  日志文件存储方式

选择日志文件来持久化消息,需要考虑:

1.      如何保证高效的读写性能:比如写时采用AOF方式进行记录;利用os的pagecache来改善磁盘访问性能和安全性;

2.      日志文件的保留策略,磁盘是有限资源如何管理和制定妥善的清除策略对存储系统尤为关键;

3.      异常退出,通过日志的如何快速恢复系统;

4.      队列一般是无限长度的空间,需设计好与有限的存储文件之间的映射;

5.      不同业务队列采用单一的事务日志进行存储,还是不同业务采用物理隔离的日志进行存储;两种存储方式在不同的业务场景下各有优势,在不同的开源产品中也都有采用;

n  数据库存储的方式

采用数据库存储一般源于多维度查询的需求和长久保存消息方便消息审计的目的,利用数据库自身的索引机制给消息的检索带来便利;但需要解决数据库性能吞吐,数据库具有强事务性特点,系统开销会比较大;

 

4.        路由策略机制

消息路由是消息系统的核心内容,包括路由元数据管理和消息数据分发策略的实现;

l  元数据管理:用以描述消息队列的物理存储地址,容量大小,分片情况;

l  消息分发策略:根据消息的路由键和系统的路由元数据,通过不同的路由策略算法计算获取落盘的具体物理地址;发送和消费可以共用相同的路由元数据,采用不同的路由算法机制,以达到各类消费的目的;

具体实现方式:有的路由策略放在server端实现;有的通过客户端来实现;

例如:

rabbitmq的路由逻辑放在服务端来实现;通过声明exchange和queue的绑定关系来确定路由情况,支持比较丰富的路由策略,direct/topic/fanout/header等方式以满足不同的业务需求,可以满足绝大部分的应用场景,不支持用户自定义策略;

         kafka的路由逻辑在客户端实现;客户端会定时和特定情形下主动拉取路由元数据,通过客户端的路由算法来确定消息的存储地址并创建tcp链接与存储broker进行通信;路由算法在客户端有缺省实现同时支持用户实现接口的方式进行自定义,提供灵活的配置方案和动态调节能力;

 

5.        负载均衡策略

负载均衡对分布式应用的稳定运行有极其重要的意义,如何防范流量不均衡导致集群雪崩效应的发生,又或是负载的不平衡造成系统的瓶颈,不能发挥最大的效能;请求负载能否自动化调节或是人工管理的方式进行灵活的分配调整,对系统健康度有着积极的作用,同样负载均衡对消息系统设计亦是如此。

 

负载均衡的设计,可以从客户端和服务端两方面来考虑:

如4中所言的路由策略,在一定意义上可以实现负载的平衡调节,不同的路由策略可以让流量进入到不同的集群节点进行处理;客户端通过调节路由算法来达到系统负载平衡;

随着集群不断的扩容,资源分布不均衡性逐步显现,资源分布如何动态进行迁移显的尤为关键, 服务端提供出灵活的监控和管理策略来调节节点资源分配就很有必要;比如多副本资源如何协调好leader节点在集群中的分配,对系统吞吐能力有很大的影响。

负载均衡策略在各个子系统中都需要进行细致设计和考虑,以充分发挥单节点和集群的整体性能。

 

6.        HA高可用设计

系统高可用从技术和业务层面都需要进行考量;

比如:日志副本的复制/同步管理,采用怎样的同步机制能保证节点失效时能快速切换到新的副本节点继续提供服务;同时保证数据在多副本之间的一致性,以保障消息不丢;这里涉及到两个方面的问题:

1. Leader节点的选举机制;

2. 副本的同步机制,如何保证副本的一致性;

针对以上问题,目前有多种一致性协议来处理,如paxos,raft,pacificA以及私有同步协议来解决副本的一致性问题;协议目的是要解决以上2个重要问题,实现时有很多安全机制需要考虑去解决各类异常情形,比如网络分区,出现慢设备,网络抖动,反复选举,日志回滚安全机制等等问题;

 

同时业务层面采用ack机制去保证业务正常被处理;发送时如何保证消息安全被传输和存储;消费时如何保证业务正确被执行,失败时如何进行重试,并最终提供安全的ack方式;这些都需要在设计上提供友好的处理方式。

 

7.        流量控制设计

消息系统承载着众多的业务数据,各业务重要程度不同,业务流量各异,遇到突增流量,对集群造成风险时;集群需在流量管理上进行流控处理以防止服务宕机,常采用阈值判断的方式来禁止请求进入;

比如:在网络io层或者业务reqest分发层来进行控制,采用blockingqueue的rejected策略,当内部业务线程处理延迟时,请求队列已经塞满的情况下,采取拒绝外部新请求来保证核心逻辑处理;

另外针对不同链接做细粒度的流量控制,对不同的业务流量采取有区别的控制方式,例如kafka根据clientid来区分具体客户端实例进行流量的细粒度控制;

除了server端的流量控制之外,也可在客户端进行流量监控和并发流量控制;客户端的流量在大促期间很容易出现流量尖刺,控制这些流量峰值对系统稳定性非常有价值,如何消除尖峰平稳流量,常常通过拥塞窗口的方式来进行控制,比如利用信号量来控制并发线程的网络io等等方式。

 

8.        安全认证和传输安全设计

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值