秒杀项目
高并发的优化:
http://blog.csdn.net/qq_33290787/article/details/51899042
业务分析与DAO层
第1章:课程介绍
1.1 秒杀API之业务分析
秒杀\红包类需求越来越常见;
1.2 项目效果演示
第2章:相关技术及搭建工程
2.1 相关技术
MySQL:1.这里我们采用手写代码创建相关表,掌握这种能力对我们以后的项目二次上线会有很大的帮助;2.SQL技巧;3.事务和行级锁的理解和一些应用。
MyBatis:1.DAO层的设计与开发。2.MyBatis的合理使用,使用Mapper动态代理的方式进行数据库的访问。3.MyBatis和Spring框架的整合:如何高效的去整合MyBatis和Spring框架。
Spring:1.Spring IOC帮我们整合Service以及Service所有的依赖。2.声明式事务。对Spring声明式事务做一些分析以及它的行为分析。
Spring MVC:1.Restful接口设计和使用。Restful现在更多的被应用在一些互联网公司Web层接口的应用上。2.框架运作流程。3.Spring Controller的使用技巧。
前端:1.交互设计。2.bootstrap。3.JQuery。设计到前端的页面代码我们直接拷贝即可,毕竟真正开发中这样一个项目是由产品经理、前端工程师、后端工程师一起完成的。
高并发:1.高并发点和高并发分析。2.优化思路并实现。
2.2 创建项目和依赖
第3章:秒杀业务分析
3.1 秒杀业务分析
3.2 mysql实现秒杀的难点
3.3 实现哪些秒杀功能
秒杀系统业务流程如下:
由图可以发现,整个系统其实是针对库存做的系统。用户成功秒杀商品,对于我们系统的操作就是:1.减库存。2.记录用户的购买明细。下面看看我们用户对库存的业务分析:
记录用户的秒杀成功信息,我们需要记录:
1.谁购买成功了。
2.购买成功的时间/有效期。
3.付款/发货信息。这些数据组成了用户的秒杀成功信息,也就是用户的购买行为。
为什么我们的系统需要事务?看如下这些故障:
1.若是用户成功秒杀商品我们记录了其购买明细却没有减库存。导致商品的超卖。
2.减了库存却没有记录用户的购买明细。导致商品的少卖。对于上述两个故障,若是没有事务的支持,损失最大的无疑是我们的用户和商家。
在MySQL中,它内置的事务机制,可以准确的帮我们完成减库存和记录用户购买明细的过程。
事务机制依然是目前最可靠的落地方案
为什么要用事务机制:
一切非关系型的数据库都可以视作Nosql。
Nosql主要追求的是性能、分布式、高可用,但对事务支持的不是很好。
MySQL实现秒杀的难点分析:当用户A秒杀id为10的商品时,此时MySQL需要进行的操作是:
1.开启事务。
2.更新商品的库存信息。
3.添加用户的购买明细,包括用户秒杀的商品id以及唯一标识用户身份的信息如电话号码等。
4.提交事务。若此时有另一个用户B也在秒杀这件id为10的商品,他就需要等待,等待到用户A成功秒杀到这件商品然后MySQL成功的提交了事务他才能拿到这个id为10的商品的锁从而进行秒杀,而同一时间是不可能只有用户B在等待,肯定是有很多很多的用户都在等待拿到这个行级锁。秒杀的难点就在这里,如何高效的处理这些竞争?
行级锁伴随着竞争,同一时间只有一个用户能够修改,其他用户都在同一时间内等待
如何高效的完成事务?在后面第4个模块如何进行高并发的优化为大家讲解。
我们这个系统需要完成秒杀的哪些功能?先来看看天猫的一个秒杀库存系统:
大家看了是不是觉得很复杂?当然不用担心,我们只是实现秒杀的一些功能:
1.秒杀接口的暴露。
2.执行秒杀的操作。
3.相关查询,比如说列表查询,详情页查询。
我们实现这三个功能即可。接下来进行具体的编码工作,首先是Dao层的编码。
第4章:DAO层设计与开发
4.1数据库设计与编码
4.2 DAO实体和接口编码
4.3 基于mybatis实现DAO层理论
4.4 基于mybatis实现DAO编程
4.5 mybatis整合spring理论
4.6 mybatis整合spring 编程
4.7 DAO层单元测试和问题排查
数据库初始化脚本
秒杀成功明细表
联合主键,防止一个用户秒杀多次
秒杀表
SeckillDao 设计<br>
1.减库存,int reduceNumber(long seckillId,Date killTime);<br>
2. 根据id查询秒杀对象 queryById(long seckillId);<br>
3. 根据偏移量查询秒杀商品列表:List<Seckill> queryALL(int offset,int limit);
秒杀详情表
SuccessKilledDao<br>
1. 插入购买明细,可过滤重复:insertSuccessKilled(long seckillId,long userPhone);<br>
2. 根据Id查询SuccessKilled并携带秒杀产品对象实体:SuccessKilled queryByIdWithSeckill(long seckillId);
mybatis的有两种方式提供SQL:
1.XML提供SQL
2.注解提供SQL
推荐利用XML提供SQL,利于维护.
Service层:
第1章:秒杀业务接口设计与实现
1.1 service开发之前说明
1.2 秒杀serviece接口设计
1.3 秒杀service接口实现
第2章:基于spring托管service实现类
2.1 使用spring托管service依赖理论
2.2 使用spring托管service依赖配置
第3章:配置并使用spring声明式事务
3.1 使用spring声明式事务理论
3.2 使用spring声明式事务配置
3.3 使用集成测试service逻辑
声明式事务的使用方式:
1.早期使用的方式:ProxyFactoryBean+XMl.
2.tx:advice+aop命名空间,这种配置的好处就是一次配置永久生效。
3.注解@Transactional的方式。在实际开发中,建议使用第三种对我们的事务进行控制,优点见下面代码中的注释。
web层:
第1章:设计restful接口
-
前端交互流程设计
-
学习restful接口设计
第2章:springmvc整合spring
2.1 使用springmvc理论
2.2 使用springmvc框架
第3章:实现秒杀相关的restful接口
3.1 使用springmvc实现restful接口
第4章:基于bootstrop开发页面结构
4.1 基于bootstrap开发页面结构
第5章: 交互逻辑编程
5.1 cookie登录交互
5.2 计时交互
5.3 秒杀交互
第6章:测试部署web接口
SpringMVC配置
高并发的优化
秒杀系统面临着如下问题:
(1)无法使用cdn缓存,因为系统逻辑不可能放在cdn中。
(2)后端缓存困难:库存问题,因为运用到了mysql事务操作(设置联合主键)。
(3)一行数据竞争:热点商品,因为多个用户同时对数据库某条数据进行操作。
秒杀系统的优化方案:
(1)前端控制:暴露接口,按钮防重复提交。
(2)动静态数据分离:cdn缓存,后端Redis缓存。
(3)事务竞争优化:减少事务锁时间,把客户端逻辑放在mysql服务端,避免网络延迟和GC的影响。 GC(Garbage Collection)垃圾回收机制
第1章:秒杀高并发优化分析
优化分析:
行级锁在Commit之后释放
优化方向减少行级锁持有的时间
判断Update更新库存成功
优化思路:
把客户端逻辑放在MySQL服务端,避免网络延迟和GC影响
使用存储过程: 整个事物在MySQL端完成。
第2章:redis后端缓存优化编码
序列化到redis
主要通过这节内容学习了redis服务端的下载,和在linux机器上的安装方法和命令,以及用jedis Java客户端操作java对象缓存的api方法,和谷歌的protostuff序列化开源方案(比Java原生的序列化效率要高)来序列化和反序列化对象,缓存对象必须转换为byte字节数组存入redis缓存,不像memcached可以直接缓存对象。实际操作思路是初次查询redis缓存,如果没有就从数据库取出对象放入redis缓存,下次取就会直接从redis缓存取数据了。但缓存有超时时间限制。
具体操作:
用jedis Java客户端操作java对象缓存的api方法,和谷歌的protostuff序列化开源Protostuff 序列化方案(比Java原生的序列化效率要高)来序列化和反序列化对象,缓存对象必须转换为byte字节数组存入redis缓存.
第3章:并发优化
简单优化 减少行级所的存在时间
深度优化 事务sql在mysql端执行,使用存储过程,整个事物在MySQL端完成。
利用存储过程将执行秒杀的一条事务逻辑放到mysql服务端去执行,减少了客户端和服务端之间的延迟和gc时间,客户端只需要传入参数执行存储过程并根据得到的返回结果做相应的逻辑处理。存储过程比较适合于简单的逻辑。
第4章:系统部署架构