摘要:业务商品有库存,如每买一个商品库存就减一减库存可以通过来实现如也可以使用来实现如面对这种场景都说要使用因为并发性能更好想实际验证一下是否这样思路设置较大的并发数去更新库存执行次比较和花费的时间代码减库存任务减库存任务分别统计次休
业务
商品有库存, 如10000 每买一个商品 库存就减一
减库存可以通过mysql来实现 如
update product_stock set stock = stock - 1 where product_id = 1 and stock > 0;
也可以使用redis来实现 如
decr 1_stock (integer) 99
面对这种场景都说要使用redis 因为redis并发性能更好 想实际验证一下是否这样
思路
设置较大的并发数去更新库存 执行10次 比较redis和mysql花费的时间
代码
@SpringBootApplication public class CocurrentUpdateStockApplication implements CommandLineRunner { @Autowired private JdbcTemplate jdbcTemplate; @Bean JedisConnectionFactory jedisConnectionFactory() { return new JedisConnectionFactory(); } @Bean RedisTemplateredisTemplate() { final RedisTemplate template = new RedisTemplate (); template.setConnectionFactory(jedisConnectionFactory()); template.setKeySerializer(new StringRedisSerializer()); template.setHashValueSerializer(new GenericToStringSerializer (Long.class)); template.setValueSerializer(new GenericToStringSerializer (Long.class)); return template; } public static void main(String[] args) { SpringApplication.run(CocurrentUpdateStockApplication.class, args); } //mysql减库存任务 private Callable updateStockInMysqlTask = () -> { final String sql = "update product_stock set stock = stock-1 where product_id=1 and stock>0"; jdbcTemplate.update(sql); return null; }; //redis减库存任务 private Callable updateStockInRedisTask = () -> { redisTemplate().execute(new RedisCallback () { public Long doInRedis(RedisConnection connection) throws DataAccessException { Long decr = connection.decr("1_stock".getBytes()); return decr; } }); return null; }; @Override public void run(String... args) throws Exception { final String name = "mysql"; // or "redis" System.out.printf("start concurrent update stock in %s...%n", name); List timeList = new ArrayList<>(); for (int i = 0; i < 10; i++) {//分别统计10次 long start = System.currentTimeMillis(); concurrentUpdateStock(name); // long end = System.currentTimeMillis(); System.out.printf("Done. Take time: %d ms%n", end - start); timeList.add(end - start); Thread.sleep(1000); //休眠1秒 } System.out.println(timeList.stream().collect(Collectors.summarizingLong(t -> t))); //输出统计结果 } private void concurrentUpdateStock(String name) throws InterruptedException { // 模拟并发更新库存 int nThreads = 500; //设置一个较大线程数 ExecutorService pool = Executors.newFixedThreadPool(nThreads); List > tasks = new ArrayList<>(); for (int i = 0; i < nThreads * 2; i++) { //2倍于线程数的减库存任务 if ("mysql".equalsIgnoreCase(name)) tasks.add(updateStockInMysqlTask); else if ("redis".equalsIgnoreCase(name)) tasks.add(updateStockInRedisTask); } List > futureList = pool.invokeAll(tasks); //并发去执行这些任务 while (futureList.stream().anyMatch(f -> !f.isDone())); //等待任务执行完 pool.shutdown(); } }
输出结果
mysql: LongSummaryStatistics{count=10, sum=11485, min=897, average=1148.500000, max=1458} redis: LongSummaryStatistics{count=10, sum=1706, min=95, average=170.600000, max=493}
结果
并发执行1000次减库存操作 mysql要比redis慢差不多7倍
完整代码见
https://github.com/zhugw/cocurrent_update_stock/blob/master/src/main/java/com/zhugw/CocurrentUpdateStockApplication.java
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/36170.html
摘要:业务商品有库存,如每买一个商品库存就减一减库存可以通过来实现如也可以使用来实现如面对这种场景都说要使用因为并发性能更好想实际验证一下是否这样思路设置较大的并发数去更新库存执行次比较和花费的时间代码减库存任务减库存任务分别统计次休 业务 商品有库存, 如10000 每买一个商品 库存就减一 减库存可以通过mysql来实现 如 update product_stock set stock ...
摘要:一为什么难秒杀系统难做的原因库存只有一份,所有人会在集中的时间读和写这些数据。又例如抢票,亦与秒杀类似,瞬时流量更甚。 一、为什么难 秒杀系统难做的原因:库存只有一份,所有人会在集中的时间读和写这些数据。例如小米手机每周二的秒杀,可能手机只有1万部,但瞬时进入的流量可能是几百几千万。又例如12306抢票,亦与秒杀类似,瞬时流量更甚。 主要需要解决的问题有两个: 高并发对数据库...
摘要:一为什么难秒杀系统难做的原因库存只有一份,所有人会在集中的时间读和写这些数据。又例如抢票,亦与秒杀类似,瞬时流量更甚。 一、为什么难 秒杀系统难做的原因:库存只有一份,所有人会在集中的时间读和写这些数据。例如小米手机每周二的秒杀,可能手机只有1万部,但瞬时进入的流量可能是几百几千万。又例如12306抢票,亦与秒杀类似,瞬时流量更甚。 主要需要解决的问题有两个: 高并发对数据库...
摘要:说明前段时间面试的时候,一直被问到如何设计一个秒杀活动,但是无奈没有此方面的实际经验,所以只好凭着自己的理解和一些资料去设计这么一个程序主要利用到了的和主要是利用它的结构去对库存进行处理,也可以用的数据结构来处理商品的库存,则用来确保用户 1 说明 前段时间面试的时候,一直被问到如何设计一个秒杀活动,但是无奈没有此方面的实际经验,所以只好凭着自己的理解和一些资料去设计这么一个程序主要利...
摘要:,大家好,很荣幸有这个机会可以通过写博文的方式,把这些年在后端开发过程中总结沉淀下来的经验和设计思路分享出来模块化设计根据业务场景,将业务抽离成独立模块,对外通过接口提供服务,减少系统复杂度和耦合度,实现可复用,易维护,易拓展项目中实践例子 Hi,大家好,很荣幸有这个机会可以通过写博文的方式,把这些年在后端开发过程中总结沉淀下来的经验和设计思路分享出来 模块化设计 根据业务场景,将业务...
阅读 1940·2023-04-26 00:09
阅读 2956·2021-09-26 10:12
阅读 3276·2019-08-30 15:44
阅读 2708·2019-08-30 13:47
阅读 803·2019-08-23 17:56
阅读 3074·2019-08-23 15:31
阅读 355·2019-08-23 13:47
阅读 2343·2019-08-23 11:56