秒杀前端+后端

第15章-秒杀前端
课程内容:
1)了解秒杀需求

  1. 完成秒杀商品存入缓存

  2. 完成秒杀首页实现

1 秒杀业务分析
1.1 需求分析
所谓“秒杀”,就是网络卖家发布一些超低价格的商品,所有买家在同一时间网上抢购的一种销售方式。通俗一点讲就是网络商家为促销等目的组织的网上限时抢购活动。由于商品价格低廉,往往一上架就被抢购一空,有时只用一秒钟。

秒杀商品通常有两种限制:库存限制、时间限制。

需求:

(1)秒杀频道首页列出秒杀商品
(4)点击立即抢购实现秒杀下单,下单时扣减库存。当库存为0或不在活动期范围内时无法秒杀。
(5)秒杀下单成功,直接跳转到支付页面(微信扫码),支付成功,跳转到成功页,填写收货地址、电话、收件人等信息,完成订单。
(6)当用户秒杀下单5分钟内未支付,取消预订单,调用微信支付的关闭订单接口,恢复库存。
1.2 表结构说明
秒杀商品信息表

CREATE TABLE tb_seckill_goods (
id bigint(20) NOT NULL AUTO_INCREMENT,
goods_id bigint(20) DEFAULT NULL COMMENT ‘spu ID’,
item_id bigint(20) DEFAULT NULL COMMENT ‘sku ID’,
title varchar(100) DEFAULT NULL COMMENT ‘标题’,
small_pic varchar(150) DEFAULT NULL COMMENT ‘商品图片’,
price decimal(10,2) DEFAULT NULL COMMENT ‘原价格’,
cost_price decimal(10,2) DEFAULT NULL COMMENT ‘秒杀价格’,
seller_id varchar(100) DEFAULT NULL COMMENT ‘商家ID’,
create_time datetime DEFAULT NULL COMMENT ‘添加日期’,
check_time datetime DEFAULT NULL COMMENT ‘审核日期’,
status char(1) DEFAULT NULL COMMENT ‘审核状态,0未审核,1审核通过,2审核不通过’,
start_time datetime DEFAULT NULL COMMENT ‘开始时间’,
end_time datetime DEFAULT NULL COMMENT ‘结束时间’,
num int(11) DEFAULT NULL COMMENT ‘秒杀商品数’,
stock_count int(11) DEFAULT NULL COMMENT ‘剩余库存数’,
introduction varchar(2000) DEFAULT NULL COMMENT ‘描述’,
PRIMARY KEY (id)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
秒杀订单表

CREATE TABLE tb_seckill_order (
id bigint(20) NOT NULL COMMENT ‘主键’,
seckill_id bigint(20) DEFAULT NULL COMMENT ‘秒杀商品ID’,
money decimal(10,2) DEFAULT NULL COMMENT ‘支付金额’,
user_id varchar(50) DEFAULT NULL COMMENT ‘用户’,
seller_id varchar(50) DEFAULT NULL COMMENT ‘商家’,
create_time datetime DEFAULT NULL COMMENT ‘创建时间’,
pay_time datetime DEFAULT NULL COMMENT ‘支付时间’,
status char(1) DEFAULT NULL COMMENT ‘状态,0未支付,1已支付’,
receiver_address varchar(200) DEFAULT NULL COMMENT ‘收货人地址’,
receiver_mobile varchar(20) DEFAULT NULL COMMENT ‘收货人电话’,
receiver varchar(20) DEFAULT NULL COMMENT ‘收货人’,
transaction_id varchar(30) DEFAULT NULL COMMENT ‘交易流水’,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

2 秒杀商品存入缓存
1564973900738

秒杀商品由B端存入Mysql,设置定时任务,每隔一段时间就从Mysql中将符合条件的数据从Mysql中查询出来并存入缓存中,redis以Hash类型进行数据存储。

2.1 秒杀服务搭建
1)新建服务changgou_service_seckill

2)添加依赖信息,详情如下:

com.changgou changgou_common_db 1.0-SNAPSHOT org.springframework.cloud spring-cloud-starter-netflix-eureka-client com.changgou changgou_service_order_api 1.0-SNAPSHOT com.changgou changgou_service_seckill_api 1.0-SNAPSHOT com.changgou changgou_service_goods_api 1.0-SNAPSHOT org.springframework.amqp spring-rabbit org.springframework.cloud spring-cloud-starter-oauth2 3) 添加启动类

