RabbitMQ的基本结构:
2.1.组成部分说明如下:
Broker :消息队列服务进程,此进程包括两个部分:Exchange和Queue。
Exchange :消息队列交换机,按一定的规则将消息路由转发到某个队列,对消息进行过虑。
Queue :消息队列,存储消息的队列,消息到达队列并转发给指定的消费方。
Producer :消息生产者,即生产方客户端,生产方客户端将消息发送到MQ。
Consumer :消息消费者,即消费方客户端,接收MQ转发的消息。
2.2.消息发布接收流程:
-----发送消息-----
1、生产者和Broker建立TCP连接。
2、生产者和Broker建立通道。
3、生产者通过通道消息发送给Broker,由Exchange将消息进行转发。
4、Exchange将消息转发到指定的Queue(队列)
----接收消息-----
1、消费者和Broker建立TCP连接
2、消费者和Broker建立通道
3、消费者监听指定的Queue(队列)
4、当有消息到达Queue时Broker默认将消息推送给消费者。
5、消费者接收到消息。
2.3.下载安装
RabbitMQ由Erlang语言开发,Erlang语言用于并发及分布式系统的开发,在电信领域应用广泛,OTP(Open
Telecom Platform)作为Erlang语言的一部分,包含了很多基于Erlang开发的中间件及工具库,安装RabbitMQ需
要安装Erlang/OTP,并保持版本匹配,如下图:
RabbitMQ的下载地址:http://www.rabbitmq.com/download.html
2.3.1.下载erlang
地址如下:http://erlang.org/download/otp_win64_20.3.exe
或去老师提供的软件包中找到 otp_win64_20.3.exe,以管理员方式运行此文件,安装。
erlang安装完成需要配置erlang环境变量: ERLANG_HOME=D:\Program Files\erl9.3 在path中添
加%ERLANG_HOME%\bin;
2.3.2.安装RabbitMQ
https://github.com/rabbitmq/rabbitmq-server/releases/tag/v3.7.3
2.4.启动
安装成功后会自动创建RabbitMQ服务并且启动。
2.4.1.从开始菜单启动RabbitMQ
完成在开始菜单找到RabbitMQ的菜单:
RabbitMQ Service-install :安装服务
RabbitMQ Service-remove 删除服务
RabbitMQ Service-start 启动
RabbitMQ Service-stop 启动
2.4.2.如果没有开始菜单则进入安装目录下sbin目录手动启动:
2.4.3.安装并运行服务
rabbitmq-service.bat install 安装服务 rabbitmq-service.bat stop 停止服务 rabbitmq-service.bat start 启动服务
2.4.4.安装管理插件
安装rabbitMQ的管理插件,方便在浏览器端管理RabbitMQ
管理员身份运行 rabbitmq-plugins.bat enable rabbitmq_management
2.4.5.启动成功 登录RabbitMQ
进入浏览器,输入:http://localhost:15672
初始账号和密码:guest/guest
2.4.6.注意事项
1、安装erlang和rabbitMQ以管理员身份运行。
2、当卸载重新安装时会出现RabbitMQ服务注册失败,此时需要进入注册表清理erlang
搜索RabbitMQ、ErlSrv,将对应的项全部删除。
2.5.Hello World
按照官方教程(http://www.rabbitmq.com/getstarted.html) 测试hello world:
2.5.1.搭建环境
1)java client
生产者和消费者都属于客户端,rabbitMQ的java客户端如下:
我们先用 rabbitMQ官方提供的java client测试,目的是对RabbitMQ的交互过程有个清晰的认识。
参考 :https://github.com/rabbitmq/rabbitmq-java-client/
2 )创建maven工程
创建生产者工程和消费者工程,分别加入RabbitMQ java client的依赖。
test-rabbitmq-producer:生产者工程
test-rabbitmq-consumer:消费者工程
com.rabbitmq
amqp‐client
4.0.3<!‐‐此版本与spring boot 1.5.9版本匹配‐‐>
org.springframework.boot
spring‐boot‐starter‐logging
2.5.2.生产者
在生产者工程下的test中创建测试类如下:
public class Producer01 {
//队列名称
private static final String QUEUE = “helloworld”;
public static void main(String[] args) throws IOException, TimeoutException {
Connection connection = null;
Channel channel = null;
try
{
ConnectionFactory factory = new ConnectionFactory();
factory.setHost(“localhost”);
factory.setPort(5672);
factory.setUsername(“guest”);
factory.setPassword(“guest”);
factory.setVirtualHost(“/”);//rabbitmq默认虚拟机名称为“/”,虚拟机相当于一个独立的mq服务
器
//创建与RabbitMQ服务的TCP连接
connection = factory.newConnection();
//创建与Exchange的通道,每个连接可以创建多个通道,每个通道代表一个会话任务
channel = connection.createChannel();
/**
-
声明队列,如果Rabbit中没有此队列将自动创建
-
param1:队列名称
-
param2:是否持久化
-
param3:队列是否独占此连接
-
param4:队列不再使用时是否自动删除此队列
-
param5:队列参数
*/
channel.queueDeclare(QUEUE, true, false, false, null);
String message = “helloworld小明”+System.currentTimeMillis();
/**
-
消息发布方法
-
param1:Exchange的名称,如果没有指定,则使用Default Exchange
-
param2:routingKey,消息的路由Key,是用于Exchange(交换机)将消息转发到指定的消息队列
-
param3:消息包含的属性
-
param4:消息体
*/
/**
- 这里没有指定交换机,消息将发送给默认交换机,每个队列也会绑定那个默认的交换机,但是不能显
示绑定或解除绑定
- 默认的交换机,routingKey等于队列名称
*/
channel.basicPublish(“”, QUEUE, null, message.getBytes());
System.out.println(“Send Message is:'” + message + “'”);
}
catch(Exception ex)
{
ex.printStackTrace();
}
finally
{
if(channel != null)
{
channel.close();
}
if(connection != null)
{
connection.close();
}
}
}
}
2.5.3.消费者
在消费者工程下的test中创建测试类如下:
public class Consumer01 {
private static final String QUEUE = “helloworld”;
public static void main(String[] args) throws IOException, TimeoutException {
ConnectionFactory factory = new ConnectionFactory();
//设置MabbitMQ所在服务器的ip和端口
factory.setHost(“127.0.0.1”);
factory.setPort(5672);
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
//声明队列
channel.queueDeclare(QUEUE, true, false, false, null);
//定义消费方法
DefaultConsumer consumer = new DefaultConsumer(channel) {
/**
-
消费者接收消息调用此方法
-
@param consumerTag 消费者的标签,在channel.basicConsume()去指定
-
@param envelope 消息包的内容,可从中获取消息id,消息routingkey,交换机,消息和重传标志
(收到消息失败后是否需要重新发送)
-
@param properties
-
@param body
-
@throws IOException
*/
@Override
public void handleDelivery(String consumerTag,
Envelope envelope,
AMQP.BasicProperties properties,
byte[] body)
throws IOException {
//交换机
String exchange = envelope.getExchange();
//路由key
String routingKey = envelope.getRoutingKey();
//消息id
long deliveryTag = envelope.getDeliveryTag();
//消息内容
String msg = new String(body,“utf‐8”);
System.out.println(“receive message…” + msg);
}
};
/**
-
监听队列String queue, boolean autoAck,Consumer callback
-
参数明细
-
1、队列名称
-
2、是否自动回复,设置为true为表示消息接收到自动向mq回复接收到了,mq接收到回复会删除消息,设置
为false则需要手动回复
- 3、消费消息的方法,消费者接收到消息后调用此方法
*/
channel.basicConsume(QUEUE, true, consumer);
}
}
2.5.4.总结
1、发送端操作流程
1)创建连接
2)创建通道
3)声明队列
4)发送消息
2、接收端
1)创建连接
2)创建通道
3)声明队列
4)监听队列
5)接收消息
6 )ack回复
RabbitMQ有以下几种工作模式 :
1、Work queues
2、Publish/Subscribe
3、Routing
4、Topics
5、Header
6、RPC
3.1.Work queues![在这里插入图片描述](https://img-blog.csdnimg.cn/20210713151854649.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NTczNTM1NQ==,size_16,color_FFFFFF,t_70)
work queues与入门程序相比,多了一个消费端,两个消费端共同消费同一个队列中的消息。
应用场景:对于 任务过重或任务较多情况使用工作队列可以提高任务处理的速度。
测试:
1、使用入门程序,启动多个消费者。
2、生产者发送多个消息。
结果:
1、一条消息只会被一个消费者接收;
2、rabbit采用轮询的方式将消息是平均发送给消费者的;
3、消费者在处理完某条消息后,才会收到下一条消息。
3.2.Publish/subscribe
3.2.1.工作模式
发布订阅模式:
1、每个消费者监听自己的队列。
2、生产者将消息发给broker,由交换机将消息转发到绑定此交换机的每个队列,每个绑定交换机的队列都将接收
到消息
3.2.2.代码
案例:
用户通知,当用户充值成功或转账完成系统通知用户,通知方式有短信、邮件多种方法 。
1、生产者
声明Exchange_fanout_inform交换机。
声明两个队列并且绑定到此交换机,绑定时不需要指定routingkey
发送消息时不需要指定routingkey
import com.rabbitmq.client.*;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
public class Producer02_publish {
//队列名称
private static final String QUEUE_INFORM_EMAIL = “queue_inform_email”;
private static final String QUEUE_INFORM_SMS = “queue_inform_sms”;
private static final String EXCHANGE_FANOUT_INFORM=“exchange_fanout_inform”;
public static void main(String[] args) {
Connection connection = null;
Channel channel = null;
try {
//创建一个与MQ的连接
ConnectionFactory factory = new ConnectionFactory();
factory.setHost(“127.0.0.1”);
factory.setPort(5672);
factory.setUsername(“guest”);
factory.setPassword(“guest”);
factory.setVirtualHost(“/”);//rabbitmq默认虚拟机名称为“/”,虚拟机相当于一个独立的mq服务
器
//创建一个连接
connection = factory.newConnection();
//创建与交换机的通道,每个通道代表一个会话
channel = connection.createChannel();
//声明交换机 String exchange, BuiltinExchangeType type
/**
-
参数明细
-
1、交换机名称
-
2、交换机类型,fanout、topic、direct、headers
*/
channel.exchangeDeclare(EXCHANGE_FANOUT_INFORM, BuiltinExchangeType.FANOUT);
//声明队列
// (String queue, boolean durable, boolean exclusive, boolean autoDelete, Map<String,Object> arguments)
/**
-
参数明细:
-
1、队列名称
-
2、是否持久化
-
3、是否独占此队列
-
4、队列不用是否自动删除
-
5、参数
*/
channel.queueDeclare(QUEUE_INFORM_EMAIL, true, false, false, null);
channel.queueDeclare(QUEUE_INFORM_SMS, true, false, false, null);
//交换机和队列绑定String queue, String exchange, String routingKey
/**
-
参数明细
-
1、队列名称
-
2、交换机名称
-
3、路由key
*/
channel.queueBind(QUEUE_INFORM_EMAIL,EXCHANGE_FANOUT_INFORM,“”);
channel.queueBind(QUEUE_INFORM_SMS,EXCHANGE_FANOUT_INFORM,“”);
//发送消息
for (int i=0;i<10;i++){
String message = “inform to user”+i;
//向交换机发送消息 String exchange, String routingKey, BasicProperties props,byte[] body
/**
-
参数明细
-
1、交换机名称,不指令使用默认交换机名称 Default Exchange
-
2、routingKey(路由key),根据key名称将消息转发到具体的队列,这里填写队列名称表示消
息将发到此队列
-
3、消息属性
-
4、消息内容
*/
channel.basicPublish(EXCHANGE_FANOUT_INFORM, “”, null, message.getBytes());
System.out.println(“Send Message is:'” + message + “'”);
}
} catch (IOException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}finally{
if(channel!=null){
try {
channel.close();
} catch (IOException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}
}
if(connection!=null){
try {
connection.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
2、邮件发送消费者
/**
-
@author Administrator
-
@version 1.0
-
@create 2018‐06‐14 10:32
**/
public class Consumer02_subscribe_email {
//队列名称
private static final String QUEUE_INFORM_EMAIL = “inform_queue_email”;
private static final String EXCHANGE_FANOUT_INFORM=“inform_exchange_fanout”;
public static void main(String[] args) throws IOException, TimeoutException {
//创建一个与MQ的连接
ConnectionFactory factory = new ConnectionFactory();
factory.setHost(“127.0.0.1”);
factory.setPort(5672);
factory.setUsername(“guest”);
factory.setPassword(“guest”);
factory.setVirtualHost(“/”);//rabbitmq默认虚拟机名称为“/”,虚拟机相当于一个独立的mq服务器
//创建一个连接
Connection connection = factory.newConnection();
//创建与交换机的通道,每个通道代表一个会话
Channel channel = connection.createChannel();
//声明交换机 String exchange, BuiltinExchangeType type
/**
-
参数明细
-
1、交换机名称
-
2、交换机类型,fanout、topic、direct、headers
*/
channel.exchangeDeclare(EXCHANGE_FANOUT_INFORM, BuiltinExchangeType.FANOUT);
//声明队列
// channel.queueDeclare(String queue, boolean durable, boolean exclusive, boolean autoDelete, Map<String, Object> arguments)
/**
-
参数明细:
-
1、队列名称
-
2、是否持久化
-
3、是否独占此队列
-
4、队列不用是否自动删除
-
5、参数
*/
channel.queueDeclare(QUEUE_INFORM_EMAIL, true, false, false, null);
//交换机和队列绑定String queue, String exchange, String routingKey
/**
-
参数明细
-
1、队列名称
-
2、交换机名称
-
3、路由key
*/
channel.queueBind(QUEUE_INFORM_EMAIL,EXCHANGE_FANOUT_INFORM,“”);
//定义消费方法
DefaultConsumer defaultConsumer = new DefaultConsumer(channel) {
@Override
public void handleDelivery(String consumerTag, Envelope envelope,
AMQP.BasicProperties properties, byte[] body) throws IOException {
long deliveryTag = envelope.getDeliveryTag();
String exchange = envelope.getExchange();
//消息内容
String message = new String(body, “utf‐8”);
System.out.println(message);
}
};
/**
-
监听队列String queue, boolean autoAck,Consumer callback
-
参数明细
-
1、队列名称
-
2、是否自动回复,设置为true为表示消息接收到自动向mq回复接收到了,mq接收到回复会删除消息,设置
为false则需要手动回复
- 3、消费消息的方法,消费者接收到消息后调用此方法
*/
channel.basicConsume(QUEUE_INFORM_EMAIL, true, defaultConsumer);
}
}
按照上边的代码,编写邮件通知的消费代码。
3、短信发送消费者
可参考上边的邮件发送消费者代码编写。
3.2.3.测试
打开RabbitMQ的管理界面,观察交换机绑定情况:
使用生产者发送若干条消息,每条消息都转发到各各队列,每消费者都接收到了消息。
3.2.3.思考
1、publish/subscribe与work queues有什么区别。
区别:
1)work queues不用定义交换机,而publish/subscribe需要定义交换机。
2)publish/subscribe的生产方是面向交换机发送消息,work queues的生产方是面向队列发送消息(底层使用默认
交换机)。
3)publish/subscribe需要设置队列和交换机的绑定,work queues不需要设置,实质上work queues会将队列绑
定到默认的交换机 。
相同点:
所以两者实现的发布/订阅的效果是一样的,多个消费端监听同一个队列不会重复消费消息。
2、实质工作用什么 publish/subscribe还是work queues。
建议使用 publish/subscribe,发布订阅模式比工作队列模式更强大,并且发布订阅模式可以指定自己专用的交换
机。
3.3.Routing
3.3.1.工作模式
路由模式:
1、每个消费者监听自己的队列,并且设置routingkey。
2、生产者将消息发给交换机,由交换机根据routingkey来转发消息到指定的队列。
3.3.2.代码
1、生产者
声明exchange_routing_inform交换机。
声明两个队列并且绑定到此交换机,绑定时需要指定routingkey
发送消息时需要指定routingkey
import com.rabbitmq.client.BuiltinExchangeType;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
public class Producer03_routing {
//队列名称
private static final String QUEUE_INFORM_EMAIL = “queue_inform_email”;
private static final String QUEUE_INFORM_SMS = “queue_inform_sms”;
private static final String EXCHANGE_ROUTING_INFORM=“exchange_routing_inform”;
public static void main(String[] args) {
Connection connection = null;
Channel channel = null;
try {
//创建一个与MQ的连接
ConnectionFactory factory = new ConnectionFactory();
factory.setHost(“127.0.0.1”);
factory.setPort(5672);
factory.setUsername(“guest”);
factory.setPassword(“guest”);
factory.setVirtualHost(“/”);//rabbitmq默认虚拟机名称为“/”,虚拟机相当于一个独立的mq服务
器
//创建一个连接
connection = factory.newConnection();
//创建与交换机的通道,每个通道代表一个会话
channel = connection.createChannel();
//声明交换机 String exchange, BuiltinExchangeType type
/**
-
参数明细
-
1、交换机名称
-
2、交换机类型,fanout、topic、direct、headers
*/
channel.exchangeDeclare(EXCHANGE_ROUTING_INFORM, BuiltinExchangeType.DIRECT);
//声明队列
// channel.queueDeclare(String queue, boolean durable, boolean exclusive, boolean autoDelete, Map<String, Object> arguments)
/**
-
参数明细:
-
1、队列名称
-
2、是否持久化
-
3、是否独占此队列
-
4、队列不用是否自动删除
-
5、参数
*/
channel.queueDeclare(QUEUE_INFORM_EMAIL, true, false, false, null);
channel.queueDeclare(QUEUE_INFORM_SMS, true, false, false, null);
//交换机和队列绑定String queue, String exchange, String routingKey
/**
-
参数明细
-
1、队列名称
-
2、交换机名称
-
3、路由key
*/
channel.queueBind(QUEUE_INFORM_EMAIL,EXCHANGE_ROUTING_INFORM,QUEUE_INFORM_EMAIL);
channel.queueBind(QUEUE_INFORM_SMS,EXCHANGE_ROUTING_INFORM,QUEUE_INFORM_SMS);
//发送邮件消息
for (int i=0;i<10;i++){
String message = “email inform to user”+i;
//向交换机发送消息 String exchange, String routingKey, BasicProperties props,byte[] body
/**
-
参数明细
-
1、交换机名称,不指令使用默认交换机名称 Default Exchange
-
2、routingKey(路由key),根据key名称将消息转发到具体的队列,这里填写队列名称表示消
息将发到此队列
-
3、消息属性
-
4、消息内容
*/
channel.basicPublish(EXCHANGE_ROUTING_INFORM, QUEUE_INFORM_EMAIL,null,message.getBytes());
System.out.println(“Send Message is:'” + message + “'”);
}
//发送短信消息
for (int i=0;i<10;i++){
String message = “sms inform to user”+i;
//向交换机发送消息 String exchange, String routingKey, BasicProperties props,byte[] body
channel.basicPublish(EXCHANGE_ROUTING_INFORM, QUEUE_INFORM_SMS, null,message.getBytes());
System.out.println(“Send Message is:'” + message + “'”);
}
} catch (IOException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}finally{
if(channel!=null){
try {
channel.close();
} catch (IOException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}
}
if(connection!=null){
try {
connection.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
2、邮件发送消费者
import com.rabbitmq.client.*;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
public class Consumer03_routing_email {
//队列名称
private static final String QUEUE_INFORM_EMAIL = “inform_queue_email”;
private static final String EXCHANGE_ROUTING_INFORM=“inform_exchange_routing”;
public static void main(String[] args) throws IOException, TimeoutException {
//创建一个与MQ的连接
ConnectionFactory factory = new ConnectionFactory();
factory.setHost(“127.0.0.1”);
factory.setPort(5672);
factory.setUsername(“guest”);
factory.setPassword(“guest”);
factory.setVirtualHost(“/”);//rabbitmq默认虚拟机名称为“/”,虚拟机相当于一个独立的mq服务器
//创建一个连接
Connection connection = factory.newConnection();
//创建与交换机的通道,每个通道代表一个会话
Channel channel = connection.createChannel();
//声明交换机 String exchange, BuiltinExchangeType type
/**
-
参数明细
-
1、交换机名称
-
2、交换机类型,fanout、topic、direct、headers
*/
channel.exchangeDeclare(EXCHANGE_ROUTING_INFORM, BuiltinExchangeType.DIRECT);
//声明队列
// channel.queueDeclare(String queue, boolean durable, boolean exclusive, boolean autoDelete, Map<String, Object> arguments)
/**
-
参数明细:
-
1、队列名称
-
2、是否持久化
-
3、是否独占此队列
-
4、队列不用是否自动删除
-
5、参数
*/
channel.queueDeclare(QUEUE_INFORM_EMAIL, true, false, false, null);
//交换机和队列绑定String queue, String exchange, String routingKey
/**
-
参数明细
-
1、队列名称
-
2、交换机名称
-
3、路由key
*/
channel.queueBind(QUEUE_INFORM_EMAIL,EXCHANGE_ROUTING_INFORM,QUEUE_INFORM_EMAIL);
//定义消费方法
DefaultConsumer defaultConsumer = new DefaultConsumer(channel) {
@Override
public void handleDelivery(String consumerTag, Envelope envelope,AMQP.BasicProperties properties, byte[] body) throws IOException {
long deliveryTag = envelope.getDeliveryTag();
String exchange = envelope.getExchange();
//消息内容
String message = new String(body, “utf‐8”);
System.out.println(message);
}
};
/**
-
监听队列String queue, boolean autoAck,Consumer callback
-
参数明细
-
1、队列名称
-
2、是否自动回复,设置为true为表示消息接收到自动向mq回复接收到了,mq接收到回复会删除消息,设置
为false则需要手动回复
- 3、消费消息的方法,消费者接收到消息后调用此方法
*/
channel.basicConsume(QUEUE_INFORM_EMAIL, true, defaultConsumer);
}
}
3 、短信发送消费者
可以参考邮件发送消费者的代码流程,编写短信通知的代码。
3.3.3.测试
打开RabbitMQ的管理界面,观察交换机绑定情况:
使用生产者发送若干条消息,交换机根据routingkey转发消息到指定的队列。
3.3.4.思考
Routing模式和Publish/subscibe有啥区别?
Routing模式要求队列在绑定交换机时要指定routingkey,消息会转发到符合routingkey的队列。
3.4.Topics
3.4.1.工作模式
路由模式:
1、每个消费者监听自己的队列,并且设置带统配符的routingkey。
2、生产者将消息发给broker,由交换机根据routingkey来转发消息到指定的队列。
3.4.2.代码
案例:
根据用户的通知设置去通知用户,设置接收Email的用户只接收Email,设置接收sms的用户只接收sms,设置两种
通知类型都接收的则两种通知都有效。
1、生产者
声明交换机,指定topic类型:
/**
-
声明交换机
-
param1:交换机名称
-
param2:交换机类型 四种交换机类型:direct、fanout、topic、headers
*/
channel.exchangeDeclare(EXCHANGE_TOPICS_INFORM, BuiltinExchangeType.TOPIC);
//Email通知
channel.basicPublish(EXCHANGE_TOPICS_INFORM, “inform.email”, null, message.getBytes());
//sms通知
channel.basicPublish(EXCHANGE_TOPICS_INFORM, “inform.sms”, null, message.getBytes());
//两种都通知
channel.basicPublish(EXCHANGE_TOPICS_INFORM, “inform.sms.email”, null, message.getBytes());
完整代码:完整代码:
import com.rabbitmq.client.BuiltinExchangeType;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
public class Producer04_topics {
//队列名称
private static final String QUEUE_INFORM_EMAIL = “queue_inform_email”;
private static final String QUEUE_INFORM_SMS = “queue_inform_sms”;
private static final String EXCHANGE_TOPICS_INFORM=“exchange_topics_inform”;
public static void main(String[] args) {
Connection connection = null;
Channel channel = null;
try {
//创建一个与MQ的连接
ConnectionFactory factory = new ConnectionFactory();
factory.setHost(“127.0.0.1”);
factory.setPort(5672);
factory.setUsername(“guest”);
factory.setPassword(“guest”);
factory.setVirtualHost(“/”);//rabbitmq默认虚拟机名称为“/”,虚拟机相当于一个独立的mq服务器
//创建一个连接
connection = factory.newConnection();
//创建与交换机的通道,每个通道代表一个会话
channel = connection.createChannel();
//声明交换机 String exchange, BuiltinExchangeType type
/**
-
参数明细* 1、交换机名称
-
2、交换机类型,fanout、topic、direct、headers
*/
channel.exchangeDeclare(EXCHANGE_TOPICS_INFORM, BuiltinExchangeType.TOPIC);
//声明队列
/**
-
参数明细:
-
1、队列名称
-
2、是否持久化
-
3、是否独占此队列
-
4、队列不用是否自动删除
-
5、参数
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)
![img](https://img-blog.csdnimg.cn/img_convert/5115b574d00400dec046908fe2923d9b.jpeg)
最后
金三银四到了,送上一个小福利!
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
();
factory.setHost(“127.0.0.1”);
factory.setPort(5672);
factory.setUsername(“guest”);
factory.setPassword(“guest”);
factory.setVirtualHost(“/”);//rabbitmq默认虚拟机名称为“/”,虚拟机相当于一个独立的mq服务器
//创建一个连接
connection = factory.newConnection();
//创建与交换机的通道,每个通道代表一个会话
channel = connection.createChannel();
//声明交换机 String exchange, BuiltinExchangeType type
/**
-
参数明细* 1、交换机名称
-
2、交换机类型,fanout、topic、direct、headers
*/
channel.exchangeDeclare(EXCHANGE_TOPICS_INFORM, BuiltinExchangeType.TOPIC);
//声明队列
/**
-
参数明细:
-
1、队列名称
-
2、是否持久化
-
3、是否独占此队列
-
4、队列不用是否自动删除
-
5、参数
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。[外链图片转存中…(img-vol1Dx2F-1713744909669)]
[外链图片转存中…(img-G0YeFijv-1713744909670)]
[外链图片转存中…(img-JhQuJnPS-1713744909670)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)
![img](https://img-blog.csdnimg.cn/img_convert/5115b574d00400dec046908fe2923d9b.jpeg)
最后
金三银四到了,送上一个小福利!
[外链图片转存中…(img-AJ0i8l16-1713744909670)]
[外链图片转存中…(img-HPgyFo5M-1713744909671)]
[外链图片转存中…(img-mzckWLKk-1713744909671)]
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!