消息模式实例

视频教程:https://ke.qq.com/course/304104

编写代码前,最好先添加好用户并设置virtual hosts

一、简单模式

1.导入jar包

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

2.创建连接

import com.idelan.rabbitmq.utils.ConnectionUtil;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection; public class Sender {
private final static String QUEUE = "testhello"; //队列名字 public static void main(String[] args) throws Exception{
//获取连接
Connection connection = ConnectionUtil.getConnection(); //创建通道
Channel channel = connection.createChannel(); //声明队列,如果队列存在则什么都不做,如果队列不存在才创建
//参数一: 队列的名字
//参数二: 是否持久化队列,我们的队列模式是在内存中的,如果rabbit重启会丢失,如果我们设置为true 则会保存到erlng自带的数据库中,重启会重新获取
//参数三: 是否排外,有两个作用,第一个当我们的链接关闭后是否会自动删除队列,作用二,是否私有当前队列,如果私有了,其他通道不可以访问当前队列,如果为true 一般适合一个队列消费者的时候
//参数四: 是否自动删除
//参数五 我们的一些其他的参数
channel.queueDeclare(QUEUE, false, false, false, null); //发送内容
channel.basicPublish("", QUEUE, null, "hello world".getBytes()); //关闭连接
channel.close();
connection.close();
}
}

3.消费者

import com.idelan.rabbitmq.utils.ConnectionUtil;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.QueueingConsumer; public class Receiver {
private final static String QUEUE = "testhello"; //队列名字 public static void main(String[] args) throws Exception{
Connection connection = ConnectionUtil.getConnection();
Channel channel = connection.createChannel();
channel.queueDeclare(QUEUE, false, false, false, null); QueueingConsumer consumer = new QueueingConsumer(channel);
//接收消息,参数二 是自动确认
channel.basicConsume(QUEUE, true, consumer); while (true) {
//获取消息 如果没有消息会等待,有的话就获取执行然后销毁,是一次性的
QueueingConsumer.Delivery delivery = consumer.nextDelivery();
String message = new String(delivery.getBody());
System.out.println("message:"+message);
}
}
}

二、工作模式

1.生产者

import com.idelan.rabbitmq.utils.ConnectionUtil;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection; public class Sender {
private final static String QUEUE = "testwork"; //队列名字 public static void main(String[] args) throws Exception{
//获取连接
Connection connection = ConnectionUtil.getConnection(); //创建通道
Channel channel = connection.createChannel(); //声明队列,如果队列存在则什么都不做,如果队列不存在才创建
//参数一: 队列的名字
//参数二: 是否持久化队列,我们的队列模式是在内存中的,如果rabbit重启会丢失,如果我们设置为true 则会保存到erlng自带的数据库中,重启会重新获取
//参数三: 是否排外,有两个作用,第一个当我们的链接关闭后是否会自动删除队列,作用二,是否私有当前队列,如果私有了,其他通道不可以访问当前队列,如果为true 一般适合一个队列消费者的时候
//参数四: 是否自动删除
//参数五 我们的一些其他的参数
channel.queueDeclare(QUEUE, false, false, false, null); for (int i = 0; i < 20; i++){
//发送内容
channel.basicPublish("", QUEUE, null, ("hello world "+i).getBytes());
} //关闭连接
channel.close();
connection.close();
}
}

2.消费者1

import com.idelan.rabbitmq.utils.ConnectionUtil;
import com.rabbitmq.client.*; import java.io.IOException; public class Receiver1 {
private final static String QUEUE = "testwork"; //队列名字 public static void main(String[] args) throws Exception{
Connection connection = ConnectionUtil.getConnection();
final Channel channel = connection.createChannel();
channel.queueDeclare(QUEUE, false, false, false, null); //告诉服务器,在我没有确认当前消息完成之前,不要给我发新消息
channel.basicQos(1); DefaultConsumer consumer = new DefaultConsumer(channel) { @Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
//当我们收到消息的时候调用
System.out.println("消费者1 收到的消息内容是:" + new String(body));
//确认 参数2,false为确认收到消息,true 为拒绝接收
channel.basicAck(envelope.getDeliveryTag(), false);
}
}; //注册消费者,参数2 收到确认,代表我们收到消息后需要手动告诉服务器,我们收到消息了
channel.basicConsume(QUEUE, false, consumer);
}
}

3.消费者2

