消息队列(mq)是什么?
是生产者先将消息投递一个叫队列的容器中,然后再从这个容器中取出消息,最后再转发给消费者。
消息队列是 Microsoft 的消息处理技术,它在任何安装 Microsoft Windows 的计算机组合中,为任何应用程序提供消息处理和消息队列功能,无论这些计算机是否在同一个网络上或者是否同时联机。
消息队列网络是能够相互间来回发送消息的任何一组计算机。网络中的不同计算机在确保消息顺利处理的过程中扮演不同的角色。它们中有些提供路由信息以确定如何发送消息,有些保存整个网络的重要信息,而有些只是发送和接收消息。
消息队列的类型介绍:
消息队列目前主要有两种类型:POSIX消息队列以及系统V消息队列,系统V消息队列目前被大量使用。每个消息队列都有一个队列头,用结构struct msg_queue来描述。队列头中包含了该消息队列的大量信息。包括消息队列键值、用户ID、组ID、消息队列中消息数目等等。
消息队列就是一个消息的链表,可以把消息看作一个记录,具有特定的格式以及特定的优先级。对消息队列有写权限的进程可以向消息队列中按照一定的规则添加新消息;对消息队列有读权限的进程则可以从消息队列中读走消息。消息队列是随内核持续的。
消息队列就是基础数据结构中的“先进先出”的一种数据机构。想一下,生活中买东西,需要排队,先排的人先买消费,就是典型的“先进先出”。
MQ是一直存在,不过随着微服务架构的流行,成了解决微服务之间问题的常用工具。
主流的消息队列MQ比较,特征,以及典型使用场景。
1.ZeroMQ
号称最快的消息队列系统,尤其针对大吞吐量的需求场景。
扩展性好,开发比较灵活,采用C语言实现,实际上只是一个socket库的重新封装,如果做为消息队列使用,需要开发大量的代码。ZeroMQ仅提供非持久性的队列,也就是说如果down机,数据将会丢失。其中,Twitter的Storm中使用ZeroMQ作为数据流的传输。
2.RabbitMQ
结合erlang语言本身的并发优势,支持很多的协议:AMQP,XMPP, SMTP, STOMP,也正是如此,使的它变的非常重量级,更适合于企业级的开发。
性能较好,但是不利于做二次开发和维护。
3.ActiveMQ
历史悠久的开源项目,是Apache下的一个子项目。已经在很多产品中得到应用,实现了JMS1.1规范,可以和spring-jms轻松融合,实现了多种协议,不够轻巧(源代码比RocketMQ多),支持持久化到数据库,对队列数较多的情况支持不好。
4.Redis
做为一个基于内存的K-V数据库,其提供了消息订阅的服务,可以当作MQ来使用,目前应用案例较少,且不方便扩展。对于RabbitMQ和Redis的入队和出队操作,各执行100万次,每10万次记录一次执行时间。
MQ全称为Message Queue,即消息队列,是一种跨进程的通信机制,用于上下游传递消息。
使用mq的原因:
1. 实现分布式系统之间的解耦调用
在分布式系统中,经常会出现一个服务会有多个消费端调用,而且可能每个消费方需要接入的逻辑不一致,又或者随着项目的不断发展,我们需要接口的未来维护和发展确定一套可扩展的规范,引入消息系统,在处理过程中间插入了一个隐含的、基于数据的接口层,两边的处理过程都要实现这一接口。这允许你独立的扩展或修改两边的处理过程,只要确保它们遵守同样的接口约束。
2. 实现异步调用
有时候我们会遇到这样的场景,用户在客户端提交了一个请求,后端处理这个请求的业务相对比较复杂,如果这个请求使用的是同步调用,客户端就会出现发送请求后过了很久才相应的情况,这对用户体验来说是十分致命的。如果说用户并不关心请求是否处理,对于一些耗时的非事务性的业务处理,我们可以使用mq异步请求的方式,将处理信息放入队列,由后端监听队列自行处理,在将消息存入队列后直接返回客户端相应,加快响应速度。
3. 削峰(队列),解决高并发问题
例如秒杀活动,可能在短时间内会有很大请求同时到后端,如果后端对每个请求都执行业务操作,例如查询数据库和写数据库,会造成服务器压力过大,同时,在同一时间进行大量数据库操作,可能会出现数据异常,我们可以使用mq实现缓冲,将所有请求先放入消息队列中,服务端每次处理业务先从消息队列获取。