Rabbitmq基础案例
端口说明:
15672:是图形化界面访问的端口。
5672:是程序访问的端口。
消息发送方:生产者
package com.zhang.rabbitmq.simple;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
/**
* 简单模式,消息的发送方
*/
public class Producer {
public static void main(String[] args) throws Exception {
// 1.创建连接工厂
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("192.168.43.213");
connectionFactory.setPort(5672);
connectionFactory.setUsername("admin");
connectionFactory.setPassword("admin");
connectionFactory.setVirtualHost("/");
// 2.创建连接Connection
Connection connection = connectionFactory.newConnection();
// 3.通过连接获取通道Channel
Channel channel = connection.createChannel();
// 4.通过通道:创建交换机、声明队列、绑定关系、路由key、发送消息和接收消息
String queueName = "queue2";
/*
* 参数1:队列名称
* 参数2:是否持久化
* 参数3:排他性
* 参数4:是否自动删除
* 参数5:携带其他属性
* */
channel.queueDeclare(queueName,false,false,false,null);//声明队列
// 5.准备消息内容
String message = "Hello Rabbitmq!";
// 6.发送消息给队列queue
channel.basicPublish("",queueName,null,message.getBytes());
System.out.println("发送成功");
// 7.关闭通道
channel.close();
// 8.关闭连接
connection.close();
}
}
消息接收方:消费者
package com.zhang.rabbitmq.simple;
import com.rabbitmq.client.*;
import java.io.IOException;
/**
* 消息接收方
*/
public class Consumer {
public static void main(String[] args) throws Exception {
// 1.创建连接工程
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("192.168.43.213");
connectionFactory.setPort(5672);
connectionFactory.setUsername("admin");
connectionFactory.setPassword("admin");
connectionFactory.setVirtualHost("/");
// 2.创建连接Connection
Connection connection = connectionFactory.newConnection("消费者");
// 3.通过连接,获取通道Channel
Channel channel = connection.createChannel();
// 4.通过通道创建交换机、路由key、绑定关系、发送消息和接收消息、声明队列
channel.basicConsume("queue1", true, new DeliverCallback() {
面试题
1、非持久化会存盘吗?
会存盘,但是会随着重启服务而丢失数据。
2、Rabbitmq为什么是基于Channel去处理,而不是链接?
3、可以存在没有交换机的队列吗?
不会。虽然没有指定交换机,但是一定会存在一个默认的交换机。
-
一个队列可以绑定多个路由key。

Rabbitmq的模式

主题模式符号说明:
-
#:表示为:一级、多级或零级
-
*:表示为:一级,有且只有一级,而且必须要有一级,不然会报错。

fanout:发布/订阅模式
当我们需要将消息一次发给多个队列时,需要使用这种模式。
任何发送到Fanout Exchange的消息都会被转发到与该Exchange绑定(Binding)的所有 Queue上。 1.可以理解为路由表的模式 2.这种模式不需要RouteKey 3.这种模式需要提前将Exchange与Queue进行绑定,一个Exchange可以绑定多个 Queue,一个Queue可以同多个Exchange进行绑定。 4.如果接受到消息的Exchange没有与任何Queue绑定,则消息会被抛弃。
-
在图形界面中将交换机和队列绑定后,在代码中可以不用绑定。

package com.zhang.rabbitmq.routing;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
/**
* 生产者,也就是消息的发送方
* fanout:发布/订阅模式
*/
public class Producer {
public static void main(String[] args) throws Exception {
//创建连接工厂
ConnectionFactory connectionFactory = new ConnectionFactory();
//配置连接属性
connectionFactory.setHost("192.168.43.213");
connectionFactory.setPort(5672);
connectionFactory.setUsername("admin");
connectionFactory.setPassword("admin");
connectionFactory.setVirtualHost("/");
//从连接工厂中获取连接
Connection connection = connectionFactory.newConnection();
//从连接中获取通道
Channel channel = connection.createChannel();
//定义交换机
String exchangeName = "fanout-exchange";
//定义类型
String type = "fanout";
//定义路由key
String routeKey = "";
//定义消息内容
String message = "Hello fanout-exchange!";
//发送消息
for (int i = 0; i < 20; i++) {
channel.basicPublish(exchangeName, routeKey, null, message.getBytes());
}
System.out.println("消息发送成功!");
//关闭通道
channel.close();
//关闭连接
connection.close();
}
}
package com.zhang.rabbitmq.routing;
import com.rabbitmq.client.*;
import java.io.IOException;
/**
* 消费者:消息接收方
* fanout:发布/订阅模式
*/
public class Consumer {
public static Runnable runnable_name = new Runnable() {
direct:路由模式
什么是路由模式(direct)
路由模式是在使用交换机的同时,生产者指定路由发送数据,消费者绑定路由接受数据。与发布/订阅模式不同的是,发布/订阅模式只要是绑定了交换机的队列都会收到生产者向交换机推送过来的数据。而路由模式下加了一个路由设置,生产者向交换机发送数据时,会声明发送给交换机下的那个路由,并且只有当消费者的队列绑定了交换机并且声明了路由,才会收到数据。
P:消息的生产者
X:交换机
红色:队列
C1,C2:消息消费者
error,info,warning:路由

package com.zhang.rabbitmq.direct;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
/**
* 生产者,消息发送方
* direct:路由模式
*/
public class Producer {
public static void main(String[] args) throws Exception {
//创建连接工厂
ConnectionFactory connectionFactory = new ConnectionFactory();
//设置连接属性
connectionFactory.setHost("192.168.43.213");
connectionFactory.setPort(5672);
connectionFactory.setUsername("admin");
connectionFactory.setPassword("admin");
//从连接工厂中获取连接
Connection connection = connectionFactory.newConnection();
//从连接中获取通道
Channel channel = connection.createChannel();
//指定交换机
String exchangeName = "direct-exchange";
//指定类型
String type = "direct";
//发送消息的内容
String message = "Hello direct-exchange!";
//指定路由key
String routeKey = "email";
//发送消息
channel.basicPublish(exchangeName,routeKey,null,message.getBytes());
System.out.println("发送消息成功");
//关闭通道
channel.close();
//关闭连接
connection.close();
}
}
package com.zhang.rabbitmq.direct;
import com.rabbitmq.client.*;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
/**
* 消费者:消息接收方
* direct:路由模式
*/
public class Consumer {
public static Runnable runnable = new Runnable() {
主题模式
跟路由模式类似,只不过路由模式是指定固定的路由键,而主题模式是可以模糊匹配路由键,类似于SQL中=和like的关系。

package com.zhang.rabbitmq.topics;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
/**
* topics:主题模式
* 生产者:消息发送方
*/
public class Producer {
public static void main(String[] args) throws Exception {
//创建连接工厂
ConnectionFactory connectionFactory = new ConnectionFactory();
//设置连接属性
connectionFactory.setHost("192.168.43.213");
connectionFactory.setPort(5672);
connectionFactory.setUsername("admin");
connectionFactory.setPassword("admin");
connectionFactory.setVirtualHost("/");
//从连接工厂中获取连接
Connection connection = connectionFactory.newConnection("生产者");
//从连接中获取通道
Channel channel = connection.createChannel();
//创建交换机
String exchangeName = "topic-exchange";
//设置类型
String type = "topic";
//设置路由key
String routeKey = "com.course.order";
//设置发送消息的内容
String message = "Hello Topic-exchange!";
//发送消息
channel.basicPublish(exchangeName,routeKey,null,message.getBytes());
System.out.println("消息发送成功");
//关闭通道
channel.close();
//关闭连接
connection.close();
}
}
package com.zhang.rabbitmq.topics;
import com.rabbitmq.client.*;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
/**
* topics:主题模式
* 消费者:消息消费方
*/
public class Consumer {
public static Runnable runnable = new Runnable() {
绑定交换机与队列
package com.zhang.rabbitmq.all;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
/**
* 生产者:消息生产者
* 用代码生成交换机、队列,并将其绑定
* 交换机与队列的绑定,在生产者和消费者中都可以绑定
*/
public class Producer {
public static void main(String[] args) throws Exception {
// 1.创建连接工厂
ConnectionFactory connectionFactory = new ConnectionFactory();
// 2.设置连接属性
connectionFactory.setHost("192.168.43.213");
connectionFactory.setPort(5672);
connectionFactory.setUsername("admin");
connectionFactory.setPassword("admin");
connectionFactory.setVirtualHost("/");
// 3.从连接工厂中获取连接
Connection connection = connectionFactory.newConnection("生产者");
// 4.从连接中获取通道
Channel channel = connection.createChannel();
// 5.定义交换机名称
String exchangeName = "direct_message_exchange";
// 6.定义交换机类型
String exchangeType = "direct";
// 7.声明交换机 -> 交换机名称,交换机类型,是否持久化(true:持久化,服务重启不会删除交换机,false:非持久化,服务重启会删除交换机)
channel.exchangeDeclare(exchangeName,exchangeType,true);
// 8.声明队列
channel.queueDeclare("queue5",true,false,false,null);
channel.queueDeclare("queue6",true,false,false,null);
channel.queueDeclare("queue7",true,false,false,null);
// 9.绑定队列与交换机
channel.queueBind("queue5",exchangeName,"order");
channel.queueBind("queue6",exchangeName,"order");
channel.queueBind("queue7",exchangeName,"course");
// 10.创建消息内容
String message = "通过代码绑定交换机和队列!";
// 11.发送消息
channel.basicPublish(exchangeName,"course",null,message.getBytes());
System.out.println("消息发送成功!");
// 12.关闭通道
channel.close();
// 13.关闭连接
connection.close();
}
}
package com.zhang.rabbitmq.all;
import com.rabbitmq.client.*;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
/**
* 接收者:消息消费者
*/
public class Consumer {
public static Runnable runnable = new Runnable() {
工作模式队列
轮询
package com.zhang.rabbitmq.work.lunxu;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
/**
* 工作模式队列
* 轮询模式:桉均分配
*/
public class Producer {
public static void main(String[] args) throws Exception {
//创建连接工厂
ConnectionFactory connectionFactory = new ConnectionFactory();
//设置连接属性
connectionFactory.setHost("192.168.43.213");
connectionFactory.setPort(5672);
connectionFactory.setUsername("admin");
connectionFactory.setPassword("admin");
connectionFactory.setVirtualHost("/");
//从连接工厂获取连接
Connection connection = connectionFactory.newConnection("生产者");
//从连接中获取通道
Channel channel = connection.createChannel();
//创建消息内容
//发送消息
for (int i = 0; i < 20; i++) {
String message = "这是工作模式:" + (i+1);
channel.basicPublish("", "queue1", null, message.getBytes());
Thread.sleep(1000);
}
System.out.println("发送消息成功!");
//关闭通道
channel.close();
//关闭连接
connection.close();
}
}
package com.zhang.rabbitmq.work.lunxu;
import com.rabbitmq.client.*;
import java.io.IOException;
/**
* 消息接收者1
*/
public class Worek1 {
public static void main(String[] args) throws Exception {
//创建连接工厂
ConnectionFactory connectionFactory = new ConnectionFactory();
//设置连接属性
connectionFactory.setHost("192.168.43.213");
connectionFactory.setPort(5672);
connectionFactory.setUsername("admin");
connectionFactory.setPassword("admin");
connectionFactory.setVirtualHost("/");
//从连接工厂中获取连接
Connection connection = connectionFactory.newConnection("消费者");
//从连接中获取通道
Channel channel = connection.createChannel();
//接收消息
channel.basicConsume("queue1", true, new DeliverCallback() {
package com.zhang.rabbitmq.work.lunxu;
import com.rabbitmq.client.*;
import java.io.IOException;
/**
* 消息接收者2
*/
public class Worek2 {
public static void main(String[] args) throws Exception {
//创建连接工厂
ConnectionFactory connectionFactory = new ConnectionFactory();
//设置连接属性
connectionFactory.setHost("192.168.43.213");
connectionFactory.setPort(5672);
connectionFactory.setUsername("admin");
connectionFactory.setPassword("admin");
connectionFactory.setVirtualHost("/");
//从连接中工厂中获取连接
Connection connection = connectionFactory.newConnection("消费者");
//从连接中获取通道
Channel channel = connection.createChannel();
//接收消息
channel.basicConsume("queue1", true, new DeliverCallback() {
公平分发
公平分发:按劳分配,执行效率越高的消费者,所获取的消息就越多。
package com.zhang.rabbitmq.work.fair;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
/**
* 工作模式队列
* 公平分发:按劳分配,性能好的,就会多执行,反之,则少执行
* pos的值没有固定的,根据内存和磁盘来决定,一般不建议设置过大
*/
public class Producer {
public static void main(String[] args) throws Exception {
//创建连接工厂
ConnectionFactory connectionFactory = new ConnectionFactory();
//定义连接属性
connectionFactory.setHost("192.168.43.213");
connectionFactory.setPort(5672);
connectionFactory.setUsername("admin");
connectionFactory.setPassword("admin");
connectionFactory.setVirtualHost("/");
//从连接工厂中获取连接
Connection connection = connectionFactory.newConnection("生产者");
//从连接中获取通道
Channel channel = connection.createChannel();
//发送消息
for (int i = 0; i < 20; i++) {
//设置消息内容
String message = "公平分发:"+(i+1);
channel.basicPublish("","queue1",null,message.getBytes());
}
System.out.println("消息发送成功!");
//关闭通道
channel.close();
//关闭连接
connection.close();
}
}
//设置每次传输条数,没有固定值,根据cup执行率和磁盘大小决定,但是不建议设置过大。 channel.basicQos(1);
//应答模式,必须改为手动应答模式,不然执行的就为轮询模式。 channel.basicAck(delivery.getEnvelope().getDeliveryTag(),false);
package com.zhang.rabbitmq.work.fair;
import com.rabbitmq.client.*;
import java.io.IOException;
/**
* 接收者
* 公平分发模式:应答模式必须改为手动应答
*/
public class Work1 {
public static void main(String[] args) throws Exception{
//创建连接工厂
ConnectionFactory connectionFactory = new ConnectionFactory();
//定义连接属性
connectionFactory.setHost("192.168.43.213");
connectionFactory.setPort(5672);
connectionFactory.setUsername("admin");
connectionFactory.setPassword("admin");
connectionFactory.setVirtualHost("/");
//从连接工厂中获取连接
Connection connection = connectionFactory.newConnection("消费者");
//从连接中获取通道
Channel channel = connection.createChannel();
//设置每次传输条数
channel.basicQos(1);
//接收消息 -> 应答模式必须改为false,手动应答
channel.basicConsume("queue1", false, new DeliverCallback() {
package com.zhang.rabbitmq.work.fair;
import com.rabbitmq.client.*;
import java.io.IOException;
/**
* 接收者
* 公平分发模式:应答模式必须改为手动应答
*/
public class Work2 {
public static void main(String[] args) throws Exception{
//创建连接工厂
ConnectionFactory connectionFactory = new ConnectionFactory();
//定义连接属性
connectionFactory.setHost("192.168.43.213");
connectionFactory.setPort(5672);
connectionFactory.setUsername("admin");
connectionFactory.setPassword("admin");
connectionFactory.setVirtualHost("/");
//从连接工厂中获取连接
Connection connection = connectionFactory.newConnection("消费者");
//从连接中获取通道
Channel channel = connection.createChannel();
//设置每次传输条数
channel.basicQos(1);
//接收消息 -> 应答模式必须改为false,手动应答
channel.basicConsume("queue1", false, new DeliverCallback() {


浙公网安备 33010602011771号