1. 需求:根据时间段搜索mysql的秒杀商品列表
1.查询活动没结束的所有秒杀商品
1)状态必须为审核通过 status=1
2)商品库存个数>0
3)活动没有结束 endTime>=now()
4)在Redis中没有该商品的缓存
5)执行查询获取对应的结果集
2.将活动没有结束的秒杀商品入库
2.定时任务
package com.changgou.seckill.task;
import com.changgou.order.pojo.SeckillGoods;
import com.changgou.seckill.dao.SeckillGoodsMapper;
import entity.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import tk.mybatis.mapper.entity.Example;
import java.util.Date;
import java.util.List;
import java.util.Set;
/**
* @ClassName HelloController
* @Description TODO
* @Author zengjx
* @Company zengjx
* @Date 2019/11/29 18:39
* @Version V1.0
*/
@Slf4j
@Component
public class SeckillGoodsPushTask {
@Autowired
private SeckillGoodsMapper seckillGoodsMapper;
@Autowired
private RedisTemplate redisTemplate;
/**
* 30秒执行一次
*/
@Scheduled(cron = "1/5 * * * * *")
public void loadGooPushTask(){
// redisTemplate.boundHashOps("SeckillGoods_" +"2019113010").delete();
log.info("定时器被调度了"); System.out.println("定时任务被调度了...");
//获取时间段集合
List<Date> dateMenus = DateUtil.getDateMenus();
//循环时间段
for (Date startTime : dateMenus) {
// namespace = SeckillGoods_20195712---- 时间转成str
String extName = DateUtil.data2str(startTime, DateUtil.PATTERN_YYYYMMDDHH);
//根据时间段数据查询对应的秒杀商品数据
Example example = new Example(SeckillGoods.class);
Example.Criteria criteria = example.createCriteria();
// 1)商品必须审核通过 status=1
criteria.andEqualTo("status", "1");
// 2)库存>0
criteria.andGreaterThan("stockCount", 0);
// 3)开始时间<=活动开始时间
criteria.andGreaterThanOrEqualTo("startTime", startTime);
// 4)活动结束时间<开始时间+2小时 以开始时间为准
Date end= DateUtil.addDateHour(startTime, 2);
String endtime =DateUtil.data2str(end,DateUtil.PATTERN_YYYYMMDDHH);
log.info("extName ------"+extName+" ----" +endtime);
criteria.andLessThan("endTime", DateUtil.addDateHour(startTime, 2));
// 5)排除之前已经加载到Redis缓存中的商品数据-----会对库存有影响
Set keys = redisTemplate.boundHashOps("SeckillGoods_" + extName).keys();//商品id 列表
if (keys != null && keys.size() > 0) {//如果有这个再追不然sql会报错
criteria.andNotIn("id", keys);
}
//查询数据
List<SeckillGoods> seckillGoods = seckillGoodsMapper.selectByExample(example);
System.out.println(extName + "时段导入商品个数为:" + seckillGoods.size());
//将秒杀商品数据存入到Redis缓存
if(seckillGoods.size()>0){
}
for (SeckillGoods seckillGood : seckillGoods) {
redisTemplate.boundHashOps("SeckillGoods_" + extName).put(seckillGood.getId(), seckillGood);
}
}
}
}
3.application.yml 配置
server:
port: 18091
spring:
application:
name: seckill
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.211.132:3306/changgou_seckill?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
username: root
password: 123456
rabbitmq:
host: 192.168.211.132 #mq的服务器地址
username: guest #账号
password: guest #密码
main:
allow-bean-definition-overriding: true
redis:
host: 192.168.211.132
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:7001/eureka
instance:
prefer-ip-address: true
feign:
hystrix:
enabled: true
#hystrix 配置
hystrix:
command:
default:
execution:
timeout:
#如果enabled设置为false,则请求超时交给ribbon控制
enabled: true
isolation:
thread:
timeoutInMilliseconds: 10000
strategy: SEMAPHORE
4. 问题: 时间段与搜索结果具体商品时间不对应
搜索出来的秒杀商品实际时间与预期时间相差 8小时或者搜索不显示商品
redis 显示:
6.排查方法 :添加日志显示功能
application.yml 添加 打印sql 语句
server:
port: 18091
spring:
application:
name: seckill
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.211.132:3306/changgou_seckill?useUnicode=true&characterEncoding=UTF-8
username: root
password: 123456
rabbitmq:
host: 192.168.211.132 #mq的服务器地址
username: guest #账号
password: guest #密码
main:
allow-bean-definition-overriding: true
redis:
host: 192.168.211.132
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:7001/eureka
instance:
prefer-ip-address: true
feign:
hystrix:
enabled: true
#hystrix 配置
hystrix:
command:
default:
execution:
timeout:
#如果enabled设置为false,则请求超时交给ribbon控制
enabled: true
isolation:
thread:
timeoutInMilliseconds: 10000
strategy: SEMAPHORE
logging:
level:
com:
changgou: debug
logging:
level:
com:
changgou: debug
https://www.jb51.net/article/133795.htm
7.
019120200时段导入商品个数为:0
2019-12-01 19:40:58.095 INFO 7984 --- [ scheduling-1] c.c.seckill.task.SeckillGoodsPushTask : extName ------2019120202 ----2019120204
2019-12-01 19:40:58.097 DEBUG 7984 --- [ scheduling-1] c.c.s.d.S.selectByExample : ==> Preparing: SELECT id,sup_id,sku_id,name,small_pic,price,cost_price,create_time,check_time,status,start_time,end_time,num,stock_count,introduction FROM tb_seckill_goods WHERE ( status = ? and stock_count > ? and start_time >= ? and end_time < ? )
2019-12-01 19:40:58.098 DEBUG 7984 --- [ scheduling-1] c.c.s.d.S.selectByExample : ==> Parameters: 1(String), 0(Integer), 2019-12-02 02:00:00.0(Timestamp), 2019-12-02 04:00:00.0(Timestamp)
2019-12-01 19:40:58.583 DEBUG 7984 --- [ scheduling-1] c.c.s.d.S.selectByExample : <== Total: 0
2019120202时段导入商品个数为:0
2019-12-01 19:41:01.001 INFO 7984 --- [ scheduling-1] c.c.seckill.task.SeckillGoodsPushTask : 定时器被调度了
定时任务被调度了...
2019-12-01 19:41:01.001 INFO 7984 --- [ scheduling-1] c.c.seckill.task.SeckillGoodsPushTask : extName ------2019120118 ----2019120120
2019-12-01 19:41:01.006 DEBUG 7984 --- [ scheduling-1] c.c.s.d.S.selectByExample : ==> Preparing: SELECT id,sup_id,sku_id,name,small_pic,price,cost_price,create_time,check_time,status,start_time,end_time,num,stock_count,introduction FROM tb_seckill_goods WHERE ( status = ? and stock_count > ? and start_time >= ? and end_time < ? and id not in ( ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? ) )
2019-12-01 19:41:01.007 DEBUG 7984 --- [ scheduling-1] c.c.s.d.S.selectByExample : ==> Parameters: 1(String), 0(Integer), 2019-12-01 18:00:00.0(Timestamp), 2019-12-01 20:00:00.0(Timestamp), 1131815859216584704(Long), 1131815858981703680(Long), 1131815858813931520(Long), 1131815859032035328(Long), 1131815859170447360(Long), 1131815858897817600(Long), 1131815858872651776(Long), 1131815858956537856(Long), 1131815858973315072(Long), 1131815858927177728(Long), 1131815858822320128(Long), 1131815858843291648(Long), 1131815859191418880(Long), 1131815859053006848(Long), 1131815858943954944(Long), 1131815858834903040(Long), 1131815858851680256(Long), 1131815859136892928(Long), 1131815858801348608(Long), 1131815859162058752(Long), 1131815859094949888(Long), 1131815859199807488(Long), 1131815859078172672(Long), 1131815859208196096(Long), 1131815858906206208(Long), 1131815858935566336(Long), 1131815859006869504(Long), 1131815858960732160(Long)
2019-12-01 19:41:01.473 DEBUG 7984 --- [ scheduling-1] c.c.s.d.S.selectByExample : <== Total: 0
2019120118时段导入商品个数为:0
2019-12-01 19:41:01.473 INFO 7984 --- [ scheduling-1] c.c.seckill.task.SeckillGoodsPushTask : extName ------2019120120 ----2019120122
2019-12-01 19:41:01.476 DEBUG 7984 --- [ scheduling-1] c.c.s.d.S.selectByExample : ==> Preparing: SELECT id,sup_id,sku_id,name,small_pic,price,cost_price,create_time,check_time,status,start_time,end_time,num,stock_count,introduction FROM tb_seckill_goods WHERE ( status = ? and stock_count > ? and start_time >= ? and end_time < ? and id not in ( ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? ) )
2019-12-01 19:41:01.476 DEBUG 7984 --- [ scheduling-1] c.c.s.d.S.selectByExample : ==> Parameters: 1(String), 0(Integer), 2019-12-01 20:00:00.0(Timestamp), 2019-12-01 22:00:00.0(Timestamp), 1131815859313053696(Long), 1131815859594072064(Long), 1131815859422105600(Long), 1131815859304665088(Long), 1131815859375968256(Long), 1131815859250139136(Long), 1131815859279499264(Long), 1131815859354996736(Long), 1131815859296276480(Long), 1131815859233361920(Long), 1131815859334025216(Long), 1131815859581489152(Long), 1131815859497603072(Long), 1131815859526963200(Long), 1131815859489214464(Long), 1131815859438882816(Long), 1131815859283693568(Long), 1131815859241750528(Long), 1131815859556323328(Long), 1131815859518574592(Long), 1131815859505991680(Long), 1131815859573100544(Long), 1131815859258527744(Long), 1131815859224973312(Long), 1131815859401134080(Long), 1131815859547934720(Long), 1131815859266916352(Long), 1131815859464048640(Long), 1131815859564711936(Long)
2019-12-01 19:41:01.951 DEBUG 7984 --- [ scheduling-1] c.c.s.d.S.selectByExample : <== Total: 0
example : sql 语句:
SELECT id,sup_id,sku_id,name,small_pic,price,cost_price,create_time,check_time,status,start_time,end_time,num,stock_count,introduction FROM tb_seckill_goods WHERE ( status = ? and stock_count > ? and start_time >= ? and end_time < ? )
2019-12-01 19:40:58.098 DEBUG 7984 --- [ scheduling-1] c.c.s.d.S.selectByExample : ==> Parameters: 1(String), 0(Integer), 2019-12-02 02:00:00.0(Timestamp), 2019-12-02 04:00:00.0(Timestamp)
SQLyog: 执行语句可以 查找对应数据 :SELECT id,sup_id,sku_id,name,small_pic,price,cost_price,create_time,check_time,status,start_time,end_time,num,stock_count,introduction FROM tb_seckill_goods WHERE ( status = 1 and stock_count > 0 and start_time >= '2019-12-01 18:00:00.0' and end_time < '2019-12-01 20:00:00.0' ) 但是redis 中不显示这个时间段。
8.编写测试类 查找redis 中存的商品
日志信息:用下面的id 搜索对应的商品
9.修改msql 的时区 :
首先,查看下mysql中使用的时区
show variables like '%time_zone%';
select now() 显示当前时间
测试查看下时间
select now();
2018-10-24 15:49:17
这个应该是没有设置时区
1 通过命令修改
设置为 东八区
set global time_zone = '+8:00';
重启连接之后,查看
show variables like '%time_zone%';
2 修改配置文件
找到my.ini, 在mysqld 下增加 default-time-zone = '+8:00'
必须放到mysqld 下,放入其它位置无效
进入docker 容器中的msql:
docker exec -it mysql /bin/bash
cd /etc/mysql/mysql.conf.d
vi mysqld.cnf
涉及到的redis 命令:
fluashall 清空 kyes 显示所有key