文章目录
1. Fanout模式和Direct模式对比
Fanout模式是由Fanout交换机向所有绑定的队列发送消息, 而Direct模式是向指定目标的队列进行消息发送, 前者是广播, 后者是匹配推送
.
fanout:
direct:
2. 编码实现Direct模式
2.1 在生产者中定义交换机和队列并进行绑定
/**
* @ClassName: RabbitMQConfiguration
* @Author zhangjin
* @Date 2021/8/15 21:24
* @Description: Direct模式, 完成交换机的创建, 队列的创建以及绑定
* 就是将FanoutExchange改成了DirectExchange并在绑定时添加.with()条件和routingKey匹配即可
*/
@Configuration
public class RabbitMQConfiguration {
/**
* Direct模式的交换机名
*/
public static final String exchangeName = "login_direct_exchange";
/**
* Direct模式的交换机, 持久化, 非自动删除的交换机
* @return DirectExchange
*/
@Bean
public DirectExchange fanoutExchange() {
return new DirectExchange(exchangeName,true,false);
}
/**
* 创建短信队列 sms.direct.queue
*/
@Bean
public Queue smsQueue() {
return new Queue("sms.direct.queue");
}
/**
* 创建邮件队列 mail.direct.queue
*/
@Bean
public Queue mailQueue() {
return new Queue("mail.direct.queue");
}
/**
* 将交换机和队列进行绑定
* Direct模式多出一个.with()条件, 用于和路由key中的字符串进行匹配
* 完成向指定队列发送信息
*/
@Bean
public Binding smsBinding() {
return BindingBuilder.bind(smsQueue()).to(fanoutExchange()).
with("sms");
}
@Bean
public Binding mailBinding() {
return BindingBuilder.bind(mailQueue()).to(fanoutExchange()).
with("mail");
}
}
2.2 登录逻辑案例–消息的生产
@Service
public class LoginService {
@Resource
private RabbitTemplate rabbitTemplate;
public void register(String phone, String userInfo) {
// 1. 将用户信息入库, 完成注册
System.out.println(phone + " 用户已入库 " + userInfo);
// 2. 将用户信息发送给指定交换机 sms; direct模式需要指定routingKey
// 只发送消息到sms队列
String routingKey = "mail"; // sms or mail
rabbitTemplate.convertAndSend(RabbitMQConfiguration.exchangeName, routingKey, userInfo);
// 也可以分别发
String routingKey2 = "sms"; // sms or mail
rabbitTemplate.convertAndSend(RabbitMQConfiguration.exchangeName, routingKey2, userInfo);
}
}
测试代码:
@SpringBootTest
class ProducerServerApplicationTests {
@Resource
private LoginService loginService;
@Test
void contextLoads() {
loginService.register("119", "这是用户信息");
}
}
执行测试用例模拟用户注册并将消息投递到相应的队列中
2.3 在消费者中编写短信服务和邮件服务完成队列中消息的消费
短信服务
@Service
@RabbitListener(queues = {"sms.direct.queue"})
public class SMSService {
@RabbitHandler
public void sandSMS(String message) {
System.out.println("向 "+message+" 发送了短信");
}
}
邮件服务
@Service
@RabbitListener(queues = {"mail.direct.queue"})
public class MailService {
@RabbitHandler
public void sandMail(String message) {
System.out.println("向 "+message+" 发送了邮件");
}
}
启动消费者工程, 查看队列中的消息被消费