秒杀系统总结

在秒杀系统中遇到的问题以及想法感悟

1.以前做的项目不叫项目,太过粗糙,没有考虑的东西太多,更谈不上优化

在这次的小项目中明确了对dto,exception,enum这些层的作用

dto:类似entity都是在封装实体,entity封装的是数据库表的实体,dto是封装结果集或者dao和service需要的实体

exception:异常层,为什么要有异常层,为了让程序更加安全,健壮,在项目中封装异常会让项目变得更加友好,另外对异常进行向上抽象

enum:枚举层,封装异常对应的提示,让项目变得对程序更加友好,以前甚至没有对枚举有过性趣,在此次项目之前甚至也不会写枚举类,现贴出以下代码

public enum SeckillStatEnum {
    SUCCESS(1,"秒杀成功"),
    END(0,"秒杀结束"),
    REPEAT_KILL(-1,"重复秒杀"),
    INNOR_ERROR(-2,"系统异常"),
    DATA_REWRITE(-3,"数据篡改");
    private int state;

    private String stateInfo;

    public int getState() {
        return state;
    }

    public String getStateInfo() {
        return stateInfo;
    }

    SeckillStatEnum(int state, String stateInfo) {
        this.state = state;
        this.stateInfo = stateInfo;
    }

    public static  SeckillStatEnum stateOf(int  index){
        for (SeckillStatEnum state: values()) {
            if(state.getState()==index){
                return state;
            }
        }
        return null;
    }
}

一般系统为了安全考虑都会采用各种加密算法,本次采用MD5算法对用户手机号进行加密:

具体操作:

private String slet="dsfwdfeferwf3wrfwerferfer";
private String getMD5(long seckillId){

    String base=seckillId+"/"+slet;
    String md5= DigestUtils.md5DigestAsHex(base.getBytes());
    return md5;
}

加入slet(颜值)为了不让别人知道算法加密规则,更加安全;

在秒杀操作之前需要有暴露秒杀接口的操作,防止被人提前知道规则,直接绕过前台提前进行秒杀,

在秒杀系统中最为重要的是秒杀操作,秒杀操作是一个事务性的,要减库存,要增加购买明细,要考虑到期间发生的各种异常

而且一般声明为运行时异常(runTimeException),spring对事物的支持是基于运行时异常的,所以想要用到spring事物,就需要声明这些运行时异常


在秒杀操作时还要注意对用户的验证,防止数据被篡改,主要是对上面暴露接口后md5进行验证,



一些优化措施

秒杀地址会有高并发:
因为用户会大量访问,会不断暴露地址
用redis,大约1秒10万访问
先去访问数据库,拿到数据之后放入redis,直接从缓存里面拿
请求地址先访问redis,然后访问mysql,因为第一次要访问mysql
,可以给缓存设置时间,比如半小时,等半小时后直接去访问mysql


秒杀操作优化:不能使用redis,因为在缓存中大量间数据,然后引起
数据不匹配,比如库存容量

某一行的热点数据会有高并发:
比如1000,秒杀iphone6,会一瞬间有大量数据


那么怎么优化秒杀高并发?

会生成一个原子计数器(记录的库存),通过redis实现
减成功后,会记录行为(也就是誰减了这一件库存),
然后放到分布式MQ当中比如kafka
后端服务消费落地
这个架构可以抗住很高的并发


到底什么让mysql变得低效

多个用户同时执行会产生行锁,当食物不提交或者不回滚
锁不会释放,大量等待

会存在GC,当gc在新生带进行工作的时候,会停止事物的操作、



优化方向:如何减少行级锁持有时间呢?

如何对update操作进行优化?
把客户端的逻辑判断放到mysql上,避免gc,因为在用java客户端和
mysql进行交互可能会引发gc

如何做?
使用存储过程整个事物放在mysql中










redis主要是对暴露接口进行优化
怎样引入redis,在pom中加入jedis得依赖


引入自定义序列化,用protostuff

在spring-dao里面注入redis



网络延迟,gc,行级锁主要构成了mysql的瓶颈


引用存储过程主要是优化事物行级锁持有的时间
放在sql中为了优化网络延迟,gc






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值