互联网day18(mq 使用 springboot整合)

本文详细介绍了如何在Spring Boot应用中整合RabbitMQ,通过实例展示了简单模式、工作模式(资源争抢)、发布/订阅模式以及主题模式的实现,包括消息的发送、接收和消费逻辑。此外,还提供了秒杀场景下RabbitMQ的配置和消费者组件的使用。
摘要由CSDN通过智能技术生成

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
五大模式
1.简单模式
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

<!-- rabbitmq -->
    <dependency>
    	<groupId>org.springframework.boot</groupId>
    	<artifactId>spring-boot-starter-amqp</artifactId>
    </dependency>

在这里插入图片描述

在这里插入图片描述

package cn.tedu.rabbitmq.test;



import java.io.IOException;

import org.junit.Before;
import org.junit.Test;

import com.rabbitmq.client.AMQP.BasicProperties;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.QueueingConsumer;
import com.rabbitmq.client.QueueingConsumer.Delivery;
/**
 * 完成连接对象【Channel】的初始化
 * 实现生成端的发送逻辑
 * 实现消费端的接收消费逻辑
 * 
 */
public class SimpleMode {
	//获取连接
	private Channel channel;
	@Before
	public void initChannel() throws Exception{
		//提供ip  port(5672) suer password virtualhost
		//构建一个连接工程
		ConnectionFactory factory=new ConnectionFactory();
		//从工厂获取连接
		factory.setHost("192.168.253.131");
		factory.setPort(5672);
		factory.setUsername("guest");
		factory.setPassword("guest");
		factory.setVirtualHost("/");
		//获取长连接
		Connection conn = factory.newConnection();
		//每次运行都单独获取一个短链接
		channel=conn.createChannel();
	}
	
	//使用一个测试方法实现消息的发送
	@Test
	public void sender() throws Exception{
		//准备一个发送的消息
		String msg="hello world mq";
		//创建一个队列,根据自定义逻辑定义队列的各种属性
		/**
		 * queue :String 队列的名称
		 * durable:Boolean true 队列有持久化,false没有持久化
		 * exclusice:Boolean 是否专属,true表示只有当前创建队列的连接才能操作队列
		 *false表示所有的connection都可以操作队列
		 *autoDelete :Boolean 是否自动删除,当最后一个连接队列断开就关闭
		 *arguments:map 队列的各种属性
		 *
		 */
		channel.queueDeclare("simplemq01", false, false, false, null);
		//执行消费端的发送逻辑
		//exchane:String 交换机的名称
		//routingkey :String 消息的目的地路由key
		//因为使用的是默认路由交换机 routingkey可以指定使用队列名称
		//proos ;basicProperties类型 表示一个消息的所有属性
		//body:Byte 数组,表示消息体内容
		
		channel.basicPublish("", "simplemq01", null,msg.getBytes() );
		
	}
	
	//一发一接
	//消费端
	@Test
	public void consumer() throws Exception{
		//创建rabbit消费端对象
		QueueingConsumer consu=new QueueingConsumer(channel);
		//绑定到队列
		/**
		 * 绑定队列的名称
		 * 是否自动确认  true 消费端不考虑消费是否成功考虑的是效率
		 * false 需要手动确认
		 * callback 消费者
		 */
		channel.basicConsume("simplemq01", true, consu);
		//监听获取队列的消息(确认机制)
		Delivery deliver = consu.nextDelivery();//每调用一次都会从队列中获取一个消息
		//队列没有消息获取的是空
		BasicProperties properties = deliver.getProperties();
		System.out.println(properties.getContentEncoding());
		System.out.println(new String(deliver.getBody()));
		System.out.println(properties.getPriority());
		//while(true);
		//使用while true死循环获取消息 手动返回确认
		//消费正确后返回确认
		while(true){
			Delivery deli=consu.nextDelivery();
			System.out.println(new String (deli.getBody()));
			//消费逻辑完毕后手动确认
			//tag 是用来标实不同消息封装对象的属性
			channel.basicAck(deli.getEnvelope().getDeliveryTag(),false);
		}
	}
}

在这里插入图片描述
2.工作模式(资源争抢)
2.1结构
在这里插入图片描述
在这里插入图片描述
2.2抢红包逻辑
在这里插入图片描述
在这里插入图片描述
2.3代码测试

package cn.tedu.rabbitmq.test;



import java.io.IOException;

import org.junit.Before;
import org.junit.Test;

import com.rabbitmq.client.AMQP.BasicProperties;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.QueueingConsumer;
import com.rabbitmq.client.QueueingConsumer.Delivery;

