RabbitMq启动后打开浏览器管理页面localhost:15672/
<dependency>
<groupId>com.rabbitmq</groupId>
<artifactId>amqp-client</artifactId>
<version>4.0.3</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>sprinf-boot-starter-logging</artifactId>
</dependency>import java.io.IOException;
import java.util.concurrent.TimeoutException;
public class RabbitMq{
public void producer() {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("127.0.0.1");
factory.setPort(5672);
factory.setUsername("guest");
factory.setPassword("guest");
factory.setVirtualHost("/");
Connection connection = null;
Channel channel = null;
try {
connection = factory.newConnection();
channel = connection.createChannel();
/**
* var1:队列名称
* var2:是否持久化
* var3:是否独占此链接,独占表示只在本链接中使用队列,链接断开队列消失
* var4:自动删除。队列不再使用时自动删除队列,var3、var4同时为true可以创建临时队列
* var5:其他参数
*/
channel.queueDeclare("短信通知",true,false,false,null);
channel.queueDeclare("邮件通知",true,false,false,null);
/**
* var1:交换机名称
* var2:交换机类型
* fanout:publish/subscribe工作模式
* direct:routing工作模式
* topic:topics工作模式
* headers:headers工作模式
*/
channel.exchangeDeclare("交换机名称",BuiltinExchangeType.DIRECT);
/**
* 交换机和队列绑定
* var1:队列名称
* var2:交换机名称
* var3:路由key
* 发布订阅模式路由key为空字符串
* 交换机根据路由key的值将消息转发到指定队列中
*/
channel.queueBind("短信通知","交换机名称","SMS");
channel.queueBind("邮件通知","交换机名称","EMAIL");
byte[] bytes = "消息内容".getBytes();
/**
* var1:交换机
* var2:routingkey
* var3:消息属性
* var4:消息内容
*/
channel.basicPublish("交换机名称","SMS",null,bytes);
} catch (IOException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}finally {
try {
channel.close();
} catch (IOException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}
try {
connection.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void consumer() throws IOException, TimeoutException {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("127.0.0.1");
factory.setPort(5672);
factory.setUsername("guest");
factory.setPassword("guest");
factory.setVirtualHost("/");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
channel.queueDeclare("短信通知",true,false,false,null);
channel.exchangeDeclare("交换机名称",BuiltinExchangeType.DIRECT);
channel.queueBind("短信通知","交换机名称","联通SMS");
channel.queueBind("短信通知","交换机名称","移动SMS");
DefaultConsumer defaultConsumer = new DefaultConsumer(channel){
/**
* @param s 消费者标签,在监听队列时设置channel.basicConsume
* @param envelope 可获得exchange/deliveryTag(消息ID)
* @param basicProperties 消息属性
* @param bytes 消息内容
* @throws IOException
*/
@Override
public void handleDelivery(String s, Envelope envelope, AMQP.BasicProperties basicProperties, byte[] bytes) throws IOException {
String message = new String(bytes);
}
}
/**
* var1:队列名称
* var2:接受消息是否自动回复;不回复消息一直存在队列,可编程回复。
* var3:
*/
channel.basicConsume("短信通知",true,defaultConsumer);
}
}
工作模式:
1.WorkQueues(工作队列模式):一个生产者、一个队列、多个消费者。多个消费者监听一个队列,消息不能被重复消费,采用轮询方式将消息平均发送给消费者。
2.publish/subscribe(发布订阅模式):一个消费者将消息发送给交换机,交换机转发到绑定此交换机的多个队列。如果消息发送到没有绑定队列的交换机上,消息将丢失。
使用场景:支付成功后,以邮件、短信两种方式通知用户。
3.Routing(路由模式):一个交换机绑定多个队列,每个队列绑定一个或多个routingkey。生产者将消息发送给交换机,消息需指定routingkey,交换机通过routingkey来判断转发给哪个队列。
4.Topics(通配符模式):与Routing不同之处是routingKey的匹配方式,Routing模式相等匹配,Topics模式通配符匹配
#:匹配一个或多个词。inform.#可以匹配inform.email/inform.sms.联通/inform.sms.移动
*:匹配一个词。inform.*可以匹配inform.email/inform.sms
5.Header:与Routing模式不同在于Header取消routingKey,使用header中的key/value匹配队列。代码变化如下:
![]()
6.RPC:使用MQ基于direct交换机实现RPC异步调用。客户端、服务端既是生产者也是消费者。客户端作生产者向队列A发送消息,服务端监听队列A获取消息,执行完毕后服务端向队列B发送消息,客户端作为消费者监听队列B接收消息。
![]()