简单队列类似于我们的生产者,消费者,


一个生产者,对应一个消费者.


直接上代码:


package com.j1.rabbitmq.simple;

import com.j1.rabbitmq.util.ConnectionUtil;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.QueueingConsumer; public class Recv { private final static String QUEUE_NAME = "test_queue"; public static void main(String[] argv) throws Exception { // 获取到连接以及mq通道
Connection connection = ConnectionUtil.getConnection();
Channel channel = connection.createChannel(); // 声明队列
/**
* 如果队列存在,则返回,如果不存在,则创建
*/
channel.queueDeclare(QUEUE_NAME, false, false, false, null); // 定义队列的消费者
QueueingConsumer consumer = new QueueingConsumer(channel);
// 监听队列
channel.basicConsume(QUEUE_NAME, true, consumer); // 获取消息
while (true) {
QueueingConsumer.Delivery delivery = consumer.nextDelivery();
String message = new String(delivery.getBody());
System.out.println(" [x] Received '" + message + "'");
}
}
}
package com.j1.rabbitmq.simple;

import com.j1.rabbitmq.util.ConnectionUtil;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection; public class Send { private final static String QUEUE_NAME = "test_queue"; public static void main(String[] argv) throws Exception {
// 获取到连接以及mq通道
Connection connection = ConnectionUtil.getConnection();
// 从连接中创建通道
Channel channel = connection.createChannel(); // 声明(创建)队列
channel.queueDeclare(QUEUE_NAME, false, false, false, null); // 消息内容
String message = "Hello World! 1111";
channel.basicPublish("", QUEUE_NAME, null, message.getBytes());
System.out.println(" [x] Sent '" + message + "'"); //关闭通道和连接
channel.close();
connection.close();
}
}

生产者生产一条信息,会被消费者进行消费,

但是上面有一个问题,只能是一对一的关系,在应用中很少用的到,

下面我们来讨论一下,一个生产者,多个消费者的情况

package com.j1.rabbitmq.work;

import com.j1.rabbitmq.util.ConnectionUtil;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection; public class Send { private final static String QUEUE_NAME = "test_queue_work"; public static void main(String[] argv) throws Exception {
// 获取到连接以及mq通道
Connection connection = ConnectionUtil.getConnection();
Channel channel = connection.createChannel(); // 声明队列
channel.queueDeclare(QUEUE_NAME, false, false, false, null); for (int i = 0; i < 100; i++) {
// 消息内容
String message = "" + i;
channel.basicPublish("", QUEUE_NAME, null, message.getBytes());
System.out.println(" [x] Sent '" + message + "'"); Thread.sleep(i * 10);
} channel.close();
connection.close();
}
}
package com.j1.rabbitmq.work;

import com.j1.rabbitmq.util.ConnectionUtil;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.QueueingConsumer; public class Recv { private final static String QUEUE_NAME = "test_queue_work"; public static void main(String[] argv) throws Exception { // 获取到连接以及mq通道
Connection connection = ConnectionUtil.getConnection();
Channel channel = connection.createChannel(); // 声明队列
channel.queueDeclare(QUEUE_NAME, false, false, false, null); // 同一时刻服务器只会发一条消息给消费者,每一次服务器只会向客户端发送一条
//channel.basicQos(1); // 定义队列的消费者
QueueingConsumer consumer = new QueueingConsumer(channel);
// 监听队列,手动返回完成
channel.basicConsume(QUEUE_NAME, false, consumer); // 获取消息
while (true) {
QueueingConsumer.Delivery delivery = consumer.nextDelivery();
String message = new String(delivery.getBody());
System.out.println(" [x] Received '" + message + "'");
//休眠
Thread.sleep(10);
// 返回确认状态
channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
}
}
}
package com.j1.rabbitmq.work;

import com.j1.rabbitmq.util.ConnectionUtil;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.QueueingConsumer; public class Recv2 { private final static String QUEUE_NAME = "test_queue_work"; public static void main(String[] argv) throws Exception { // 获取到连接以及mq通道
Connection connection = ConnectionUtil.getConnection();
Channel channel = connection.createChannel(); // 声明队列
channel.queueDeclare(QUEUE_NAME, false, false, false, null); // 同一时刻服务器只会发一条消息给消费者,每一次服务器只会向客户端发送一条
// channel.basicQos(1); // 定义队列的消费者
QueueingConsumer consumer = new QueueingConsumer(channel);
// 监听队列,手动返回完成状态
channel.basicConsume(QUEUE_NAME, false, consumer); // 获取消息
while (true) {
QueueingConsumer.Delivery delivery = consumer.nextDelivery();
String message = new String(delivery.getBody());
System.out.println(" [x] Received '" + message + "'");
// 休眠1秒
Thread.sleep(1000); channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
}
}
}