public class WorkMode {
	//获取连接
	private Channel channel;
	@Before
	public void initChannel() throws Exception{
		//提供ip  port(5672) suer password virtualhost
		//构建一个连接工程
		ConnectionFactory factory=new ConnectionFactory();
		//从工厂获取连接
		factory.setHost("192.168.253.131");
		factory.setPort(5672);
		factory.setUsername("guest");
		factory.setPassword("guest");
		factory.setVirtualHost("/");
		//获取长连接
		Connection conn = factory.newConnection();
		//每次运行都单独获取一个短链接
		channel=conn.createChannel();
	}
	
	//使用一个测试方法实现消息的发送
	@Test
	public void sender() throws Exception{
		//准备一个发送的消息
		String msg="hello worldwork mode";
		
		channel.queueDeclare("workqm01", false, false, false, null);
		
		channel.basicPublish("", "workqm01", null,msg.getBytes() );
		
	}
	
	//一发一接
	//消费端
	@Test
	public void consumer01() throws Exception{
		//创建rabbit消费端对象
		QueueingConsumer consu=new QueueingConsumer(channel);
		//绑定到队列
		channel.basicConsume("workqm01", true, consu);
		while(true){
			Delivery deli=consu.nextDelivery();
			System.out.println("消费者1"+new String (deli.getBody()));
			channel.basicAck(deli.getEnvelope().getDeliveryTag(),false);
		}
	}
	@Test
	public void consumer02() throws Exception{
		//创建rabbit消费端对象
		QueueingConsumer consu=new QueueingConsumer(channel);
		//绑定到队列
		channel.basicConsume("workqm01", true, consu);
		while(true){
			Delivery deli=consu.nextDelivery();
			System.out.println("消费者2"+new String (deli.getBody()));
			channel.basicAck(deli.getEnvelope().getDeliveryTag(),false);
		}
	}
}

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

package cn.tedu.rabbitmq.test;



import java.io.IOException;

import org.junit.Before;
import org.junit.Test;

import com.rabbitmq.client.AMQP.BasicProperties;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.QueueingConsumer;
import com.rabbitmq.client.QueueingConsumer.Delivery;

public class FanoutMode {
	//获取连接
	private Channel channel;
	@Before
	public void initChannel() throws Exception{
		//提供ip  port(5672) suer password virtualhost
		//构建一个连接工程
		ConnectionFactory factory=new ConnectionFactory();
		//从工厂获取连接
		factory.setHost("192.168.253.131");
		factory.setPort(5672);
		factory.setUsername("guest");
		factory.setPassword("guest");
		factory.setVirtualHost("/");
		//获取长连接
		Connection conn = factory.newConnection();
		//每次运行都单独获取一个短链接
		channel=conn.createChannel();
	}
	//fanout 发订阅  direct  路由 topic 主题
 	private static final String type="fanout";
	private static final String q01=type+"q01";
	private static final String q02=type+"q02";
	private  static final String ex=type+"ex";
	//使用一个测试方法实现消息的发送
	@Test
	public void sender() throws Exception{
		//准备一个发送的消息
		String msg="hello fanout";
		//申明交换机  提供交换机的名称和类型
		//队列的申明,交换机的申明 有则直接使用忽略申明
		//无则创建
		channel.exchangeDeclare(ex, type);
		//发送消息,最常用的发布订阅的路由key
		channel.basicPublish(ex, "", null, msg.getBytes());
		//channel.queueDeclare("workqm01", false, false, false, null);
		/*for(int i=0;i<100;i++){
			channel.basicPublish("", "workqm01", null,msg.getBytes() );
			
		}*/
		
	}
	
	//一发一接
	//消费端
	@Test
	public void consumer01() throws Exception{
		
		//创建rabbit消费端对象
		QueueingConsumer consu=new QueueingConsumer(channel);
		//申明队列
		channel.queueDeclare(q01, false, false, false, null);
		//绑定到队列q01  到fanoutex
		channel.queueBind(q01, ex, "");
		channel.basicConsume(q01, true, consu);
		while(true){
			Delivery deli=consu.nextDelivery();
			System.out.println("消费者1"+new String (deli.getBody()));
			channel.basicAck(deli.getEnvelope().getDeliveryTag(),false);
		}
	}
	@Test
	public void consumer02() throws Exception{
		//创建rabbit消费端对象
		QueueingConsumer consu=new QueueingConsumer(channel);
		//申明队列
		channel.queueDeclare(q02, false, false, false, null);
		//绑定到队列q02  到fanoutex
		//绑定到队列
		channel.queueBind(q02, ex, "");
		channel.basicConsume(q02, true, consu);
		while(true){
			Delivery deli=consu.nextDelivery();
			System.out.println("消费者2"+new String (deli.getBody()));
			channel.basicAck(deli.getEnvelope().getDeliveryTag(),false);
		}
	}
}

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