import com.idelan.rabbitmq.utils.ConnectionUtil;
import com.rabbitmq.client.*; import java.io.IOException; public class Receiver2 {
private final static String QUEUE = "testwork"; //队列名字 public static void main(String[] args) throws Exception{
Connection connection = ConnectionUtil.getConnection();
final Channel channel = connection.createChannel();
channel.queueDeclare(QUEUE, false, false, false, null); //告诉服务器,在我没有确认当前消息完成之前,不要给我发新消息
channel.basicQos(1);
DefaultConsumer consumer = new DefaultConsumer(channel) { @Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
//当我们收到消息的时候调用
System.out.println("消费者2 收到的消息内容是:" + new String(body));
//确认 参数2,false为确认收到消息,true 为拒绝接收
channel.basicAck(envelope.getDeliveryTag(), false);
}
}; //注册消费者,参数2 收到确认,代表我们收到消息后需要手动告诉服务器,我们收到消息了
channel.basicConsume(QUEUE, false, consumer);
}
}

三、发布订阅模式

1.生产者

import com.idelan.rabbitmq.utils.ConnectionUtil;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection; public class Sender {
private final static String EXCHANGE_NAME = "testexchange"; //定义交换机名字 public static void main(String[] args) throws Exception{ Connection connection = ConnectionUtil.getConnection();
Channel channel = connection.createChannel();
//声明交换机
channel.exchangeDeclare(EXCHANGE_NAME, "fanout");//定义一个交换机,类型是fanout //发布订阅模式,因为消息是先发布到交换机中,而交换机是没有保存功能的,所以如果没有消费者,消息则会丢失
channel.basicPublish(EXCHANGE_NAME, "", null, "发布订阅模式的消息".getBytes());
channel.close();
connection.close();
}
}

2.消费者1

import com.idelan.rabbitmq.utils.ConnectionUtil;
import com.rabbitmq.client.*; import java.io.IOException; public class Receiver1 {
private final static String EXCHANGE_NAME = "testexchange"; //定义交换机名字 public static void main(String[] args) throws Exception{
Connection connection = ConnectionUtil.getConnection();
final Channel channel = connection.createChannel();
channel.queueDeclare("testpubQueue1", false, false, false, null); //绑定队列到交换机
channel.queueBind("testpubQueue1", EXCHANGE_NAME, "");
channel.basicQos(1);
DefaultConsumer consumer = new DefaultConsumer(channel) {
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
System.out.println("消费者1:"+new String(body));
channel.basicAck(envelope.getDeliveryTag(),false);
}
};
channel.basicConsume("testpubQueue1", false, consumer);
}
}

3.消费者2

import com.idelan.rabbitmq.utils.ConnectionUtil;
import com.rabbitmq.client.*; import java.io.IOException; public class Receiver2 {
private final static String EXCHANGE_NAME = "testexchange"; //定义交换机名字 public static void main(String[] args) throws Exception{
Connection connection = ConnectionUtil.getConnection();
final Channel channel = connection.createChannel();
channel.queueDeclare("testpubQueue2", false, false, false, null); //绑定队列到交换机
channel.queueBind("testpubQueue2", EXCHANGE_NAME, "");
channel.basicQos(1);
DefaultConsumer consumer = new DefaultConsumer(channel) {
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
System.out.println("消费者2:"+new String(body));
channel.basicAck(envelope.getDeliveryTag(),false);
}
};
channel.basicConsume("testpubQueue2", false, consumer);
}
}

四、路由模式

1.生产者

import com.idelan.rabbitmq.utils.ConnectionUtil;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection; public class Sender {
private final static String EXCHANGE_NAME = "testexroute"; //定义交换机名字 public static void main(String[] args) throws Exception{ Connection connection = ConnectionUtil.getConnection();
Channel channel = connection.createChannel();
//声明交换机
channel.exchangeDeclare(EXCHANGE_NAME, "direct");//定义一个路由格式的交换机 //发布订阅模式,因为消息是先发布到交换机中,而交换机是没有保存功能的,所以如果没有消费者,消息则会丢失
// routingKey 为key1
channel.basicPublish(EXCHANGE_NAME, "key3", null, "路由模式的消息".getBytes());
channel.close();
connection.close();
}
}

2.消费者1

import com.idelan.rabbitmq.utils.ConnectionUtil;
import com.rabbitmq.client.*; import java.io.IOException; public class Receiver1 {
private final static String EXCHANGE_NAME = "testexroute"; //定义交换机名字 public static void main(String[] args) throws Exception{
Connection connection = ConnectionUtil.getConnection();
final Channel channel = connection.createChannel();
channel.queueDeclare("testRouteQueue1", false, false, false, null); //绑定队列到交换机
//参数3标记,绑定到交换机的时候会指定一个标记,只有和它一样的标记的消息才会被当前消费者接收到
channel.queueBind("testRouteQueue1", EXCHANGE_NAME, "key1");
//如果需要绑定多个标记 在执行一次即可
channel.queueBind("testRouteQueue1", EXCHANGE_NAME, "key3");
channel.basicQos(1);
DefaultConsumer consumer = new DefaultConsumer(channel) {
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
System.out.println("消费者1:"+new String(body));
channel.basicAck(envelope.getDeliveryTag(),false);
}
};
channel.basicConsume("testRouteQueue1", false, consumer);
}
}

