RabbitMQ消息队列
RabbitMQ是一套开源的消息队列服务软件,实现了高级消息队列协议(AMQP),服务器采用Erlang语言开发,支持多种客户端,如:Python、Ruby、Java、JMS、C#、PHP、JavaScript等。
其特点包含:
- 异步处理:通过把消息发送给消息中间件,消息中间件并不立即处理它,而是后续再慢慢处理
- 应用解耦:单个系统出现故障,消息队列也能保证消息的可靠投递,不会导致消息丢失,降低了应用之间的耦合度
- 流量削峰:服务器在接收到用户请求后,首先写入消息队列,这时如果消息队列中消息数量超过最大数量,则直接抛弃用户请求
- 高可靠性:使用了一些机制来保证可靠性,比如持久化、传输确认、发布确认
- 高可用性:队列可以在集群中的机器上设置镜像,使得在部分节点出现问题的情况下队列仍然可用
- 灵活路由:所有的消息都会通过路由器转发到各个消息队列中,RabbitMQ内建了几个常用的路由器,并且可以通过路由器的组合以及自定义路由器插件来完成复杂的路由功能
在业务中的应用
1.创建RabbitMQ配置类
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MQConfig {
//Direct模式
public static final String QUEUE="queue";
/**
* Direct模式
*/
@Bean
public Queue queue() {
//名称,是否持久化
return new Queue(QUEUE,true);
}
}
备注:RabbitMQ安装及配置参考https://blog.csdn.net/rexueqingchun/article/details/103250554
2.创建RabbitMQ生产者
import java.util.Map;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
//生产者
@Service
public class MQSender {
@Autowired
AmqpTemplate amqpTemplate;
//Direct模式
public void send(Map<String,Object> msg) {
//第一个参数队列的名字,第二个参数发出的信息
amqpTemplate.convertAndSend(MQConfig.QUEUE, msg);
}
}
3.创建RabbitMQ消费者
import java.util.List;
import java.util.Map;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import cn.com.app.service.MiaoshaService;
//消费者
@Service
public class MQReceiver {
@Autowired
private MiaoshaService miaoshaService;
@RabbitListener(queues=MQConfig.QUEUE)//指明监听的是哪一个queue
public void receive(Map<String,Object> msg) {
int stock = 0;
//查数据库中商品库存
Map<String, Object> m = miaoshaService.queryGoodStockById(msg);
if(m != null && m.get("stock_count") != null){
stock = Integer.parseInt(m.get("stock_count").toString());
}
if(stock <= 0){//库存不足
return;
}
//这里业务是同一用户同一商品只能购买一次,所以判断该商品用户是否下过单
List<Map<String, Object>> list = miaoshaService.queryOrderByUserIdAndCoodsId(msg);
if(list != null && list.size() > 0){//重复下单
return;
}
//减库存,下订单
miaoshaService.miaosha(msg);
}
}
4.创建Redis操作工具类
import java.util.List;
import org.springframe