Java高并发、秒杀电商项目--实战

9 篇文章 0 订阅

项目说明

注意:此项目仅为个人学习使用的项目

项目背景

这个项目是根据我在慕课网上面学习的《Java秒杀系统方案优化 高性能高并发实战》这门课程后,又加了个支付宝支付的整合的一个项目。

这是一个基于java技术的手机秒杀网站主要是学习秒杀、多并发、性能提升方面的知识。

项目环境

IDEA(Eclipse)+Maven

本地虚拟机 + centos7 (注:有真实服务器更好。可以测试更真实的压测数据。)
虚拟机安装centos7教程:https://blog.csdn.net/fangchao2011/article/details/103203305

Redis Desktop Manager:redis客户端可视化软件
Centos7安装Redis教程:
https://blog.csdn.net/fangchao2011/article/details/105687080

Centos7安装rabbitMQ教程:
https://blog.csdn.net/fangchao2011/article/details/105687237

Navicat:mysql免费可视化管理软件

jMeter:压测工具,用于对网站进行压力测试

lombok : lombok是一个可以通过简单的注解的形式来帮助我们简化消除一些必须有但显得很臃肿的 Java 代码的工具,

推荐一个前端页面代码生成的网站:http://www.ibootstrap.cn/

ProcessOn:一个画架构图以及各种图的软件

技术栈

  • Spring Boot

  • MyBatis

  • Redis, MySQL

  • Thymeleaf

  • freemarker

  • RabbitMQ

  • Durid

  • Bootstrap

  • Ajax

  • jQuery

  • javaScript

项目结构

在这里插入图片描述

项目效果图集:

登录项目后进入 秒杀商品列表:
在这里插入图片描述
点击 详情:
如果未登录则提示后跳转登录页:
在这里插入图片描述
用户登录:
在这里插入图片描述
已登入用户进入详情:
在这里插入图片描述
输入验证码进行秒杀:
重复秒杀情况:
在这里插入图片描述
秒杀成功:
在这里插入图片描述
查看秒杀成功的订单:
在这里插入图片描述
点击 “立即支付” 跳转支付宝支付页面:(沙箱模式,即测试模式)
在这里插入图片描述
付款:
在这里插入图片描述
付款成功:
在这里插入图片描述
跳转订单详情页面:
在这里插入图片描述
点击“订单详情”:
在这里插入图片描述

流程完毕。

秒杀过程图解

以下图文借鉴这篇博文:https://blog.csdn.net/silent_gods/article/details/94386454
懒得自己写文作图了。

​ 根据架构图分析一下
在这里插入图片描述

​ 1、首先用户通过任意渠道访问我们的网站,然后根据一定的路由规则(比如对用户的ID进行hash)被分配到某个服务器接受服务。(我这里没有用Nginx做负载均衡,但实际应该要做的,不然所有用户都访问同一个服务器,负载 太大。)

​ 2、当用户进行秒杀时,因为考虑到同一个时刻,并发量可能会特别大。所以不能让服务器直接访问DB,不然DB很容易挂掉,所以应该使用redis加缓存。用户在秒杀的时候在Redis中预减库存减少数据库的访问,同时使用内存标记减少redis的访问,(redis的处理能力也是有限的,负载太大也是会宕机的,所以这里也要进行Redis的保护,即加一个标记变量记录是否还有商品,如果商品已经没有了,那就置位,这样的话,后续的请求就不会去访问redis然后直接返回秒杀失败)。

​ 3、RabbitMQ队列缓冲,异步下单。因为服务器处理下单涉及DB的读写,当并发量很大的时候,需要很多时间,从而用户体验会很不好,因为需要等待很久才知道结果。所以采用消息队列异步下单。即如果用户秒杀成功,那么创建的订单并不直接写入DB。而是给rabbitmq发送一条message.然后就直接返回给用户说下单成功。然后由监听消息队列的消费者根据接收到的消息,创建订单并写入DB.这里为了提高效率,可以使用一个线程池来解决并发及连接复用的的问题。

​ 4、用户下单完成后,点击订单详情可以查看订单详情,然后选择立即支付。 可以使用支付宝支付,因为时测试,所以使用的是沙箱环境。想体验的朋友可以下载沙箱钱包来测试一下。支付完成后,可以回到商品列表继续秒杀。

优化

因为高并发系统瓶颈在数据库:

​ 根本解决方案加缓存!!!在保证数据一致性的前提下加缓存!

页面优化技术:

​ 1、页面缓存+URL缓存+对象缓存

​ 因为内存redis里面比DB要快,所以最好加各种各样的缓存,尽量少访问DB。

​ 对象级缓存,如果有更新一定要记得把数据库和缓存一起更新,这样的才能保证数据一致性。

​ 2、页面静态化,前后端分离

