电商秒杀模块 :异常解决:redis 显示的商品的时间与搜索时间段不对应

 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

发布了221 篇原创文章 · 获赞 8 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/oDianZi1234567/article/details/103338238