目录前端
@(Java消息中间件)java
消息中间件也能够称消息队列,是指用高效可靠的消息传递机制进行与平台无关的数据交流,并基于数据通讯来进行分布式系统的集成。经过提供消息传递和消息队列模型,能够在分布式环境下扩展进程的通讯。当下主流的消息中间件有RabbitMQ、Kafka、ActiveMQ、RocketMQ等。其能在不一样平台之间进行通讯,经常使用来屏蔽各类平台协议之间的特性,实现应用程序之间的协同。其优势在于可以在客户端和服务器之间进行同步和异步的链接,而且在任什么时候刻均可以将消息进行传送和转发。是分布式系统中很是重要的组件,主要用来解决应用耦合、异步通讯、流量削峰等问题redis
消息中间件几大主要做用以下:算法
P2P模式包含三个角色:消息队列(Queue),发送者(Sender),接收者(Receiver)。每一个消息都被发送到一个特定的队列,接收者从队列中获取消息。队列保留着消息,直到他们被消费或超时。数据库
P2P的特色:apache
消息生产者(发布)将消息发布到topic中,同时有多个消息消费者(订阅)消费该消息。和点对点方式不一样,发布到topic的消息会被全部订阅者消费。
queue实现了负载均衡,将producer生产的消息发送到消息队列中,由多个消费者消费。但一个消息只能被一个消费者接受,当没有消费者可用时,这个消息会被保存直到有一个可用的消费者。
topic实现了发布和订阅,当你发布一个消息,全部订阅这个topic的服务都能获得这个消息,因此从1到N个订阅者都能获得一个消息的拷贝浏览器
Pub/Sub的特色安全
场景说明:用户在注册后,须要发注册邮件和注册短信,传统的作法有两种:1.串行; 2.并行
1.串行方式:将注册信息写入数据库后,发送注册邮件,再发送注册短信,以上三个任务所有完成后才返回给客户端。 这有一个问题是,邮件,短信并非必须的,它只是一个通知,而这种作法让客户端等待没有必要等待的东西.
2.并行方式:将注册信息写入数据库后,发送邮件的同时,发送短信,以上三个任务完成后,返回给客户端,并行的方式能提升处理的时间。
假设三个业务节点分别使用50ms,串行方式使用时间150ms,并行使用时间100ms。虽然并性已经提升的处理时间,可是,前面说过,邮件和短信对我正常的使用网站没有任何影响,客户端没有必要等着其发送完成才显示注册成功,应该是写入数据库后就返回.服务器
3.消息队列
引入消息队列后,把发送邮件,短信不是必须的业务逻辑异步处理
由此能够看出,引入消息队列后,用户的响应时间就等于写入数据库的时间+写入消息队列的时间(能够忽略不计),引入消息队列后处理后,响应时间是串行的3倍,是并行的2倍。网络
这是一个高耦合度系统的例子
先是来一我的找他要求发送数据给一个新的系统H,系统A的同窗要修改代码而后在那个代码里加入调用新系统H的流程。
一会那个系统B是个陈旧老系统要下线了,告诉系统A的同窗:别给我发送数据了,接着系统A再次修改代码再也不给这个系统B。
而后若是要是某个下游系统忽然宕机了呢?
系统A的调用代码里是否是会抛异常?那系统A的同窗会收到报警说异常了,结果他还要去care是下游哪一个系统宕机了。
因此在实际的系统架构设计中,若是所有采起这种系统耦合的方式,在某些场景下绝对是不合适的,系统耦合度太严重。
而且互相耦合起来并非核心链路的调用,而是一些非核心的场景(好比上述的数据消费)致使了系统耦合,这样会严重的影响上下游系统的开发和维护效率。
所以在上述系统架构中,就能够采用MQ中间件来实现系统解耦。
系统A就把本身的一份核心数据发到MQ里,下游哪一个系统感兴趣本身去消费便可,不须要了就取消数据的消费,以下图所示:
AMQP协议
AMQP即Advanced Message Queuing Protocol,一个提供统一消息服务的应用层标准高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计。基于此协议的客户端与消息中间件可传递消息,并不受客户端/中间件不一样产品,不一样开发语言等条件的限制。
优势:可靠、通用
MQTT协议
MQTT(Message Queuing Telemetry Transport,消息队列遥测传输)是IBM开发的一个即时通信协议,有可能成为物联网的重要组成部分。该协议支持全部平台,几乎能够把全部联网物品和外部链接起来,被用来当作传感器和致动器(好比经过Twitter让房屋联网)的通讯协议。
优势:格式简洁、占用带宽小、移动端通讯、PUSH、嵌入式系统
STOMP协议
STOMP(Streaming Text Orientated Message Protocol)是流文本定向消息协议,是一种为MOM(Message Oriented Middleware,面向消息的中间件)设计的简单文本协议。STOMP提供一个可互操做的链接格式,容许客户端与任意STOMP消息代理(Broker)进行交互。
优势:命令模式(非topic\queue模式)
XMPP协议
XMPP(可扩展消息处理现场协议,Extensible Messaging and Presence Protocol)是基于可扩展标记语言(XML)的协议,多用于即时消息(IM)以及在线现场探测。适用于服务器之间的准即时操做。核心是基于XML流传输,这个协议可能最终容许因特网用户向因特网上的其余任何人发送即时消息,即便其操做系统和浏览器不一样。
优势:通用公开、兼容性强、可扩展、安全性高,但XML编码格式占用带宽大
其余基于TCP/IP自定义的协议
有些特殊框架(如:redis、kafka、zeroMq等)根据自身须要未严格遵循MQ规范,而是基于TCP\IP自行封装了一套协议,经过网络socket接口进行传输,实现了MQ的功能。
RocketMQ
阿里系下开源的一款分布式、队列模型的消息中间件,原名Metaq,3.0版本名称改成RocketMQ,是阿里参照kafka设计思想使用java实现的一套mq。同时将阿里系内部多款mq产品(Notify、metaq)进行整合,只维护核心功能,去除了全部其余运行时依赖,保证核心功能最简化,在此基础上配合阿里上述其余开源产品实现不一样场景下mq的架构,目前主要多用于订单交易系统。
具备如下特色:
可以保证严格的消息顺序
提供针对消息的过滤功能
提供丰富的消息拉取模式
高效的订阅者水平扩展能力
实时的消息订阅机制
亿级消息堆积能力
官方提供了一些不一样于kafka的对比差别:
https://rocketmq.apache.org/docs/motivation/
ActiveMQ
Apache下的一个子项目。使用Java彻底支持JMS1.1和J2EE 1.4规范的 JMS Provider实现,少许代码就能够高效地实现高级应用场景。可插拔的传输协议支持,好比:in-VM, TCP, SSL, NIO, UDP, multicast, JGroups and JXTA transports。RabbitMQ、ZeroMQ、ActiveMQ均支持经常使用的多种语言客户端 C++、Java、.Net,、Python、 Php、 Ruby等。
Redis
使用C语言开发的一个Key-Value的NoSQL数据库,开发维护很活跃,虽然它是一个Key-Value数据库存储系统,但它自己支持MQ功能,因此彻底能够当作一个轻量级的队列服务来使用。对于RabbitMQ和Redis的入队和出队操做,各执行100万次,每10万次记录一次执行时间。测试数据分为128Bytes、512Bytes、1K和10K四个不一样大小的数据。实验代表:入队时,当数据比较小时Redis的性能要高于RabbitMQ,而若是数据大小超过了10K,Redis则慢的没法忍受;出队时,不管数据大小,Redis都表现出很是好的性能,而RabbitMQ的出队性能则远低于Redis。
Kafka
Apache下的一个子项目,使用scala实现的一个高性能分布式Publish/Subscribe消息队列系统,具备如下特性:
快速持久化:经过磁盘顺序读写与零拷贝机制,能够在O(1)的系统开销下进行消息持久化;
高吞吐:在一台普通的服务器上既能够达到10W/s的吞吐速率;
高堆积:支持topic下消费者较长时间离线,消息堆积量大;
彻底的分布式系统:Broker、Producer、Consumer都原生自动支持分布式,依赖zookeeper自动实现复杂均衡;
支持Hadoop数据并行加载:对于像Hadoop的同样的日志数据和离线分析系统,但又要求实时处理的限制,这是一个可行的解决方案。
ZeroMQ
号称最快的消息队列系统,专门为高吞吐量/低延迟的场景开发,在金融界的应用中常用,偏重于实时数据通讯场景。ZMQ可以实现RabbitMQ不擅长的高级/复杂的队列,可是开发人员须要本身组合多种技术框架,开发成本高。所以ZeroMQ具备一个独特的非中间件的模式,更像一个socket library,你不须要安装和运行一个消息服务器或中间件,由于你的应用程序自己就是使用ZeroMQ API完成逻辑服务的角色。可是ZeroMQ仅提供非持久性的队列,若是down机,数据将会丢失。如:Twitter的Storm中使用ZeroMQ做为数据流的传输。
ZeroMQ套接字是与传输层无关的:ZeroMQ套接字对全部传输层协议定义了统一的API接口。默认支持 进程内(inproc) ,进程间(IPC) ,多播,TCP协议,在不一样的协议之间切换只要简单的改变链接字符串的前缀。能够在任什么时候候以最小的代价从进程间的本地通讯切换到分布式下的TCP通讯。ZeroMQ在背后处理链接创建,断开和重连逻辑。
特性:
无锁的队列模型:对于跨线程间的交互(用户端和session)之间的数据交换通道pipe,采用无锁的队列算法CAS;在pipe的两端注册有异步事件,在读或者写消息到pipe的时,会自动触发读写事件。
批量处理的算法:对于批量的消息,进行了适应性的优化,能够批量的接收和发送消息。
多核下的线程绑定,无须CPU切换:区别于传统的多线程并发模式,信号量或者临界区,zeroMQ充分利用多核的优点,每一个核绑定运行一个工做者线程,避免多线程之间的CPU切换开销。