3.消费者2

import com.idelan.rabbitmq.utils.ConnectionUtil;
import com.rabbitmq.client.*; import java.io.IOException; public class Receiver2 {
private final static String EXCHANGE_NAME = "testexroute"; //定义交换机名字 public static void main(String[] args) throws Exception{
Connection connection = ConnectionUtil.getConnection();
final Channel channel = connection.createChannel();
channel.queueDeclare("testRouteQueue2", false, false, false, null); //绑定队列到交换机
//参数3标记,绑定到交换机的时候会指定一个标记,只有和它一样的标记的消息才会被当前消费者接收到
channel.queueBind("testRouteQueue2", EXCHANGE_NAME, "key1");
//如果需要绑定多个标记 在执行一次即可
channel.queueBind("testRouteQueue2", EXCHANGE_NAME, "key2");
channel.basicQos(1);
DefaultConsumer consumer = new DefaultConsumer(channel) {
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
System.out.println("消费者2:"+new String(body));
channel.basicAck(envelope.getDeliveryTag(),false);
}
};
channel.basicConsume("testRouteQueue2", false, consumer);
}
}

五、主题模式

1.生产者

import com.idelan.rabbitmq.utils.ConnectionUtil;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection; public class Sender {
private final static String EXCHANGE_NAME = "testexchangetopic"; //定义交换机名字 public static void main(String[] args) throws Exception{ Connection connection = ConnectionUtil.getConnection();
Channel channel = connection.createChannel();
//声明交换机
channel.exchangeDeclare(EXCHANGE_NAME, "topic");//定义一个topic 格式的交换机 //发布订阅模式,因为消息是先发布到交换机中,而交换机是没有保存功能的,所以如果没有消费者,消息则会丢失
// routingKey 为key1
// * 只能匹配一个字符 # 可以匹配多个字符
channel.basicPublish(EXCHANGE_NAME, "abc.1.3", null, "topic模式的消息".getBytes());
channel.close();
connection.close();
}
}

2.消费者1

import com.idelan.rabbitmq.utils.ConnectionUtil;
import com.rabbitmq.client.*; import java.io.IOException; public class Receiver1 {
private final static String EXCHANGE_NAME = "testexchangetopic"; //定义交换机名字 public static void main(String[] args) throws Exception{
Connection connection = ConnectionUtil.getConnection();
final Channel channel = connection.createChannel();
channel.queueDeclare("testTopicQueue1", false, false, false, null); //绑定队列到交换机
//参数3标记,绑定到交换机的时候会指定一个标记,只有和它一样的标记的消息才会被当前消费者接收到
channel.queueBind("testTopicQueue1", EXCHANGE_NAME, "key.*");
//如果需要绑定多个标记 在执行一次即可
channel.queueBind("testTopicQueue1", EXCHANGE_NAME, "abc.#");
channel.basicQos(1);
DefaultConsumer consumer = new DefaultConsumer(channel) {
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
System.out.println("消费者1:"+new String(body));
channel.basicAck(envelope.getDeliveryTag(),false);
}
};
channel.basicConsume("testTopicQueue1", false, consumer);
}
}

3.消费者2

import com.idelan.rabbitmq.utils.ConnectionUtil;
import com.rabbitmq.client.*; import java.io.IOException; public class Receiver2 {
private final static String EXCHANGE_NAME = "testexchangetopic"; //定义交换机名字 public static void main(String[] args) throws Exception{
Connection connection = ConnectionUtil.getConnection();
final Channel channel = connection.createChannel();
channel.queueDeclare("testTopicQueue2", false, false, false, null); //绑定队列到交换机
//参数3标记,绑定到交换机的时候会指定一个标记,只有和它一样的标记的消息才会被当前消费者接收到
channel.queueBind("testTopicQueue2", EXCHANGE_NAME, "key.#");
//如果需要绑定多个标记 在执行一次即可
channel.queueBind("testTopicQueue2", EXCHANGE_NAME, "abc.*");
channel.basicQos(1);
DefaultConsumer consumer = new DefaultConsumer(channel) {
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
System.out.println("消费者2:"+new String(body));
channel.basicAck(envelope.getDeliveryTag(),false);
}
};
channel.basicConsume("testTopicQueue2", false, consumer);
}
}