@SpringBootApplication
@EnableDiscoveryClient
@MapperScan(basePackages = {“com.changgou.seckill.dao”})
@EnableScheduling
public class SecKillApplication {

public static void main(String[] args) {
//TimeZone.setDefault(TimeZone.getTimeZone(“Asia/Shanghai”));
SpringApplication.run(SecKillApplication.class,args);
}

@Bean
public IdWorker idWorker(){
return new IdWorker(1,1);
}

/**
* 设置 redisTemplate 的序列化设置
* @param redisConnectionFactory
* @return
*/
@Bean
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
// 1.创建 redisTemplate 模版
RedisTemplate<Object, Object> template = new RedisTemplate<>();
// 2.关联 redisConnectionFactory
template.setConnectionFactory(redisConnectionFactory);
// 3.创建 序列化类
GenericToStringSerializer genericToStringSerializer = new GenericToStringSerializer(Object.class);
// 6.序列化类,对象映射设置
// 7.设置 value 的转化格式和 key 的转化格式
template.setValueSerializer(genericToStringSerializer);
template.setKeySerializer(new StringRedisSerializer());
template.afterPropertiesSet();
return template;
}

}
4) 添加application.yml

server:
port: 9011
spring:
jackson:
time-zone: GMT+8
application:
name: seckill
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://192.168.200.128:3306/changgou_seckill?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowMultiQueries=true&serverTimezone=GMT%2b8
username: root
password: root
main:
allow-bean-definition-overriding: true #当遇到同样名字的时候,是否允许覆盖注册
redis:
host: 192.168.200.128
rabbitmq:
host: 192.168.200.128
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:6868/eureka
instance:
prefer-ip-address: true
feign:
hystrix:
enabled: true
client:
config:
default: #配置全局的feign的调用超时时间 如果 有指定的服务配置 默认的配置不会生效
connectTimeout: 60000 # 指定的是 消费者 连接服务提供者的连接超时时间 是否能连接 单位是毫秒
readTimeout: 20000 # 指定的是调用服务提供者的 服务 的超时时间() 单位是毫秒
#hystrix 配置
hystrix:
command:
default:
execution:
timeout:
#如果enabled设置为false,则请求超时交给ribbon控制
enabled: true
isolation:
strategy: SEMAPHORE
thread:
# 熔断器超时时间,默认:1000/毫秒
timeoutInMilliseconds: 20000
5) 添加公钥

  1. 添加Oauth配置类

@Configuration
@EnableResourceServer
//开启方法上的PreAuthorize注解
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {

//公钥
private static final String PUBLIC_KEY = “public.key”;

/***
* 定义JwtTokenStore
* @param jwtAccessTokenConverter
* @return
/
@Bean
public TokenStore tokenStore(JwtAccessTokenConverter jwtAccessTokenConverter) {
return new JwtTokenStore(jwtAccessTokenConverter);
}

/
**
* 定义JJwtAccessTokenConverter
* @return
/
@Bean
public JwtAccessTokenConverter jwtAccessTokenConverter() {
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
converter.setVerifierKey(getPubKey());
return converter;
}
/
*
* 获取非对称加密公钥 Key
* @return 公钥 Key
/
private String getPubKey() {
Resource resource = new ClassPathResource(PUBLIC_KEY);
try {
InputStreamReader inputStreamReader = new InputStreamReader(resource.getInputStream());
BufferedReader br = new BufferedReader(inputStreamReader);
return br.lines().collect(Collectors.joining("\n"));
} catch (IOException ioe) {
return null;
}
}

/
**
* Http安全配置,对每个到达系统的http请求链接进行校验
* @param http
* @throws Exception
*/
@Override
public void configure(HttpSecurity http) throws Exception {
//所有请求必须认证通过
http.authorizeRequests()
.anyRequest().
authenticated(); //其他地址需要认证授权
}
}
7) 更改网关路径过滤类,添加秒杀工程过滤信息

1564975415777

  1. 更改网关配置文件,添加请求路由转发

#秒杀微服务
- id: changgou_seckill_route
uri: lb://seckill
predicates:
- Path=/api/seckill/**
filters:
- StripPrefix=1
2.2 时间操作
2.2.1 秒杀商品时间段分析
1564987708050

1564988365868

根据产品原型图结合秒杀商品表设计可以得知,秒杀商品是存在开始时间与结束时间的,当前秒杀商品是按照秒杀时间段进行显示,如果当前时间在符合条件的时间段范围之内,则用户可以秒杀购买当前时间段之内的秒杀商品。

缓存数据加载思路:定义定时任务,每天凌晨会进行当天所有时间段秒杀商品预加载。并且在B端进行限制,添加秒杀商品的话,只能添加当前日期+1的时间限制,比如说:当前日期为8月5日,则添加秒杀商品时,开始时间必须为6日的某一个时间段,否则不能添加。

2.2.2 秒杀商品时间段计算
将资源/DateUtil.java添加到公共服务中。基于当前工具类可以进行时间段的计算。

1564991518816

在该工具类中,进行时间计算测试:

public static void main(String[] args) {

//定义存储结果的集合
List dateList = new ArrayList<>();

//获取本日凌晨时间点
Date currentData = toDayStartHour(new Date());

//循环12次 (因为要获取每隔两个时间为一个时间段的值)
for (int i=0;i<12;i++){
dateList.add(addDateHour(currentData,i*2));
}

for (Date

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值