上面标红的地方要特别注意一下,

生产者在生产消息时,消费者的拿到的数据是一样的,这样就很不合理,因为能者多劳嘛,为了解决这一个问题,引入一行代码:

channel.basicQos(1);

上面的生产者生产了100条信息,A消费者拿到48条信息,B拿到52条数据,说明A,B拿的信息不是同一条,

就上面的问题我们有一种解决方案:

package com.j1.rabbitmq.ps;

import com.j1.rabbitmq.util.ConnectionUtil;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection; public class Send { private final static String EXCHANGE_NAME = "test_exchange_fanout"; public static void main(String[] argv) throws Exception {
// 获取到连接以及mq通道
Connection connection = ConnectionUtil.getConnection();
Channel channel = connection.createChannel(); // 声明exchange交换机
channel.exchangeDeclare(EXCHANGE_NAME, "fanout"); // 消息内容
String message = "Hello World!";
channel.basicPublish(EXCHANGE_NAME, "", null, message.getBytes());
System.out.println(" [x] Sent '" + message + "'"); channel.close();
connection.close();
}
}
package com.j1.rabbitmq.ps;

import com.j1.rabbitmq.util.ConnectionUtil;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.QueueingConsumer; public class Recv { private final static String QUEUE_NAME = "test_queue_exchange"; private final static String EXCHANGE_NAME = "test_exchange_fanout"; public static void main(String[] argv) throws Exception { // 获取到连接以及mq通道
Connection connection = ConnectionUtil.getConnection();
Channel channel = connection.createChannel(); // 声明队列
channel.queueDeclare(QUEUE_NAME, false, false, false, null); // 绑定队列到交换机
channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, ""); // 同一时刻服务器只会发一条消息给消费者
channel.basicQos(1); // 定义队列的消费者
QueueingConsumer consumer = new QueueingConsumer(channel);
// 监听队列,手动返回完成
channel.basicConsume(QUEUE_NAME, false, consumer); // 获取消息
while (true) {
QueueingConsumer.Delivery delivery = consumer.nextDelivery();
String message = new String(delivery.getBody());
System.out.println(" [x] Received '" + message + "'");
Thread.sleep(10);
// 返回消息消费状态
channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
}
}
}
package com.j1.rabbitmq.ps;

import com.j1.rabbitmq.util.ConnectionUtil;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.QueueingConsumer; public class Recv2 { private final static String QUEUE_NAME = "test_queue_exchange2"; private final static String EXCHANGE_NAME = "test_exchange_fanout"; public static void main(String[] argv) throws Exception { // 获取到连接以及mq通道
Connection connection = ConnectionUtil.getConnection();
Channel channel = connection.createChannel(); // 声明队列
channel.queueDeclare(QUEUE_NAME, false, false, false, null); // 绑定队列到交换机
channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, ""); // 同一时刻服务器只会发一条消息给消费者
channel.basicQos(1); // 定义队列的消费者
QueueingConsumer consumer = new QueueingConsumer(channel);
// 监听队列,手动返回完成
channel.basicConsume(QUEUE_NAME, false, consumer); // 获取消息
while (true) {
QueueingConsumer.Delivery delivery = consumer.nextDelivery();
String message = new String(delivery.getBody());
System.out.println(" [x] Received '" + message + "'");
Thread.sleep(10); channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
}
}
}

其实总结一下:

一个生产者,多个消费者,每个消费者获取到的消息是一样的。

1、生产者发送消息到交换机。(生产者可以向队列或者交换机发送消息)

2、消费者监听消息队列,消费者永远只能从队列中获取消息。

3、队列绑定到交换机,获取消息。

就是将队列绑定在交换机上,监听队列,获取生产者者信息.

一个交换机可以对应好几个队列,

这种模式将用于我们的搜索,缓存服务,后面会在实际应用中看到

