五大模式
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);
}
}