消息中间件对目前大中型互联网来讲是很是重要的,在业务数据流动中仅次于RPC服务调用,担负着愈来愈复杂的网站业务从主流程上解耦的重要责任;
从目前互联网对消息中间件的需求来看应该分为两种类型,一种是和钱相关的需求,一种是和钱无关的需求;和钱相关的需求消息的可靠性是放在第一位的,和钱无关的需求是速度放在第一位的,但这两种需求又是矛盾的,很难设计出一种既可靠又高效的系统,除非将两套方案捏合成一个系统,经过配置来选择不一样方案,但从实现上说仍是两种实现。因此目前业界有几种不一样的设计方式来知足不一样的需求。
下面看看如下几种典型实现方案:
一、以ActiveMQ为表明的可靠性优先的设计原理:
此种方案将全部的消息数据和消息的发送状态都存储在消息服务器上,能够在消息服务上经过多种手段来保证消息的可靠性,但增长了众多复杂的可靠性保证手段后,消息从发布者到订阅者的速度势必会受到影响;此种方式发布者将消息推向消息服务器,消息服务器再将消息推向订阅者,为消息发送策略提供了很好的可扩展性;
二、以KafKa为表明的速度优先的设计原理:
此种方式将消息的发送状态保存在客户端,同时客户端用拉的模式从消息服务器上获取消息,因为是顺序读,同时还采起了不少保证速度的策略,如zero-copy,因此此种方案速度比较快,但牺牲了不少可靠性方面的保证,比较适合Web2.0网站,这些网站对消息的可靠性要求不是很高,同时因为产生了大量的和用户状态相关的消息,须要一个高效的系统来处理这些消息;另外这种方案也比较适合日志消息的收集;
三、传统的系解耦方案:
此种方式是不用消息中间件直接用数据库存储作的解耦,随着消息中间件的出现,这种方式的使用愈来愈少,但如今因为MongoDB和Redis等的兴起,一些基于这些Nosql数据库的消息应用逐渐兴起,因为消息数据和消息状态都存储在DB上,因此效率和速度在上面两种方案之间;sql
那么有没有一种更高效的方式呢?数据库
答案是确定的,但那可能要进一步下降可靠性!服务器
看看Facebook的Scribe日志收集系统的原理:网络
若是Scribe Server正常工做,Scribe Client将App的日志(能够当作一个消息)推送到Scribe Server端,若是不正常,则写到本地文件,当Scribe Server恢复正常时再将其推送过去;这里使用本地文件做为缓冲,那么可否综合Scribe和Kafka的优势来设计一个消息系统(或日志收集系统,改造一下能够互用),看下面的方案:网站
上面的MQ暂且叫他FastMQ吧,①中消息发布端直接写本地文件,同时消息订阅者经过Zookeeper协调,向相关消息发布者的Agent拉消息,并在本地记录消息指针状态;设计
若是嫌在消息发布端开启MQ Agent麻烦,那么如②中消息拉取协议使用SCP或FTP协议,用这些Linux必备的协议提供者做为Agent减小开发和部署的难度,在服务订阅端解析这些协议流,反序列化为消息供业务使用;指针
若是以为消息只存储在消息发布端的磁盘不可靠,那么如③中能够在消息订阅者处理不及消息的时候,把消息数据缓冲在消息订阅端的磁盘上来备份数据,不过这样作就使系统变的复杂,虽然提升了可靠性,可是速度就会有所下降;日志
此种方案可使消息分散的存储在业务自己的磁盘上,避免集中存储相互影响的缺点,同时又能够有效利用业务机器的磁盘(大部分业务机器磁盘基本没使用),另外还能够减小一次网络通讯的过程,使从发送到接收的速度更快;但其自己也有很多缺点,要作好监控,避免消息大量积压的时候业务磁盘过分使用,对业务形成影响。中间件
目前咱们的监控日志收集系统使用的是和②中相似的方案,消息系统使用的是3方案,后期可能会将可靠性要求高的向1方案过分,可靠性要求不高的向最下面介绍这种过分!图片
转自:http://www.iteye.com/topic/1113331