zoukankan      html  css  js  c++  java
  • 购物网站和秒杀系统实现技术

    我们需要两个模块,一个后台Admin模块,一个前台Home模块,利用ThinkPhp框架,自动生成MVC框架如图6-2所示。

     

    任何一个表单的操作,都需要前端验证和后台验证,前端验证是为了用户体验,使用javascript,后台验证是为了数据的完整性,使用php,最好的方法,是结合二者,就是ajax了。图片上传的部分,使用tp自带的上传类。

    6.3 秒杀系统

    秒杀系统其实是针对库存做的系统。用户成功秒杀商品,对于我们系统的操作就是减库存和记录用户的购买明细。用户的购买明细包括记录谁购买成功、购买成功的时间和付款信息。而对于减库存操作,需要考虑到以下两个问题:

    (1)若是用户成功秒杀商品,我们记录了其购买明细,却没有减库存。会导致商品的超卖。

    (2)减了库存却没有记录用户的购买明细,导致商品的少卖。

    对于上述两个问题,可以通过MySQL内置的事务机制进行处理,它可以准确的帮我们完成减库存和记录用户购买明细的过程。

    对于秒杀系统,我们只是实现秒杀的一些功能:

    (1)秒杀接口的暴露。

    (2)执行秒杀的操作。

    (3)相关查询,比如说列表查询,详情页查询。

    秒杀系统包括包括三个模块的设计,DAO层、Service层和Web层的设计,另外考虑到系统高并发的问题,从而设计了系统高并发的处理。在系统设计之前,为了更好地理解系统的开发过程,对相关技术进行描述。

    6.3.2 相关软件包安装

    用Maven创建我们的项目seckill,然后使用IDEA打开该项目。在 main包下进行我们项目的代码编写及相关配置文件,test包下进行我们项目的测试。

    秒杀系统的servlet版本为3.1,相关的第三发jar包通过pom文件添加,

    6.3.2 DAO层

    首先需要创建秒杀库存表和秒杀成功明细表,如下所示:

    基于MyBatis来实现我们设计的Dao层接口。首先需要配置我们的MyBatis,在resources包下创建MyBatis全局配置文件mybatis-config.xml文件。

    配置文件创建好后我们需要关注的是Dao接口该如何实现,mybatis为我们提供了mapper动态代理开发的方式为我们自动实现Dao的接口。在mapper包下创建对应Dao接口的xml映射文件,里面用于编写我们操作数据库的sql语句,SeckillDao.xml和SuccessKilledDao.xml。

    MyBatis和Spring的整合,整合目标:

    (1)更少的编码:只写接口,不写实现类。

    (2)更少的配置:别名、配置扫描映射xml文件、dao实现。

    (3)足够的灵活性:自由定制SQL语句、自由传结果集自动赋值。

    在spring包下创建一个spring-dao.xml,用于配置dao层对象的配置文件,在resources包下创建jdbc.properties.xml,用于配置数据库的连接信息,配置如下。

    6.3.3 Service层

    在Dao层我们只完成了针对表的相关操作,包括写了接口方法和映射文件中的sql语句,并没有编写逻辑的代码,例如对多个Dao层方法的拼接,当我们用户成功秒杀商品时我们需要进行商品的减库存操作(调用SeckillDao接口)和增加用户明细(调用SuccessKilledDao接口),这些逻辑我们都需要在Service层完成。Dao层只进行数据的访问操作,接下来我们便进行Service层代码的编写。秒杀Service接口设计如下:

    (1)创建service包用于存放我们的Service接口和其实现类。

    (2)创建exception包用于存放service层出现的异常,例如重复秒杀商品异常、秒杀已关闭等异常。

    (3)创建dto包作为传输层, 用于完成web和service层的数据传递。

    (4)创建entity包用于业务数据的封装。

    在dto包中创建Exposer.java,用于封装秒杀的地址信息。SeckillExecution.java,用于判断秒杀是否成功,成功就返回秒杀成功的所有信息(包括秒杀的商品id、秒杀成功状态、成功信息、用户明细),失败就抛出一个我们允许的异常(重复秒杀异常、秒杀结束异常)。

    然后需要在exception包下创建我们在秒杀业务过程中允许的异常,RepeatKillException.java用于处理重复的秒杀异常;SeckillCloseException.java用于处理秒杀关闭异常;SeckillException.java用于处理秒杀相关业务的异常。

    在实现类SeckillServiceImpl.java中,我们用枚举的方式将异常函数中返回的常量进行封装,在enums包下创建一个枚举类型SeckillStatEnum.java,用于返回state和stateInfo这两个参数的相关数据。

    使用Spring托管Service依赖配置:

    在spring包下创建一个spring-service.xml文件,然后采用注解的方式将Service的实现类加入到Spring IOC容器中,然后在Service实现类的方法中,在需要进行事务声明的方法上加上事务的注解,配置如下。

    6.3.4 Web层

    秒杀系统Web层主要涉及前端交互设计、Restful:url满足Restful设计规范、Spring MVC、bootstrap+jquery这四个方面的开发。秒杀系统的前端交互流程设计如下图6-3所示。

     

    图6-3 前端交互流程

    整合配置Spring MVC框架:

    在web.xml中进行我们前端控制器DispatcherServlet的配置,配置springMVC需要加载的配置文件spring-dao.xml,spring-service.xml和spring-web.xml,详细配置如下。

    完成Spring MVC的相关配置后,接下来就要基于Restful接口实现项目中的Controller开发。Controller中的每一个方法都对应我们系统中的一个资源URL,其设计应该遵循Restful接口的设计风格。在web包下创建一个SeckillController.java,内容如表6-11所示。

    json数据的一个Vo类,即SeckillResult.java,在dto包中创建它,内容如下。

    6.3.5 高并发的优化

    秒杀系统面临着如下问题:

    (1)无法使用cdn缓存,因为系统逻辑不可能放在cdn中。

    (2)后端缓存困难:库存问题,因为运用到了mysql事务操作(设置联合主键)。

    (3)一行数据竞争:热点商品,因为多个用户同时对数据库某条数据进行操作。

    秒杀系统的优化方案:

    (1)前端控制:暴露接口,按钮防重复提交。

    (2)动静态数据分离:cdn缓存,后端Redis缓存。

    (3)事务竞争优化:减少事务锁时间,把客户端逻辑放在mysql服务端,避免网络延迟和GC的影响。 GC(Garbage Collection)垃圾回收机制

    使用Redis优化地址暴露接口,在dao包下新建一个cache包,然后创建一个RedisDao.java函数,在spring-dao.xml中配置redisdao构造器。

    针对网络延迟和GC导致的并发问题,使用存储过程,将整个事务放在mysql端完成,秒杀存储过程实现如下。

    最后,在ServiceService.java中建立存储执行秒杀操作的函数,在SeckillDao.java实现该接口,在SeckillDao.xml中使用mybatis调用存储过程,在服务端的SeckillServiceImpl.java完成配置即可。

  • 相关阅读:
    swift 第十四课 可视化view: @IBDesignable 、@IBInspectable
    swift 第十三课 GCD 的介绍和使用
    swift 第十二课 as 的使用方法
    swift 第十一课 结构体定义model类
    swift 第十课 cocopod 网络请求 Alamofire
    swift 第九课 用tableview 做一个下拉菜单Menu
    swift 第八课 CollectView的 添加 footerView 、headerView
    swift 第七课 xib 约束的优先级
    swift 第六课 scrollview xib 的使用
    swift 第五课 定义model类 和 导航栏隐藏返回标题
  • 原文地址:https://www.cnblogs.com/smuxiaolei/p/7542903.html
Copyright © 2011-2022 走看看