转自 http://blog.csdn.net/xiaoxian8023/article/details/48679609

本文是简单介绍一下RabbitMQ,参考官网上的教程。同时加入了一些自己的理解。官网教程详见:"Hello World!"

引言


你是否遇到过多个系统间需要通过定时任务来同步某些数据?

你是否在为异构系统的不同进程间相互调用、通讯的问题而苦恼、挣扎?

如果是,那么恭喜你,消息服务让你可以很轻松地解决这些问题。消息服务擅长于解决多系统、异构系统间的数据交换(消息通知/通讯)问题。

本文将要介绍的RabbitMQ就是当前最主流的消息中间件之一。

RabbitMQ简介


MQ(Message Queue,消息队列)是一种应用系统之间的通信方法。是通过读写出入队列的消息来通信(RPC则是通过直接调用彼此来通信的)。

AMQP,即Advanced Message Queuing Protocol,高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计。消息中间件主要用于组件之间的解耦,消息的发送者无需知道消息使用者的存在,反之亦然。
AMQP的主要特征是面向消息、队列、路由(包括点对点和发布/订阅)、可靠性、安全。

RabbitMQ是一个开源的AMQP实现,服务器端用Erlang语言编写,支持多种客户端,如:Python、Ruby、.NET、Java、JMS、C、PHP、ActionScript、XMPP、STOMP等,支持AJAX。用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面表现不俗。

下面通过生产者代码来解释一下RabbitMQ中涉及到的概念。

  1. public class MsgSender {
  2. private final static String QUEUE_NAME = "hello";
  3. public static void main(String[] args) throws IOException {
  4. /**
  5. * 创建连接连接到MabbitMQ
  6. */
  7. ConnectionFactory factory = new ConnectionFactory();
  8. // 设置MabbitMQ所在主机ip或者主机名
  9. factory.setHost("127.0.0.1");
  10. // 创建一个连接
  11. Connection connection = factory.newConnection();
  12. // 创建一个频道
  13. Channel channel = connection.createChannel();
  14. // 指定一个队列
  15. channel.queueDeclare(QUEUE_NAME, false, false, false, null);
  16. // 发送的消息
  17. String message = "hello world!龙轩";
  18. // 往队列中发出一条消息
  19. channel.basicPublish("", QUEUE_NAME, null, message.getBytes());
  20. System.out.println(" [x] Sent '" + message + "'");
  21. // 关闭频道和连接
  22. channel.close();
  23. connection.close();
  24. }
  25. }

ConnectionFactory、Connection、Channel

ConnectionFactory、Connection、Channel,这三个都是RabbitMQ对外提供的API中最基本的对象。不管是服务器端还是客户端都会首先创建这三类对象。
       ConnectionFactory为Connection的制造工厂。

Connection是与RabbitMQ服务器的socket链接,它封装了socket协议及身份验证相关部分逻辑。

Channel是我们与RabbitMQ打交道的最重要的一个接口,大部分的业务操作是在Channel这个接口中完成的,包括定义Queue、定义Exchange、绑定Queue与Exchange、发布消息等。

Queue

Queue(队列)是RabbitMQ的内部对象,用于存储消息,用下图表示。

RabbitMQ中的消息都只能存储在Queue中,生产者(下图中的P)生产消息并最终投递到Queue中,消费者(下图中的C)可以从Queue中获取消息并消费。

队列是有Channel声明的,而且这个操作是幂等的。同名的队列多次声明也只会创建一次。我们发送消息就是想这个声明的队列里发送消息。

看一下消费者的代码:

  1. public class MsgReceiver {
  2. private final static String QUEUE_NAME = "hello";
  3. public static void main(String[] argv) throws IOException, InterruptedException {
  4. ConnectionFactory factory = new ConnectionFactory();
  5. factory.setHost("127.0.0.1");
  6. // 打开连接和创建频道,与发送端一样
  7. Connection connection = factory.newConnection();
  8. Channel channel = connection.createChannel();
  9. // 声明队列,主要为了防止消息接收者先运行此程序,队列还不存在时创建队列。
  10. channel.queueDeclare(QUEUE_NAME, false, false, false, null);
  11. // 创建队列消费者
  12. QueueingConsumer consumer = new QueueingConsumer(channel);
  13. System.out.println(" [*] Waiting for messages. To exit press CTRL+C");
  14. // 指定消费队列
  15. channel.basicConsume(QUEUE_NAME, true, consumer);
  16. while (true) {
  17. // nextDelivery是一个阻塞方法(内部实现其实是阻塞队列的take方法)
  18. QueueingConsumer.Delivery delivery = consumer.nextDelivery();
  19. String message = new String(delivery.getBody());
  20. System.out.println(" [x] Received '" + message + "'");
  21. }
  22. }
  23. }

从上述代码中,我们可以看到ConnectionFactory、Connection、Channel这三个对象都还是会创建。而队列在消费者这里又声明了一遍。这是为了防止先启动消费者,当为消费者指定队列时,如果RabbitMQ服务器上未声明过队列,就会抛出IO异常。

QueueingConsumer

队列消费者,用于监听队列中的消息。调用nextDelivery方法时,内部实现就是调用队列的take方法。该方法的作用:获取并移除此队列的头部,在元素变得可用之前一直等待(如果有必要)。说白了就是如果没有消息,就处于阻塞状态。

运行结果如下:(生产者、消费者谁先运行都可以)

