SSM秒杀系统(十一)消息队列RabbitMQ实现异步订单

本文介绍了在秒杀系统中如何利用RabbitMQ进行订单与支付的异步处理,以提高并发量并降低服务耦合度。通过将订单信息和支付状态更新放入消息队列,再由消费者处理数据库操作,实现了订单模块的优化,包括Redis缓存的使用和消息队列的详细配置与应用。
摘要由CSDN通过智能技术生成

RabbitMQ 是实现 AMQP(高级消息队列协议)的消息中间件的一种,最初起源于金融系统,用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面表现不俗。消息中间件主要用于组件之间的解耦,消息的发送者无需知道消息使用者的存在,反之亦然。

为什么要使用消息队列?

再秒杀系统中,如果商品服务和订单服务是两个不同的微服务,在下单的过程中订单服务需要调用商品服务进行扣库存操作。按照传统的方式,下单过程要等到调用完毕之后才能返回下单成功,如果网络产生波动等原因使得商品服务扣库存延迟或者失败,会带来较差的用户体验,如果在高并发的场景下,这样的处理显然是不合适的,那怎么进行优化呢?这就需要消息队列登场了。

消息队列提供一个异步通信机制,消息的发送者不必一直等待到消息被成功处理才返回,而是立即返回。消息中间件负责处理网络通信,如果网络连接不可用,消息被暂存于队列当中,当网络畅通的时候在将消息转发给相应的应用程序或者服务,当然前提是这些服务订阅了该队列。如果在商品服务和订单服务之间使用消息中间件,既可以提高并发量,又降低服务之间的耦合度。

十五、消息队列RabbitMQ

15.1 rabbitMQ的安装与使用

1.RabbitMQ服务端代码是使用并发式语言Erlang编写的,安装Rabbit MQ的前提是安装Erlang
我下载的是19.3: http://erlang.org/download/otp_win64_19.3.exe

2.安装RabbitMQ
我是用的3.6.10的windows版本:https://www.rabbitmq.com/releases/rabbitmq-server/v3.6.10/rabbitmq-server-3.6.10.exe

3.使用RabbitMQ

rabbitmqctl status	//查看启动状态

rabbitmq-service start //开始服务

Rabbitmq-service stop  //停止服务

//插件启动和停止
rabbitmq-plugins enable rabbitmq_management //启动

rabbitmq-plugins disable rabbitmq_management //关闭

在浏览器输:http:localhost:15672进入控制台
默认的账号和密码都是 guest

15.2 消息队列使用

我们所有的订单、提交订单和支付订单都需要使用redis缓存和消息队列来实现

1.订单模块优化–redis缓存

将订单提交后的订单信息(新增订单),订单支付(订单状态更新),订单查询全部交由redis来处理,先保存在redis缓存中。

(1) OrderRedisService.java 订单缓存

public class OrderRedisServiceImpl implements OrderRedisService{
   
	
	
	@Autowired
	private RedisUtil redisUtil;
	
	/**
	 * 	将秒杀商品放到redis缓存
	 */
	public Map<String,Object> seckill(int userid, int productid,ConstomOrder msorder) {
   
		Map<String,Object> resultmap = new HashMap<String,Object>(); 
	    int stockcount = msorder.getStockcount();//库存总数
	    if(redisUtil.getkeylistsize(productid+"")> stockcount){
   
	    	System.out.println("秒杀失败");
	    	resultmap.put("success", false);
	    }
	    //将每个商品秒杀情况加入到redis的list中
	    redisUtil.pushlist(productid+"", userid+"");
	    System.out.println("秒杀成功");
	    
	    //将订单信息存放到redis
	    String key = "userid:"+userid+"==productid:"+productid;
	    String value = "";
	    //日期转换成字符串
	    String createtimestring = DateUtils.transferdate(new Date(), "yyyy-MM-dd HH:mm:ss");
	    String merchantid = msorder.getMerchantid()+"";
	    String payamount = msorder.getPayamount()+"";
	    String receivingadress = msorder.getReceivingadress();
	    String receivingname = msorder.getReceivingname();
	    String receivingphone = msorder.getReceivingphone();
	    String stockcountnum = msorder.getStockcount()+"";
	    String tradeserialnumber = createtimestring+UUID.randomUUID();
	    String paystatus = "1";
	    value += paystatus+"=="+tradeserialnumber+"=="+createtimestring+"=="+merchantid+"=="+payamount+"=="+receivingadress+"=="+receivingname+"=="+receivingphone+"=="+stockcountnum;
	    redisUtil.set(key, value);
	   
	    //返回订单信息,供action调用
	    Map<String,String> datamap = new HashMap<String,String>();
	    datamap.put("createtime", createtimestring);
	    datamap.put("merchantid", merchantid);
	    datamap.put("payamount", payamount);
	    datamap.put("receivingadress", receivingadress);
	    datamap.put("receivingname", receivingname);
	    datamap.put("receivingphone", receivingphone);
	    datamap.put("stockcountnum", stockcountnum);
	    datamap.put("tradeserialnumber", tradeserialnumber);
	    datamap.put("paystatus", paystatus);
	    datamap.put("productid", productid+"");
	    datamap.put("userid", userid+"");
	    
	    resultmap.put("success", true);
	    resultmap.put("datamap", datamap);
		return resultmap;
	}
	
	
	/**
	 * 	更新redis缓存的订单(在redis中修改订单状态)
	 */
	public boolean payorder(int paytype,int userid,int productid,int merchantid,String tradeserialnumber, int payamount){
   
		String key = "userid:"+userid+"==productid:"+productid;
		String value = (String) redisUtil.get(key);
		String[] splitvalues = value.split("==");
		splitvalues[0] = "2";
		value = "";
		//更新redis缓存里的订单状态
		for(String temp:splitvalues){
   
			value += temp+"==";
		}
		boolean issuccess = redisUtil.set(key, value);
		return issuccess;
	}
	
	//在redis中查询所有的订单
	public List<Msorder> queryorderbyuserid(int userid){
   
		List<Msorder> listmsorder = new ArrayList<Msorder>();
		Set<String> keys = redisUtil.getkeys("userid:"+userid);
		for(String key :keys){
   
			String[] prusers = key.split("==");
			if(prusers.length <= 1){
   
				continue;
			}
			String productid = prusers[1].split(":")[1]; 
			String useridstring = prusers[0].split(":")[1]; 
			String value = (String) redisUtil.get
  • 1
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值