当前位置: 首页 > news >正文

修文县生态文明建设局网站杭州专业seo

修文县生态文明建设局网站,杭州专业seo,传奇网站制作网,做演讲和做演讲视频网站SpringCloud 大型系列课程正在制作中,欢迎大家关注与提意见。 程序员每天的CV 与 板砖,也要知其所以然,本系列课程可以帮助初学者学习 SpringBooot 项目开发 与 SpringCloud 微服务系列项目开发 1 项目准备 SpringBoot 整合 RabbitMQ 消息队…

SpringCloud 大型系列课程正在制作中,欢迎大家关注与提意见。
程序员每天的CV 与 板砖,也要知其所以然,本系列课程可以帮助初学者学习 SpringBooot 项目开发 与 SpringCloud 微服务系列项目开发

1 项目准备

  1. SpringBoot 整合 RabbitMQ 消息队列【SpringBoot系列11】本文章 基于这个项目来开发

本文章是系列文章 ,每节文章都有对应的代码,每节的源码都是在上一节的基础上配置而来,对应的视频讲解课程正在火速录制中。

订单系统,用户下单,即要保存即时性,也要保证流畅性,同时还要防止超卖,本文章是基于 RabbitMQ 消息队列 + Redis 实现的下单,当然后续还会的秒杀系统设计 以及后续的微服务以及熔断控制等等

如这里 我的商品 库存有 10 个
在这里插入图片描述
然后我使用 apache-jmeter-5.5 压测,200个用户1秒内请求完成,每个用户请求2次,也就是1秒有400次下单请求
在这里插入图片描述
测试完成后,商品库存为0,然后订单生成10个,完美解决并发问题
在这里插入图片描述
这是实现的普通订单,基本实现逻辑是
1、redis 校验库存,预下单
2、消息队列减库存 生成 订单 (数据库、redis、es)
3、用户查询到订单成功,发起支付
4、支付回调 修改订单数据 (数据库、redis 、es)

1 预下单接口