​ 最近比较火的,Restful 风格:前后端分离,在本项目中前端就是html+Ajax ,只传输动态参数,也就是VO对象。然后前端拿到数据后通过Ajax进行渲染。把页面等静态资源缓存在客户端,这样前端和后端之间的交互就只传输需要的参数就行。并不需要后端模板引擎吧页面渲染好然后把整个页面传到前端,极大的减少了服务器的压力和网络带宽的压力。

​ 3、静态资源优化

​ js/css压缩,减小流量。

​ 多个js/css组合。减少连接数。

​ 4、CDN优化(未涉及)

接口优化技巧:

​ 1、Redis预减库存减少数据库的访问。

​ 2、内存标记减少Redis访问。(即:如果预减库存那一步已经把flag置位,表示没有商品了。那就不应该访问redis了。这样以后的请求就可以直接返回秒杀失败,从而减少redis的压力)。

​ 3、RabbitMQ队列异步下单,增强用户体验。原理见:秒杀过程

安全优化:

​ 1、秒杀接口地址隐藏:

​ 为了防止别人提前得到接口,通过机器人来刷单。所以必须得等到秒杀开始时候才能点击按钮,此时再去请求真正的地址。然后再进行秒杀。

​ 2、数学公式验证码:

​ 数学验证码或者其他什么选字验证码之类的,主要是也是为了防止机器人刷单比如按键脚本什么的。但是对于用户来说的话不太友好。因为太麻烦了。所以这个看情况使用。

​ 3、接口防刷

​ 主要就是防止按键脚本之类的。疯狂点击秒杀按钮。这样疯狂发送请求的话,容易给服务器带来很大的压力。所以我们对每个用户进行了限定。比如每个用户1秒钟内或者3秒钟内只能点击5次按钮。超过规定的次数。就返回点击太频繁的异常提示。后台接口不处理业务,直接返回异常。这样的话可以很大程度上减少服务器的压力。

​ 具体实现:使用redis缓存服务存储每个user在一段时间内的访问次数。设置一个key和过期时间。如果在过期时间内次数超过规定次数,那就返回点击频繁异常。不进行任何操作。

项目地址:

github太慢了,没有传。
码云:https://gitee.com/jack_party/Miaosha.git

慕课网Java高并发秒杀(课程) 很好的spring,springMVC,mybatis,bootstrap,jQuery,mysql,Restful学习案例 SQL脚本 CREATE DATABASE seckill; USE seckill; -- todo:mysql Ver 5.7.12for Linux(x86_64)中一个表只能有一个TIMESTAMP CREATE TABLE seckill( `seckill_id` BIGINT NOT NUll AUTO_INCREMENT COMMENT '商品库存ID', `name` VARCHAR(120) NOT NULL COMMENT '商品名称', `number` int NOT NULL COMMENT '库存数量', `start_time` TIMESTAMP NOT NULL COMMENT '秒杀开始时间', `end_time` DATETIME NOT NULL COMMENT '秒杀结束时间', `create_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', PRIMARY KEY (seckill_id), key idx_start_time(start_time), key idx_end_time(end_time), key idx_create_time(create_time) )ENGINE=INNODB AUTO_INCREMENT=1000 DEFAULT CHARSET=utf8 COMMENT='秒杀库存表'; -- 初始化数据 INSERT into seckill(name,number,start_time,end_time) VALUES ('3000元秒杀iphone6',100,'2016-01-01 00:00:00','2016-12-31 00:00:00'), ('2000元秒杀ipad',100,'2016-01-01 00:00:00','2016-05-01 00:00:00'), ('6000元秒杀mac book pro',100,'2016-07-01 00:00:00','2016-12-31 00:00:00'), ('7000元秒杀iMac',100,'2016-05-01 00:00:00','2016-12-31 00:00:00') -- 秒杀成功明细表 -- 用户登录认证相关信息(简化为手机号) CREATE TABLE success_killed( `seckill_id` BIGINT NOT NULL COMMENT '秒杀商品ID', `user_phone` BIGINT NOT NULL COMMENT '用户手机号', `state` TINYINT NOT NULL DEFAULT -1 COMMENT '状态标识:-1:无效 0:成功 1:已付款 2:已发货', `create_time` TIMESTAMP NOT NULL COMMENT '创建时间', PRIMARY KEY(seckill_id,user_phone),/*联合主键*/ KEY idx_create_time(create_time) )ENGINE=INNODB DEFAULT CHARSET=utf8 COMMENT='秒杀成功明细表' SHOW CREATE TABLE seckill\G;#显示表的创建信息 Mybatis两个问题?①sql写在哪里?②怎么实现DAO接口?第一个问题:注解或者XML选择XML.第二个问题:Mapper自动实现DAO接口或者API编程方式实现DAO接口.选择Mapper.
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值