【性能优化】秒杀系统性能优化初体验

秒杀系统性能优化

github项目地址
码云项目地址

优化之前的准备

在吞吐量、延迟和内存这三点中选择我们业务的着重点。

例如本次这个系统,我认为应该更加注重吞吐量。

为什么更加注重吞吐量?

延迟:像我们大家平时去进行商品抢购的时候,应该都会觉得现在人太多了,卡一卡没什么问题(但是也不能太久,你给我直接来个10s,肯定给你差评),只关心的是最后我有没有抢到商品。所以我认为延迟这方面应该是其次,主要的是系统处理请求的数量。

内存占用:一般秒杀活动都会有时间限制,这段时间也不会占用太大的内存。我电脑16G也不用担心,如果真的内存很缺少,可以考虑考虑。

所以在保证TP99不超过1s(抢购活动开始时,大量用户进入抢购页面)的情况下,最大的提高系统的吞吐量。

代码优化

将写入Redis缓存代码与数据库事务分开

​ 防止网络抖动可能导致写缓存响应时间较慢,阻塞数据库事务。

原始代码:

/**
 * 下订单、减库存事务(原始代码)
 */
@Transactional
public void seckillTransaction(SeckillDto seckillDto, GoodDto goodDto){
    
    //添加订单操作......
    
    //减库存操作......

    //写入缓存,不用再调用数据库判断是否还能继续抢购
    if (goodDto.getSurplusCount() <= 0){
        redisTemplate.delete(seckillDto.getGoodId().toString());
        redisTemplate.opsForValue().set(seckillDto.getGoodId().toString(), JSONObject.toJSONString(goodDto), 320, TimeUnit.SECONDS);
    }

}

修改后:

public boolean seckillGood(SeckillDto seckillDto) {
    
    // ......

    if (goodDto.getSurplusCount()>0){
        //执行下单 、 减库存事务
        seckillTransaction(seckillDto, goodDto);
        //写入缓存,不用再调用数据库判断是否还能继续抢购
        if (goodDto.getSurplusCount() - 1 <= 0){
            redisTemplate.delete(seckillDto.getGoodId().toString());
            redisTemplate.opsForValue().set(seckillDto.getGoodId().toString(), JSONObject.toJSONString(goodDto), 320, TimeUnit.SECONDS);
        }
    }

    // ......
}


/**
 * 下订单、减库存事务(修改后)
 */
@Transactional
public void seckillTransaction(SeckillDto seckillDto, GoodDto goodDto){
    log.info("seckillTransaction已调用");
    //添加订单操作......
    //减库存操作......
}

数据库相关优化

因为没弄很多数据,SQL语句也挺简单的,就不考虑那么多了。重点考虑连接池的参数设置。

连接池优化

我的电脑CPU是8核的。因为数据库连接算IO操作,所以我们将连接数在16左右进行调节。

使用的是dbcp2连接池:

​ max-wait-millis:最大等待时间

​ initial-size:连接池启动时创建的初始化连接数量

​ max-total:最大连接数

​ min-idle:最小空闲连接

​ max-idle:最大空闲连接

场景:100个请求同时对数据库进行抢购(下订单、减库存)操作,10个商品。开启了事务。

默认情况下,不配置连接参数。initialSize = 0,minIdle = 0。

在这里插入图片描述

连接数为16。initialSize = 16,minIdle = 16。

在这里插入图片描述

连接数为10。initialSize = 10,minIdle = 10。

在这里插入图片描述

连接数12。initialSize = 12,minIdle = 12。

在这里插入图片描述

连接数13。initialSize = 13,minIdle = 13。

在这里插入图片描述

TP95 TP99 吞吐量
默认 2671 2694 104.2
连接数12 2408 2431 114.5

上面的数据可以测试数据可以看出:配置了连接数之后整体操作TP99下降了260ms,吞吐量也增加了10/s。

缓存

缓存这方面其实挺多的,有前端缓存、代理服务器缓存、分布式缓存、服务端缓存等。引入缓存之后还得考虑缓存一致性、缓存穿透等问题。

因为本文只是考虑提高系统的吞吐量、延迟方面,就不仔细的考虑那么多。主要从代理服务器缓存和分布式缓存入手。

代理服务器缓存

​ 主要是将图片等静态资源放到Nginx的静态资源下(边缘缓存),就像CDN。

分布式缓存

场景:1000个同时请求,连续请求一分钟

在这里插入图片描述

未加分布式缓存:

在这里插入图片描述

在这里插入图片描述

Redis:

在这里插入图片描述

在这里插入图片描述

对比:以上数据都是在每种情况下测了至少3次取的最优的。

最小值 最大值 TP95 TP99 吞吐量
未加分布式缓存 5 1231 379 481 2368.1
Redis 5 1195 281 455 3030

上面数据可以看出,使用Redis做分布式缓存时,TP95下降了100ms,TP99下降了30ms,吞吐量更是有很大的提升,整整提高了600/s多!

未完待续......

posted @ 2021-04-27 21:59  糯米糍好吃!  阅读(149)  评论(0编辑  收藏  举报