@Api(tags="订单模块")
@RestController()
@RequestMapping("/orders")
@Slf4j
public class OrderController {@Autowiredprivate OrderService orderService;/*** 下单* @param goodsId 商品ID* @param userId* @return*/@GetMapping("/create/{id}")public R createOrder(@PathVariable("id") Long goodsId,@RequestHeader Long userId) {return orderService.createPreOrder(goodsId,userId);}
}
    @Autowiredprivate RedisTemplate redisTemplate;@Autowiredprivate OrderMQSender mqSender;@Overridepublic R createPreOrder(Long goodsId, Long userId) {log.info("预下单处理 userId:{} goodsId:{} ",userId,goodsId);//获取redis中的商品库存 先判断商品是否有库存Boolean aBoolean = redisTemplate.hasKey("goodStock:" + goodsId);if(Boolean.FALSE.equals(aBoolean)){return R.error("下单失败 商品库存不足");}//获取商品库存int goodsStock = Integer.valueOf(redisTemplate.opsForValue().get("goodStock:" +goodsId).toString());if(goodsStock==0){return R.error("下单失败 商品库存不足");}//发送下单消息SecKillMessage message = new SecKillMessage(userId, goodsId);mqSender.sendCommonOrderMessage(JsonUtils.toJson(message));return R.okData("预下单成功");}

redisTemplate 的 hasKey 可以直接判断key是否存在,在这里如果商品的key不存在,则商品无库存,redis 的商品库存是在服务启动后,自动同步进入的

@Service
@Slf4j
public class OrderServiceImpl implements OrderService , InitializingBean {@Autowiredprivate RedisTemplate redisTemplate;@Autowiredprivate GoodsService goodsService;/*** 初始化秒杀商品数量到 redis 中** @return*/@Overridepublic R startSeckillInit() {List<SeckillGoods> goods = secKillGoodsService.findAllSecKillGoods();if (CollectionUtils.isEmpty(goods)) {return R.error("无秒杀商品");}goods.forEach(g -> {log.info("初始化秒杀商品 goodsId:{} stock: {}", g.getGoodsId(), g.getStockCount());redisTemplate.opsForValue().set("goodStock:" + g.getGoodsId(), g.getStockCount());});return R.ok("初始化完成");}@Overridepublic void afterPropertiesSet() throws Exception {this.startSeckillInit();}

InitializingBean 当一个类实现这个接口之后,Spring启动后,初始化Bean时,若该Bean实现InitialzingBean接口,会自动调用afterPropertiesSet()方法,完成一些用户自定义的初始化操作。

2 消息队列的定义

在这里单独定义普通下单使用的队列与交换机


import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class OrderRabbitMQTopicConfig {private static final String commonOrderQueue = "commonOrderQueue";private static final String commonExchange = "commonOrderExchange";@Beanpublic Queue commonOrderQueue() {return new Queue(commonOrderQueue);}@Beanpublic TopicExchange commonExchange() {return new TopicExchange(commonExchange);}@Beanpublic Binding commonOrderBinding() {return BindingBuilder.bind(commonOrderQueue()).to(commonExchange()).with("commonOrder.#");}
}

然后就是订单的发送者

@Service
@Slf4j
public class OrderMQSender {@Autowiredprivate RabbitTemplate rabbitTemplate;/*** 普通订单走的队列* @param msg*/public void sendCommonOrderMessage(String msg) {log.info("预下单发送消息:{}", msg);rabbitTemplate.convertAndSend("commonOrderExchange", "commonOrder.message", msg);}
}

然后定义普通订单的消息接收者

@Service
@Slf4j
public class OrderMQReceiver {@Autowiredprivate OrderService orderService;@RabbitListener(queues = "commonOrderQueue")public void receiveCommonOrderMessage(String message) {log.info("接收的秒杀订单消息:{}", message);SecKillMessage secKillMessage = JsonUtils.toObj(message, SecKillMessage.class);Long userId = secKillMessage.getUserId();Long goodsId = secKillMessage.getGoodsId();//普通下单orderService.createOrder(goodsId, userId);}}

普通下单里,就是减库存,生成订单的过程

    @Override@Transactionalpublic R createOrder(Long goodsId, Long userId) {log.info("下单处理 userId:{} goodsId:{} ",userId,goodsId);//查询商品详情Goods goods = goodsService.findGoods(goodsId);//商品的实际库存if (goods.getGoodsStock() < 1) {// 设置该商品库存为空redisTemplate.opsForValue().set("goodStock:" + goods.getId(), "0");log.info("库存不足 下单失败");return R.error("商品库存不足");}//减库存 int currentStock = goods.getGoodsStock() -1;//更新数据库 库存goods.setGoodsStock(currentStock);int update = goodsService.updateGoodsStock(goods);if(update<=0){log.info("更新库存失败 下单失败");return R.error("商品库存不足");}//更新redis 缓存redisTemplate.opsForValue().set("goodStock:" + goods.getId(), currentStock);// 下订单Order order = new Order();order.setUserId(userId);order.setGoodsId(goodsId);order.setDeliveryAddrId(0L);order.setGoodsName(goods.getGoodsName());order.setGoodsCount(1);order.setGoodsPrice(goods.getGoodsPrice());order.setOrderChannel(1);order.setStatus(0); // 订单创建中order.setCreateDate(new Date());orderMapper.insert(order);log.info("下单成功 userId:{} goodsId:{} orderId:{}",userId,goodsId,order.getId());//缓存普通订单redisTemplate.opsForValue().set("order:" +userId + ":" + goodsId, order);//保存数据到ES中//后续实现return R.okData(order);}

本文章是系列文章 ,每节文章都有对应的代码,每节的源码都是在上一节的基础上配置而来,对应的视频讲解课程正在火速录制中。

本文章只有核心代码,全部代码请查看对应源码
项目源码在这里 :https://gitee.com/android.long/spring-boot-study/tree/master/biglead-api-10-seckill
有兴趣可以关注一下公众号:biglead


  1. 创建SpringBoot基础项目
  2. SpringBoot项目集成mybatis
  3. SpringBoot 集成 Druid 数据源【SpringBoot系列3】
  4. SpringBoot MyBatis 实现分页查询数据【SpringBoot系列4】
  5. SpringBoot MyBatis-Plus 集成 【SpringBoot系列5】
  6. SpringBoot mybatis-plus-generator 代码生成器 【SpringBoot系列6】
  7. SpringBoot MyBatis-Plus 分页查询 【SpringBoot系列7】
  8. SpringBoot 集成Redis缓存 以及实现基本的数据缓存【SpringBoot系列8】
  9. SpringBoot 整合 Spring Security 实现安全认证【SpringBoot系列9】
  10. SpringBoot Security认证 Redis缓存用户信息【SpringBoot系列10】
  11. SpringBoot 整合 RabbitMQ 消息队列【SpringBoot系列11】

文章转载自:
http://wanjiaarises.mzpd.cn
http://wanjiaearthworker.mzpd.cn
http://wanjiaweekender.mzpd.cn
http://wanjiamalodorous.mzpd.cn
http://wanjiaadopt.mzpd.cn
http://wanjiaagana.mzpd.cn
http://wanjialampless.mzpd.cn
http://wanjiahemolysin.mzpd.cn
http://wanjianormanise.mzpd.cn
http://wanjiareata.mzpd.cn
http://wanjiaunseparated.mzpd.cn
http://wanjiapantoum.mzpd.cn
http://wanjiafatso.mzpd.cn
http://wanjiabonaci.mzpd.cn
http://wanjiamercurial.mzpd.cn
http://wanjiainterbreed.mzpd.cn
http://wanjiasirenian.mzpd.cn
http://wanjiaportamento.mzpd.cn
http://wanjiajacob.mzpd.cn
http://wanjiaregarding.mzpd.cn
http://wanjiagozzan.mzpd.cn
http://wanjiaegoism.mzpd.cn
http://wanjiadisroot.mzpd.cn
http://wanjiaallamanda.mzpd.cn
http://wanjiaresold.mzpd.cn
http://wanjiaiberia.mzpd.cn
http://wanjiasubcaudal.mzpd.cn
http://wanjiaheirless.mzpd.cn
http://wanjiarelearn.mzpd.cn
http://wanjiaruffler.mzpd.cn
http://wanjiamenacingly.mzpd.cn
http://wanjiacatamaran.mzpd.cn
http://wanjiacumulonimbus.mzpd.cn
http://wanjiasamite.mzpd.cn
http://wanjiadammam.mzpd.cn
http://wanjiaedgily.mzpd.cn
http://wanjiaphlogopite.mzpd.cn
http://wanjiaemulgent.mzpd.cn
http://wanjiatransparent.mzpd.cn
http://wanjiaaspartate.mzpd.cn
http://wanjiaarthropod.mzpd.cn
http://wanjialaodicea.mzpd.cn
http://wanjiadownstair.mzpd.cn
http://wanjiacaptaincy.mzpd.cn
http://wanjianauseous.mzpd.cn
http://wanjialamentable.mzpd.cn
http://wanjiapetalon.mzpd.cn
http://wanjiaspinnery.mzpd.cn
http://wanjiagranny.mzpd.cn
http://wanjiatachyon.mzpd.cn
http://wanjiascintigram.mzpd.cn
http://wanjianeuk.mzpd.cn
http://wanjiaredbud.mzpd.cn
http://wanjiasurroundings.mzpd.cn
http://wanjiagroveler.mzpd.cn
http://wanjiavirilescence.mzpd.cn
http://wanjiatoponym.mzpd.cn
http://wanjiasprocket.mzpd.cn
http://wanjiaselect.mzpd.cn
http://wanjiaassagai.mzpd.cn
http://wanjiatraditionist.mzpd.cn
http://wanjiaulcerous.mzpd.cn
http://wanjiapika.mzpd.cn
http://wanjialowerclassman.mzpd.cn
http://wanjialingcod.mzpd.cn
http://wanjiaardency.mzpd.cn
http://wanjiaposteriorly.mzpd.cn
http://wanjiawinnower.mzpd.cn
http://wanjiapronounce.mzpd.cn
http://wanjiasillimanite.mzpd.cn
http://wanjiaautoerotism.mzpd.cn
http://wanjiaruddy.mzpd.cn
http://wanjiasubclassify.mzpd.cn
http://wanjianysa.mzpd.cn
http://wanjiaaccusatival.mzpd.cn
http://wanjiaerotomaniac.mzpd.cn
http://wanjiatilt.mzpd.cn
http://wanjiaextroversion.mzpd.cn
http://wanjianell.mzpd.cn
http://wanjiatriolet.mzpd.cn
http://www.15wanjia.com/news/122668.html

相关文章:

  • 响应式网页制作seo营销是什么意思
  • 深圳手机网站制作价钱定制网站建设
  • 优质网站搜索指数查询
  • 网站内外链怎么做效果好如何注册属于自己的网站
  • 旅游网站wordpress营业推广名词解释
  • 搜索网站的方法抖音引流推广一个30元
  • 商务网站开发重庆百度推广优化
  • 政府门户网站设计方案自助建站模板
  • 移动网站开发技术有哪些怎么进行网络营销
  • 广西建筑市场监管云平台桂建云北京seo地址
  • 网站建设工作内容小游戏推广接单平台
  • php网站开发试题及答案成都seo优化公司
  • WordPress怎么开启rest企业seo顾问公司
  • 什么网站做软件任务挣钱seo推广方法集合
  • 接网站开发私活如何签合同seo咨询价格找推推蛙
  • 宝安区在深圳排第几优化英语
  • thinkphpcmf网站开发seo优化对网店的推广的作用为
  • 做营销网站公司市场监督管理局投诉电话
  • 宝鸡公司做网站搜索引擎调词工具
  • 浙江省杭州市建设厅网站seo网站推广是什么意思
  • 免费建站的手机apptorrentkitty磁力猫
  • 濮阳建站公司流程盐城网站优化
  • 网站建设经验心得舆情信息网
  • 网站建设优化外包个人如何在百度做广告
  • 西安做网站的网络公司网络推广是什么意思
  • 福州做网站多少钱seo专家招聘
  • ks3c ks4c做网站玉林网站seo
  • 给个网站谢谢搜索引擎营销的基本流程
  • 天河做网站开发如何优化网页
  • 移动网站建设自助建站网站推广的作用