聊聊消息队列

聊聊消息队列

写在前面
  最近一两年,总是能听到同行们说 ‘消息队列’这个词,听起来就很高端,但是苦于自己做的是传统项目,对于新技术的应用实在有限,为了不被飞速发展的技术圈淘汰,可以不用,但是不能不会。下面就来看下什么是消息队列,以及消息队列能干什么?有哪些可用的技术框架可以实现它?如何自己写一个消息队列?
  首先看消息队列是什么?
  其实消息队列也是一项普通的技术,并不高端。我们知道消息队列里面的队列(Queue))是java中的一种数据结构,它的特点是先进先出。那么消息队列,我们就可以这样理解,它就是将要传输的数据(消息)放入队列。我们自定义一个队列来验证是否是先进先出,代码如下:

/**
* 输出结果
* first message.
  second message.
  third message.
  由此可见 队列是先进先出的
* @author jbzhang
*
*/
public class CustomQueue {
        // 定义消息队列
   private static Queue<String> queue = new LinkedList<>();

   public static void main(String[] args) {
       producer(); // 调用生产者
       consumer(); // 调用消费者
   }

   // 生产者
   public static void producer() {
       // 添加消息
       queue.add("first message.");
       queue.add("second message.");
       queue.add("third message.");
   }

   // 消费者
   public static void consumer() {
       while (!queue.isEmpty()) {
           // 消费消息
           System.out.println(queue.poll());
       }
   }
}

  那么既然队列可以做到,为什么还要单独提出消息队列这样的概念呢?下面我们就来看看消息队列常见的使用场景:
  应用耦合:多应用间通过消息队列对同一消息进行处理,避免调用接口失败导致整个过程失败;
  这种使用场景如下:
  用户下单后,订单系统需要通知库存系统。传统的做法是,订单系统调用库存系统的接口。
  订单系统:用户下单后,订单系统完成持久化处理,将消息写入消息队列,返回用户订单下单成功。
  库存系统:订阅下单的消息,采用拉/推的方式,获取下单信息,库存系统根据下单信息,进行库存操作。
假如:在下单时库存系统不能正常使用。也不影响正常下单,因为下单后,订单系统写入消息队列就不再关心其他的后续操作了。实现订单系统与库存系统的应用解耦。
  异步处理:即多应用对消息队列中同一消息进行处理,应用间并发处理消息,相比串行处理,减少处理时间;
  这种使用场景如下:
   用户为了使用某个应用,进行注册,系统需要发送注册邮件并验证短信。对这两个操作的处理方式有两种:串行及并行。但是无论并行、串行,你将注册信息写入数据库都要使用一定的时间,但如果直接写进消息队列,将不会耗费什么时间,直接返回注册成功给用户,提高了用户的体验。
  限流削峰:广泛应用于秒杀或抢购活动中,避免流量过大导致应用系统挂掉的情况;
  这种使用场景如下:
   如淘宝聚划算的秒杀活动,一般由于瞬时访问量过大,服务器接收过大,会导致流量暴增,相关系统无法处理请求甚至崩溃。而加入消息队列后,系统可以从消息队列中取数据,相当于消息队列做了一次缓冲。
  这样做的好处是,请求先入消息队列,而不是由业务处理系统直接处理,做了一次缓冲,极大地减少了业务处理系统的压力; 队列长度可以做限制,事实上,秒杀时,后入队列的用户无法秒杀到商品,这些请求可以直接被抛弃,返回活动已结束或商品已售完信息;
  消息驱动的系统:系统分为消息队列、消息生产者、消息消费者,生产者负责产生消息,消费者(可能有多个)负责对消息进行处理;
   这种的使用场景,如我们群聊这种功能,你发出消息供别人查看,此时你就是生产者,读取消息的人就是消费者。
既然消息队列有这么多的使用场景,那有哪些具体的技术框架(消息中间件)呢?
  目前在生产环境,使用较多的消息队列有ActiveMQ,RabbitMQ,ZeroMQ,Kafka,MetaMQ,RocketMQ等。
  其实消息中间件有很多,各有各的优势,但是它们的原理都是相同,我们学会一种的实现思路,就可以理解其他消息中间件的原理。
  我主要学习了RabbitMQ,下面来介绍我的总结:
  RabbitMQ 是一个老牌开源的消息中间件,它实现了标准的 AMQP(Advanced Message Queuing Protocol,高级消息队列协议)消息中间件,使用 Erlang 语言开发,支持集群部署,和多种客户端语言混合调。
RabbitMQ 中有 3 个重要的概念:生产者、消费者和代理。
  生产者:消息的创建者,负责创建和推送数据到消息服务器。
  消费者:消息的接收方,用于处理数据和确认消息。
  代理:也就是 RabbitMQ 服务本身,它用于扮演“快递”的角色,因为它本身并不生产消息,只是扮演了“快递”的角色,把消息进行暂存和传递。
它们的运行流程,如下图所示:
  RabbitMQ 具备以下几个优点:
  支持持久化,RabbitMQ 支持磁盘持久化功能,保证了消息不会丢失;
  高并发,RabbitMQ 使用了 Erlang 开发语言,Erlang 是为电话交换机开发的语言,天生自带高并发光环和高可用特性;
  支持分布式集群,正是因为 Erlang 语言实现的,因此 RabbitMQ 集群部署也非常简单,只需要启动每个节点并使用 --link 把节点加入到集群中即可,并且 RabbitMQ 支持自动选主和自动容灾;
  支持多种语言,比如 Java、.NET、PHP、Python、JavaScript、Ruby、Go 等;
  支持消息确认,支持消息消费确认(ack)保证了每条消息可以被正常消费;
  支持很多插件,比如网页控制台消息管理插件、消息延迟插件等,RabbitMQ 的插件很多并且使用都很方便。
  RabbitMQ 的消息类型,分为以下四种:
  direct(默认类型)模式,此模式为一对一的发送方式,也就是一条消息只会发送给一个消费者;
   headers 模式,允许你匹配消息的 header 而非路由键(RoutingKey),除此之外 headers 和 direct 的使用完全一致,但因为 headers 匹配的性能很差,几乎不会被用到;
  fanout 模式,为多播的方式,会把一个消息分发给所有的订阅者;
  topic 模式,为主题订阅模式,允许使用通配符(#、*)匹配一个或者多个消息,我可以使用“cn.mq.#”匹配到多个前缀是“cn.mq.xxx”的消息,比如可以匹配到“cn.mq.rabbit”、“cn.mq.kafka”等消息。
关于RabbitMQ的具体使用方法,我会在另外一篇文章中进行总结,这里不再赘述,下面贴上文章的链接(未完成)
  我们介绍完了消息队列的概念,使用场景及相关的中间件,下面我们来思考如何自己写一个消息队列?
实现思路如下:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值