package cn.tedu.rabbitmq.test;



import java.io.IOException;

import org.junit.Before;
import org.junit.Test;

import com.rabbitmq.client.AMQP.BasicProperties;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.QueueingConsumer;
import com.rabbitmq.client.QueueingConsumer.Delivery;

public class TopicMode {
	//获取连接
	private Channel channel;
	@Before
	public void initChannel() throws Exception{
		//提供ip  port(5672) suer password virtualhost
		//构建一个连接工程
		ConnectionFactory factory=new ConnectionFactory();
		//从工厂获取连接
		factory.setHost("192.168.253.131");
		factory.setPort(5672);
		factory.setUsername("guest");
		factory.setPassword("guest");
		factory.setVirtualHost("/");
		//获取长连接
		Connection conn = factory.newConnection();
		//每次运行都单独获取一个短链接
		channel=conn.createChannel();
	}
	//fanout 发订阅  direct  路由 topic 主题
 	private static final String type="topic";
	private static final String q01=type+"q01";
	private static final String q02=type+"q02";
	private  static final String ex=type+"ex";
	//使用一个测试方法实现消息的发送
	@Test
	public void sender() throws Exception{
		//准备一个发送的消息
		String msg="hello topic";
		//申明交换机  提供交换机的名称和类型
		//队列的申明,交换机的申明 有则直接使用忽略申明
		//无则创建
		channel.exchangeDeclare(ex, type);
		//发送消息,最常用的发布订阅的路由key
		channel.basicPublish(ex, "zg.gd.sz", null, msg.getBytes());
		//channel.queueDeclare("workqm01", false, false, false, null);
		/*for(int i=0;i<100;i++){
			channel.basicPublish("", "workqm01", null,msg.getBytes() );
			
		}*/
		
	}
	
	//一发一接
	//消费端
	@Test
	public void consumer01() throws Exception{
		
		//创建rabbit消费端对象
		QueueingConsumer consu=new QueueingConsumer(channel);
		//申明队列
		channel.queueDeclare(q01, false, false, false, null);
		//绑定到队列q01  到fanoutex  ""为路由
		channel.queueBind(q01, ex, "zg.#");
		channel.basicConsume(q01, true, consu);
		while(true){
			Delivery deli=consu.nextDelivery();
			System.out.println("消费者1"+new String (deli.getBody()));
			channel.basicAck(deli.getEnvelope().getDeliveryTag(),false);
		}
	}
	@Test
	public void consumer02() throws Exception{
		//创建rabbit消费端对象
		QueueingConsumer consu=new QueueingConsumer(channel);
		//申明队列
		channel.queueDeclare(q02, false, false, false, null);
		//绑定到队列q02  到fanoutex
		//绑定到队列
		channel.queueBind(q02, ex, "zg.*.*");
		channel.basicConsume(q02, true, consu);
		while(true){
			Delivery deli=consu.nextDelivery();
			System.out.println("消费者2"+new String (deli.getBody()));
			channel.basicAck(deli.getEnvelope().getDeliveryTag(),false);
		}
	}
}

springboot整合rabbitmq

1.秒杀的结构
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

package cn.tedu.seckill.config;

import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
 * 扫描范围加载 在配置内容中准备多个
 * 需要的bean对象
 * @author 在路上
 *
 */
@Configuration
public class SeckillConfig {
	//内存的队列queue对象
	@Bean
	public Queue queue01(){
		return new Queue(RabbitmqNameUtils.queueName, true, false, false,null);
	}
	//内存的交换机对象
	@Bean
	public DirectExchange ex01(){
		return new DirectExchange(RabbitmqNameUtils.exName, 
				false, false,null);
	}
	//绑定关系对象
	@Bean
	public Binding bind01(){
		//将seckill去 seckillex 绑定 seckill路由
		return BindingBuilder.bind(queue01()).to(ex01()).with(RabbitmqNameUtils.routingKey);
	}
}

在这里插入图片描述

package cn.tedu.rabbitmq.consumer;

import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import cn.tedu.seckill.config.RabbitmqNameUtils;

@Component
public class Consumer01 {
	/*
	 * 自动配置中实现了连接对象的创建
	 * @rabbitlister
	 * 生成一个内存中的消费对象,根据绑定队列名称
	 * 实现各种绑定的关系,自动从队列接受监听信息,转给
	 * 当前类的对象,实现对象调用consumer
	 */
	//编写消费的逻辑代码
	@RabbitListener(queues=RabbitmqNameUtils.queueName)
	public void consume(String msg){
		//msg就是消息队列中保存的消息body
		System.out.println(msg);	
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值