RobbitMQ消息队列
处理异步处理,应用解耦,流量削峰,使用消息服务可以实现高性能,高可用,高扩展系统
相比其它产品并发性强
Kadka 和 RocketMQ的处理大数据请求更强
原理:
3个角色 消息生产者 消息代理者(RobbitMq) 消息消费者
消息生产者与消息代理者建立长连接 中间有小连接
消息代理者:
2个组件:Exchange 消息交换机 Queue队列
交换机将消息 转发给队列
消息消费者:
与代理者建立长连接 ,监听队列
5种工作模式:
Work queues 工作队列模式:
不需要交换机 但需要指定队列 ,每个队列绑定多个消费者。
消费者通过轮询的方式依次处理队列的消息
Pubish/Subscribe 发布队列模式:
需要fanout类型交换机
交换机可以绑定多个队列,不用指定路由键,会把消息转发给所有队列。
一个队列的所有消费者还是轮询处理消息
Routing路由模式
交换机类型 :direct
需要指定路由键(Routing key)将消息发到不同的消息队列中存储
Topics通配符:
交换机类型:Topic
指定不同的路由键进行转发到队列
*表示匹配一个字符 #表示匹配多个字符
RPC模式:
消费者和生产者回环
整合Spirngboot:
1.添加依赖![外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传](https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=C%3A%5CUsers%5C%E5%86%89%E6%AF%93%5CAppData%5CRoaming%5CTypora%5Ctypora-user-images%5Cimage-20240517115452132.png&pos_id=img-6vWSmLxv-1718805552281)
2.添加配置
spring:
rabbitmq:
host: localhost
port: 5672
username: guest
password: guest
#setting RabbitMQ virtual host path , default can be ignored
virtual-host: /
3.配置类
package com.example.robbitmqlearn.config;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.FanoutExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author
*/
@Configuration
public class RabbitMqConfig {
//定义常量
/**
* 定义一个交换机名称
*/
public static final String FANOUT_EXCHANGE="fanout_exchange";
/**
* 定义2个小希队列
*/
public static final String SMS_QUEUE_NAME="sms_queue";
public static final String EMAIL_QUEUE_NAME="email_queue";
//定义fanout类型的交换机
@Bean
public FanoutExchange fanoutExchange(){
return new FanoutExchange(FANOUT_EXCHANGE,true,false);
}
//定义存储sms消息的队列
@Bean
public Queue smsQueue(){
return new Queue(SMS_QUEUE_NAME,true);
}
//定义存储email消息的队列
@Bean
public Queue emailQueue(){
return new Queue(EMAIL_QUEUE_NAME,true);
}
//将队列和交换机进行绑定
@Bean
public Binding bindingSms(){
return BindingBuilder.bind(smsQueue()).to(fanoutExchange());
}
@Bean
public Binding bindingEmail(){
return BindingBuilder.bind(emailQueue()).to(fanoutExchange());
}
}
4.控制器中直接使用模版
@Controller
public class UserController {
@Autowired
private RabbitTemplate rabbitTemplate;
@RequestMapping("/register")
@ResponseBody
public String add(User user){
user.setUserName("122");
user.setEmail("@qq.com");
user.setTel("123tel");
//选交换机和 发送的message
rabbitTemplate.convertAndSend(RabbitMqConfig.FANOUT_EXCHANGE,"",user);
return "用户注册成功";
}
}
因为默认的消息转换器(SimpleMessageConverter)只支持Spring、byte[]和Serializable序列化后的消息
5.添加组件
/**
* 类型的消息转换器组件 将返回类型变为MessageConverter
* @return
*/
@Bean
public MessageConverter messageConverter(){
return new Jackson2JsonMessageConverter();
}
6.监听消息队列
当消息队列有内容时 直接调用以下方法
@RabbitListener注解指定队列
@Component()
public class RabbitMQLister {
@RabbitListener(queues = RabbitMqConfig.EMAIL_QUEUE_NAME)
public void subEmail(User user){
System.out.println("email:"+user.getEmail());
}
@RabbitListener(queues = RabbitMqConfig.SMS_QUEUE_NAME)
public void subSms(User user){
System.out.println("sms:"+user.getTel());
}
}
n(“email:”+user.getEmail());
}
@RabbitListener(queues = RabbitMqConfig.SMS_QUEUE_NAME)
public void subSms(User user){
System.out.println(“sms:”+user.getTel());
}
}