RabbitMQ 消息模式的更多相关文章

  1. RabbitMQ消息队列(八)-通过Topic主题模式分发消息(.Net Core版)

    前两章我们讲了RabbitMQ的direct模式和fanout模式,本章介绍topic主题模式的应用.如果对direct模式下通过routingkey来匹配消息的模式已经有一定了解那fanout也很好 ...

  2. (九)RabbitMQ消息队列-通过Headers模式分发消息

    原文:(九)RabbitMQ消息队列-通过Headers模式分发消息 Headers类型的exchange使用的比较少,以至于官方文档貌似都没提到,它是忽略routingKey的一种路由方式.是使用H ...

  3. (八)RabbitMQ消息队列-通过Topic主题模式分发消息

    原文:(八)RabbitMQ消息队列-通过Topic主题模式分发消息 前两章我们讲了RabbitMQ的direct模式和fanout模式,本章介绍topic主题模式的应用.如果对direct模式下通过 ...

  4. (七)RabbitMQ消息队列-通过fanout模式将消息推送到多个Queue中

    原文:(七)RabbitMQ消息队列-通过fanout模式将消息推送到多个Queue中 前面第六章我们使用的是direct直连模式来进行消息投递和分发.本章将介绍如何使用fanout模式将消息推送到多 ...

  5. RabbitMQ之消息模式(下)

    目的: RabbitMQ之消息模式(上):https://www.cnblogs.com/huangting/p/11994539.html 消费端限流 消息的ACK与重回队列 TTL消息 死信队列 ...

  6. RabbitMQ之消息模式简单易懂,超详细分享~~~

    前言 上一篇对RabbitMQ的流程和相关的理论进行初步的概述,如果小伙伴之前对消息队列不是很了解,那么在看理论时会有些困惑,这里以消息模式为切入点,结合理论细节和代码实践的方式一起来学习. 正文 常 ...

  7. Rabbitmq -Publish_Subscribe模式- python编码实现

    what is Exchanges ?? Let's quickly go over what we covered in the previous tutorials: A producer is ...

  8. (转)RabbitMQ消息队列(九):Publisher的消息确认机制

    在前面的文章中提到了queue和consumer之间的消息确认机制:通过设置ack.那么Publisher能不到知道他post的Message有没有到达queue,甚至更近一步,是否被某个Consum ...

  9. (转)RabbitMQ消息队列(四):分发到多Consumer(Publish/Subscribe)

    上篇文章中,我们把每个Message都是deliver到某个Consumer.在这篇文章中,我们将会将同一个Message deliver到多个Consumer中.这个模式也被成为 "pub ...

随机推荐

  1. Windows_Management_Instrumentation

    WMI是管理系统中的核心 使用本工具的前提是:系统的服务列表中,Windows_Management_Instrumentation(winmgmts)这个服务处于运行状态.如果处于关闭状态,请在运行 ...

  2. IntelliJ IDEA项目断开版本管理解决方案

    今天使用idea时打开项目突然发现项目不受svn管理(项目目录依然受svn管理,只是idea脱管了),如遇到可用以下方法: 图片示例: 1. 2. 希望能帮到你

  3. 吴裕雄--天生自然python学习笔记:python文档操作批量替换 Word 文件中的文字

    我们经常会遇到在不同的 Word 文件中的需要做相同的文字替换,若是一个一个 文件操作,会花费大量时间 . 本节案例可以找出指定目录中的所有 Word 文件(包含 子目录),并对每一个文件进行指定的文 ...

  4. windows下redis的配置和jedis api的最基本的使用

    redis的安装直接跳过 1.注册redis服务 在DOM窗口下,进入redis的安装目录(可以先进入安装目录,然后shift+右键,选择在此处打开powershell窗口), 输入命令: redis ...

  5. python学习笔记(4)数据类型-元组

    元组其实和列表一样,不一样的是,元组的值不能改变,一旦创建,就不能再改变了,比如说,要存数据库的连接信息,这个连接信息在程序运行中是不能被改变的,如果变了那数据库连不上了,就程序就完犊子了,这样的就可 ...

  6. mysqli存储过程

    <?php$link = mysqli_connect('localhost','root','','chinatupai');  $sql = "call getEmail('000 ...

  7. 吴裕雄--天生自然Android开发学习:Android studio 3.5安装详解

    3. 建立AVD(安卓虚拟设备) 点击右上角AVD Manager图标,单击按钮Create Virtual Device,选择Nexus 5X,下一步,选择版本9.0,Download,然后Next ...

  8. Ajax 请求参数过多导致 400 错误 and BCryptPasswordEncoder 加密判断

    2019/06/19 先分享一种密码加密方式: Spring Security 提供了 BCryptPasswordEncoder类, 实现Spring的PasswordEncoder接口使用BCry ...

  9. Typescript - 联合类型

    原文:TypeScript基本知识点整理 零.序言 联合类型表示一个变量值可以是几种类型之一,我们可以使用 “|” 来分割每个类型: 联合类型的变量在被赋值时,会根据类型推断的规则推断出一个类型: 如 ...

  10. container/injection简介以及发展历史

    一:什么是Container?Container的作用? 容器是一个标准的软件单元,它将代码及其所有依赖关系打包,以便应用程序从一个计算环境快速可靠地运行到另一个计算环境.container的主要作用 ...