目录
1.topic模式
Topic模式与Direct模式相比,他们都可以根据Routing key把消息路由到对应的队列上,但是Topic模式相较于Direct来说,它可以基于多个标准进行路由。也就是在队列绑定Routing key的时候使用通配符。使我们相较于Direct模式灵活性更大。
2.通配符的使用
"*"可以代替一个单词。
"#"可以代替零个或多个单词。
路由键必须是一串字符用 . 隔开
一个“.”代表分割符,分割成多个单词。
给queue1绑定a.#(与a的后边有一个或者多个单词的路由匹配)
给queue2绑定*.b.*(与b的前边和后边分别只有一个单词的路由匹配)
给queue3绑定*.*.c(与c的前边有两个单词的路由匹配)
3.举例
hello.hen.c(与queue3匹配)
hello.b.ds(与queue2匹配)
hello.b.c(与queue2和queue3匹配)
hello.b.c.d(全都不匹配,queue2中b的后边只有一个*,只能有一个单词,queue3中c的后边没有通配
符,不能有单词)
a.gfd.dfs(与queue1匹配,queue1中a的后边可以有多个或零个单词)
a(与queue1匹配,queue1中a的后边可以有多个或零个单词)
a.b.v.d.e.f(与queue1匹配,queue1中a的后边可以有多个或零个单词)
4.生产者代码示例
package com.sj.direct;
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 DirectBoss {
public static void main(String[] args) {
ConnectionFactory factory = new ConnectionFactory();
try {
factory.setHost("安装RabbitMQ的服务器IP");
factory.setPort(5672);
factory.setVirtualHost("/");
factory.setUsername("admin");
factory.setPassword("admin");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
//声明交换机(名称和类型)
channel.exchangeDeclare("topic01", BuiltinExchangeType.TOPIC);
String message = "直接交换模式j0,j1";
//消息发布(其中"directLogs"为交换机名称,"jay"为routingKey)
channel.basicPublish("topic01", "a.b.c.d", null, message.getBytes());
System.out.println("********Message********:发送成功");
channel.close();
connection.close();
} catch (IOException | TimeoutException e) {
e.printStackTrace();
}
}
}
5.消费者代码示例
package com.sj.direct;
import com.rabbitmq.client.*;
import javax.sound.midi.Soundbank;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
//消息消费者
public class DirectWorker {
public static void main(String[] args) {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("安装RabbitMQ的服务器IP");
factory.setPort(5672);
factory.setVirtualHost("/");
factory.setUsername("admin");
factory.setPassword("admin");
try {
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
//交换机声明(参数为:交换机名称;交换机类型)
channel.exchangeDeclare("topic01", BuiltinExchangeType.TOPIC);
//获取一个临时队列
String queueName = channel.queueDeclare().getQueue();
//队列与交换机绑定(参数为:队列名称;交换机名称;密匙-routingKey)
channel.queueBind(queueName,"topic01","*.b.*.*");
System.out.println("********Waiting for messages********");
//这里重写了DefaultConsumer的handleDelivery方法,因为发送的时候对消息进行了getByte(),在这里要重新组装成String
Consumer consumer = new DefaultConsumer(channel) {
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
super.handleDelivery(consumerTag, envelope, properties, body);
String message = new String(body,"UTF-8");
System.out.println("received:" + message);
}
};
//声明队列中被消费掉的消息(参数为:队列名称;消息是否自动确认;consumer主体)
channel.basicConsume(queueName,true,consumer);
//这里不能关闭连接,调用了消费方法后,消费者会一直连接着rabbitMQ等待消费
} catch (IOException |TimeoutException e) {
e.printStackTrace();
}
}
}