RabbitMq 之简单队列的更多相关文章

  1. RabbitMQ (二) 简单队列

    参考:https://blog.csdn.net/vbirdbest/article/details/78583480 简单队列的模型: P : 生产者,即 Producer C : 消费者,即 Co ...

  2. RabbitMq(2) 简单消息队列

    <dependency> <groupId>com.rabbitmq</groupId> <artifactId>amqp-client </ar ...

  3. RabbitMQ学习笔记(2)----RabbitMQ简单队列(Hello World)的使用

    1. 简单队列结构图 2. 引入依赖 pom.xml文件 <dependency> <groupId>com.rabbitmq</groupId> <arti ...

  4. RabbitMQ六种队列模式-简单队列模式

    前言 RabbitMQ六种队列模式-简单队列 [本文]RabbitMQ六种队列模式-工作队列RabbitMQ六种队列模式-发布订阅RabbitMQ六种队列模式-路由模式RabbitMQ六种队列模式-主 ...

  5. RabbitMQ ——与Spring集成及exchange的direct、topic方式实现和简单队列实现

    程序整体结构 Maven依赖 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http: ...

  6. RabbitMQ ——简单队列

    一 .概述 我们不从开始就讲述基本的概念,尤其是在Rabbitmq之中有些概念确实比较难以理解,我们首先做的就是将光放提供的消息模型 进行实现,然后再总结一下Rabbitmq之中的基本概念. 二 .基 ...

  7. RabbitMQ消息队列(一): 简单队列

    1. 示例选用python的pika模块进行测试,需要预先安装pika模块: https://pypi.python.org/pypi/pika/0.10.0#downloads 上述地址下载源码,加 ...

  8. RabbitMQ分布式消息队列服务器(一、Windows下安装和部署)

    RabbitMQ消息队列服务器在Windows下的安装和部署-> 一.Erlang语言环境的搭建 RabbitMQ开源消息队列服务是使用Erlang语言开发的,因此我们要使用他就必须先进行Erl ...

  9. python---RabbitMQ(1)简单队列使用,消息依次分发(一对一),消息持久化处理

    MQ全称为Message Queue, 消息队列(MQ)是一种应用程序对应用程序的通信方法.应用程序通过读写出入队列的消息(针对应用程序的数据)来通信,而无需专用连接来链接它们.消息传递指的是程序之间 ...

随机推荐

  1. Android Studio apk 打包

    1.Build -> Generate Signed APK...,打开如下窗口 2.假设这里没有打过apk包,点击Create new,窗口如下 这里只要输入几个必要项 Key store p ...

  2. How to deal with "Could not find component on update server. Contact VMware Support or your system administrator." in Vmware.

    手动将vmware安装目录下的vmtools镜像文件,windows.iso文件放到虚拟机的光区里. 再进入虚拟机的系统,在系统里打开光盘进行安装

  3. wifi 通过omnipeek 查看 pmf是否生效

    给android的wifi设备添加PMF支持时,抓取omnipeek分析. 从assoc req 中发现相关标志位没有使能,说明STA 没有使能PMF RSN Capabilities: %00000 ...

  4. c++11 std::move() 的使用

    std::move函数可以以非常简单的方式将左值引用转换为右值引用.(左值.左值引用.右值.右值引用 参见:http://www.cnblogs.com/SZxiaochun/p/8017475.ht ...

  5. php模拟post提交数据,用处很多,可用来网站的采集,登陆等等

    1. [代码][PHP]代码 <?php //以程序登陆一个论坛登录为例 function bbslogin($user_login, $password, $host, $port = &qu ...

  6. HttpWebRequest.ReadWriteTimeout 属性

    获取或设置写入或读取流时的超时. 属性值在写入超时或读取超时之前的毫秒数.默认值为 300,000 毫秒(5 分钟). 备注 在写入由 GetRequestStream 方法返回的流时,或在读取由 G ...

  7. (转)在SDL工程中让SDL_ttf渲染汉字

    有时候在关于SDL的博文中看到一些评论,说SDL对中文的支持不佳,因为当程序涉及中文时总是输出乱码. 照我个人观点,这里面很多都是误解.下面就根据我在windows下使用SDL的情况,说说我的观点. ...

  8. nodejs基础 -- web模块

    什么是 Web 服务器? Web服务器一般指网站服务器,是指驻留于因特网上某种类型计算机的程序,Web服务器的基本功能就是提供Web信息浏览服务.它只需支持HTTP协议.HTML文档格式及URL,与客 ...

  9. (实用)Ubuntu 、CentOS更换国内源

    Ubuntu更换apt-get源 通过编辑/etc/apt/sources.list文件,我们能够更换Ubuntu的默认软件更新源.通常是将其换成一些国内比较知名的源.本文主要列举这些内容. 注意,在 ...

  10. mysql分页查询语句怎么写?

    ref: http://www.dashen100.com/question/500 是用limit函数 取前5条数据 select * from table_name limit 0,5 或者 se ...