轻松搞定RabbitMQ(一)——RabbitMQ基础知识+HelloWorld的更多相关文章

  1. 轻松搞定RabbitMQ(六)——主题

    转自 http://blog.csdn.net/xiaoxian8023/article/details/48806871 翻译地址:http://www.rabbitmq.com/tutorials ...

  2. 【转】轻松搞定FTP之FlashFxp全攻略

    转载网址:http://www.newhua.com/2008/0603/39163.shtml 轻松搞定FTP之FlashFxp全攻略 导读: FlashFXP是一款功能强大的FXP/FTP软件,融 ...

  3. 【微服务】之六:轻松搞定SpringCloud微服务-API网关zuul

    通过前面几篇文章的介绍,我们可以轻松搭建起来微服务体系中比较重要的几个基础构建服务.那么,在本篇博文中,我们重点讲解一下,如何将所有微服务的API同意对外暴露,这个就设计API网关的概念. 本系列教程 ...

  4. 使用BleLib的轻松搞定Android低功耗蓝牙Ble 4.0开发具体解释

    转载请注明来源: http://blog.csdn.net/kjunchen/article/details/50909410 使用BleLib的轻松搞定Android低功耗蓝牙Ble 4.0开发具体 ...

  5. 春节过后就是金三银四求职季,分享几个Java面试妙招,轻松搞定HR!

    春节过后就是金三银四,分享几个Java面试妙招,轻松搞定HR! 2020年了,先祝大家新年快乐! 今年IT职位依然相当热门,特别是Java开发岗位.软件开发人才在今年将有大量的就业机会.春节过后,金三 ...

  6. 盘它!基于CANN的辅助驾驶AI实战案例,轻松搞定车辆检测和车距计算!

    摘要:基于昇腾AI异构计算架构CANN(Compute Architecture for Neural Networks)的简易版辅助驾驶AI应用,具备车辆检测.车距计算等基本功能,作为辅助驾驶入门级 ...

  7. 轻松搞定javascript变量(闭包,预解析机制,变量在内存的分配 )

    变量:  存储数据的容器     1.声明        var   2.作用域       全局变量. 局部变量. 闭包(相对的全局变量):   3.类型         a.基本类型(undefi ...

  8. Webcast / 技术小视频制作方法——自己动手录制video轻松搞定

    Webcast / 技术小视频制作方法——自己动手录制video轻松搞定 http://blog.sina.com.cn/s/blog_67d387490100wdnh.html 最近申请加入MSP的 ...

  9. 【微服务】之二:从零开始,轻松搞定SpringCloud微服务系列--注册中心(一)

    微服务体系,有效解决项目庞大.互相依赖的问题.目前SpringCloud体系有强大的一整套针对微服务的解决方案.本文中,重点对微服务体系中的服务发现注册中心进行详细说明.本篇中的注册中心,采用Netf ...

  10. 【微服务】之三:从零开始,轻松搞定SpringCloud微服务-配置中心

    在整个微服务体系中,除了注册中心具有非常重要的意义之外,还有一个注册中心.注册中心作为管理在整个项目群的配置文件及动态参数的重要载体服务.Spring Cloud体系的子项目中,Spring Clou ...

随机推荐

  1. git如何忽略文件或者文件夹

    用git开发中会有一些不愿意提交的目录或者文件 在仓库目录下新建一个名为.gitignore的文件(因为是点开头,没有文件名,没办法直接在windows目录下直接创建,必须通过右键Git Bash,按 ...

  2. Can not issue data manipulation statements with executeQuery().解决方案

    这个错误提示是说无法发行sql语句到指定的位置 错误写法: 正确写法: excuteQuery是查询语句,而我要调用的是更新的语句,所以这样数据库很为难到底要干嘛,实际我想用的是更新,但是我写成了查询 ...

  3. Welcome-to-Swift-10属性 (Properties)

    属性将值跟特定的类.结构或枚举关联.存储属性存储常量或变量作为实例的一部分,计算属性计算(而不是存储)一个值.计算属性可以用于类.结构体和枚举里,存储属性只能用于类和结构体. 存储属性和计算属性通常用 ...

  4. 【Luogu】P2567幸运数字(容斥爆搜)

    题目链接 先预处理出幸运数,把成倍数关系的剔掉,然后用容斥原理搜索一下. 这里的容斥很像小学学的那个“班上有n个同学,有a个同学喜欢数学,b个同学喜欢语文……”那样. #include<cstd ...

  5. HDU——1215七夕节(因数和)

    七夕节 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submis ...

  6. python 粘包问题及解决方法

    一粘包 TCP协议是面向对象的,面向流的,提高可靠性服务.使用了优化算法,Nagle算法.将多次间隔较少且数据量小的数据,合并成一个大的数据块,然后进行封包.这样接收端就很难分辨出来.TCP协议数据是 ...

  7. FZOJ Problem 2107 Hua Rong Dao

                                                                                                        ...

  8. 求N维前缀和

    转载自http://blog.csdn.net/jzhang1/article/details/50528549#comments 膜拜 #include <iostream> #incl ...

  9. 【NOIP2016练习】T1 string (计数)

    题意: 思路: ; ..]of int64; n,k,i:longint; ans,x,y:int64; s,t:ansistring; function c(x,y:longint):int64; ...

  10. 获取本机外网IP的工具类

    ExternalIpAddressFetcher.java package com.tyust.common; import java.io.IOException; import java.io.I ...