Commit 0311eff4 authored by wulixian's avatar wulixian

Merge branch 'dev' into 'test'

添加盲盒商品预热 See merge request !19
parents 6fba3e2f 867ee2ca
...@@ -6,10 +6,12 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; ...@@ -6,10 +6,12 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.MultipartConfigFactory; import org.springframework.boot.web.servlet.MultipartConfigFactory;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.ComponentScan;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.util.unit.DataSize; import org.springframework.util.unit.DataSize;
import javax.servlet.MultipartConfigElement; import javax.servlet.MultipartConfigElement;
@EnableScheduling
@MapperScan("com.fzm.mall.server.front.*.mapper") @MapperScan("com.fzm.mall.server.front.*.mapper")
@SpringBootApplication(scanBasePackages = "com.fzm.mall") @SpringBootApplication(scanBasePackages = "com.fzm.mall")
public class MallServerFrontApplication { public class MallServerFrontApplication {
...@@ -21,6 +23,7 @@ public class MallServerFrontApplication { ...@@ -21,6 +23,7 @@ public class MallServerFrontApplication {
System.out.println("ssssssssssssssssssssss"+e.toString()); System.out.println("ssssssssssssssssssssss"+e.toString());
} }
} }
@Bean @Bean
public MultipartConfigElement multipartConfigElement() { public MultipartConfigElement multipartConfigElement() {
MultipartConfigFactory factory = new MultipartConfigFactory(); MultipartConfigFactory factory = new MultipartConfigFactory();
......
package com.fzm.mall.server.front.constant.cache; package com.fzm.mall.server.front.constant.cache;
import com.fzm.mall.server.front.constant.MALLGlobalConfig;
/** /**
* springboot 2.0 * springboot 2.0
* *
...@@ -67,4 +69,9 @@ public class GoodCache { ...@@ -67,4 +69,9 @@ public class GoodCache {
* 商品提货物流信息 * 商品提货物流信息
*/ */
public static final String GOOD_LOGISTICS = "mall_good_logistics_"; public static final String GOOD_LOGISTICS = "mall_good_logistics_";
/**
* 商品可用规格库存信息
*/
public static final String GOOD_SKU_EFFECTIVE = MALLGlobalConfig.PJ_SUFFIX + "_good_sku_effective_";
} }
...@@ -4,6 +4,8 @@ import com.fzm.mall.server.front.constant.GoodMainConst; ...@@ -4,6 +4,8 @@ import com.fzm.mall.server.front.constant.GoodMainConst;
import com.fzm.mall.server.front.goods.mapper.GoodSkuMapper; import com.fzm.mall.server.front.goods.mapper.GoodSkuMapper;
import com.fzm.mall.server.front.goods.model.vo.SkuVo; import com.fzm.mall.server.front.goods.model.vo.SkuVo;
import com.fzm.mall.server.front.order.service.IOrderBindBoxService; import com.fzm.mall.server.front.order.service.IOrderBindBoxService;
import com.fzm.mall.server.front.redis.GoodRedis;
import com.fzm.mall.server.front.redis.OrderRedis;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
...@@ -13,6 +15,7 @@ import org.springframework.util.CollectionUtils; ...@@ -13,6 +15,7 @@ import org.springframework.util.CollectionUtils;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
/** /**
* @author wulixian * @author wulixian
...@@ -20,19 +23,33 @@ import java.util.concurrent.ThreadLocalRandom; ...@@ -20,19 +23,33 @@ import java.util.concurrent.ThreadLocalRandom;
*/ */
@Slf4j @Slf4j
@Service @Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class IOrderBindBoxServiceImpl implements IOrderBindBoxService { public class IOrderBindBoxServiceImpl implements IOrderBindBoxService {
private final GoodSkuMapper goodSkuMapper; @Autowired
private GoodSkuMapper goodSkuMapper;
@Autowired
private GoodRedis goodRedis;
@Override @Override
public SkuVo genRandomSku(String goodsId) { public SkuVo genRandomSku(String goodsId) {
long wStart = System.currentTimeMillis();
SkuVo result = null; SkuVo result = null;
/** /**
* 从数据库获取库存大于0的盲盒sku列表 * 提前预热,减轻数据库压力
*/ */
List<SkuVo> skuList = goodSkuMapper.listAvailableSku(goodsId); List<SkuVo> skuList = goodRedis.getEffecticveSku(goodsId);
long wStart = System.currentTimeMillis(); if(CollectionUtils.isEmpty(skuList)){
log.error("redis中读取");
/**
* 从数据库获取库存大于0的盲盒sku列表
*/
skuList = goodSkuMapper.listAvailableSku(goodsId);
/**
* 1分钟缓存
*/
goodRedis.setEffecticveSku(goodsId, skuList, 1, TimeUnit.MINUTES);
}
while(!CollectionUtils.isEmpty(skuList)){ while(!CollectionUtils.isEmpty(skuList)){
int difficulty = skuList.stream().map(SkuVo::getDifficulty).findFirst().get(); int difficulty = skuList.stream().map(SkuVo::getDifficulty).findFirst().get();
result = genRandomSku(skuList, difficulty); result = genRandomSku(skuList, difficulty);
...@@ -53,6 +70,10 @@ public class IOrderBindBoxServiceImpl implements IOrderBindBoxService { ...@@ -53,6 +70,10 @@ public class IOrderBindBoxServiceImpl implements IOrderBindBoxService {
} }
long wEnd = System.currentTimeMillis(); long wEnd = System.currentTimeMillis();
log.info("循环耗时:" +(wEnd-wStart)); log.info("循环耗时:" +(wEnd-wStart));
/**
* 将缓存更新
*/
goodRedis.setEffecticveSku(goodsId, skuList, 1, TimeUnit.MINUTES);
if (result == null) { if (result == null) {
throw new RuntimeException("库存不足!!!"); throw new RuntimeException("库存不足!!!");
} }
......
...@@ -5,6 +5,8 @@ import com.fzm.mall.server.front.asset.model.vo.good.*; ...@@ -5,6 +5,8 @@ import com.fzm.mall.server.front.asset.model.vo.good.*;
import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.core.type.TypeReference;
import com.fzm.mall.server.front.goods.model.GoodSale; import com.fzm.mall.server.front.goods.model.GoodSale;
import com.fzm.mall.server.front.goods.model.GoodSpu; import com.fzm.mall.server.front.goods.model.GoodSpu;
import com.fzm.mall.server.front.goods.model.vo.SkuVo;
import com.fzm.mall.server.front.order.model.Order;
import com.fzm.mall.server.front.repository.RedisRepository; import com.fzm.mall.server.front.repository.RedisRepository;
import com.fzm.mall.server.front.constant.cache.GoodCache; import com.fzm.mall.server.front.constant.cache.GoodCache;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
...@@ -216,4 +218,26 @@ public class GoodRedis { ...@@ -216,4 +218,26 @@ public class GoodRedis {
public void delState(String gid) { public void delState(String gid) {
redisRepository.delObj(GoodCache.GOOD_STATE + gid); redisRepository.delObj(GoodCache.GOOD_STATE + gid);
} }
public void setEffecticveSku(String goodsId, List<SkuVo> effectiveSkuList, long time, TimeUnit timeUnit){
redisRepository.setObj(GoodCache.GOOD_SKU_EFFECTIVE + goodsId, effectiveSkuList, time, timeUnit);
}
public List<SkuVo> getEffecticveSku(String goodsId){
try {
Object obj = redisRepository.getObj(GoodCache.GOOD_SKU_EFFECTIVE + goodsId);
if (obj != null) {
return JSON.parseArray(JSON.toJSONString(obj), SkuVo.class);
}
} catch (Exception e) {
e.printStackTrace();
// 缓存中获取的数据转换发生错误,重置缓存
delEffecticveSku(goodsId);
}
return null;
}
public void delEffecticveSku(String goodsId){
redisRepository.delObj(GoodCache.GOOD_SKU_EFFECTIVE + goodsId);
}
} }
package com.fzm.mall.server.front.task.goods;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fzm.mall.server.front.constant.StateConst;
import com.fzm.mall.server.front.enums.GoodSpuSalesTypeEnum;
import com.fzm.mall.server.front.goods.mapper.GoodSkuMapper;
import com.fzm.mall.server.front.goods.mapper.GoodSpuMapper;
import com.fzm.mall.server.front.goods.model.GoodSpu;
import com.fzm.mall.server.front.goods.model.vo.SkuVo;
import com.fzm.mall.server.front.redis.GoodRedis;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
* @author wulixian
* @since 2022/3/10
*/
@Component
@Slf4j
public class GoodsSkuTask {
@Autowired
private GoodSkuMapper goodSkuMapper;
@Autowired
private GoodSpuMapper goodSpuMapper;
@Autowired
private GoodRedis goodRedis;
//提前预加载盲盒商品
@Scheduled(cron = "${goods.effective-sku-preload}")
public void preLoadBlindBoxEffectiveSku() {
log.info("开始预加载盲盒商品");
QueryWrapper<GoodSpu> spuWrapper = new QueryWrapper<>();
spuWrapper.eq("status", StateConst.ACTIVE_SUCCESS)
.eq("sales_type", GoodSpuSalesTypeEnum.BLIND_BOX.getType());
List<GoodSpu> spuList = goodSpuMapper.selectList(spuWrapper);
if(CollectionUtils.isEmpty(spuList)){
return;
}
spuList.forEach(goodSpu -> {
List<SkuVo> skuList = goodSkuMapper.listAvailableSku(goodSpu.getGoodsId());
/**
* 定时任务预加载设置缓存时间为23小时
*/
goodRedis.setEffecticveSku(goodSpu.getGoodsId(), skuList, 23, TimeUnit.HOURS);
});
}
}
...@@ -95,3 +95,6 @@ alipay: ...@@ -95,3 +95,6 @@ alipay:
pay-notify-url: http://testwxc.huowulian365.com/root/xls/alipay/without/payNotify pay-notify-url: http://testwxc.huowulian365.com/root/xls/alipay/without/payNotify
pay-postfee-url: http://testwxc.huowulian365.com/root/xls/alipay/without/payPostFee pay-postfee-url: http://testwxc.huowulian365.com/root/xls/alipay/without/payPostFee
refund-notify-url: http://testwxc.huowulian365.com/root/pay/refundNotify refund-notify-url: http://testwxc.huowulian365.com/root/pay/refundNotify
goods:
effective-sku-preload: 0 0 0 * * ?
\ No newline at end of file
...@@ -95,3 +95,6 @@ express: ...@@ -95,3 +95,6 @@ express:
key: key key: key
# 阿里云调用: appcode # 阿里云调用: appcode
appcode: d97dd0febda34a64a751f3ff6ea6d242 appcode: d97dd0febda34a64a751f3ff6ea6d242
goods:
effective-sku-preload: 0 0 0 * * ?
...@@ -75,4 +75,7 @@ alipay: ...@@ -75,4 +75,7 @@ alipay:
notify-url: http://47.99.152.140:8092/pay/mainNotify notify-url: http://47.99.152.140:8092/pay/mainNotify
pay-notify-url: http://testwxc.huowulian365.com/root/xls/alipay/without/payNotify pay-notify-url: http://testwxc.huowulian365.com/root/xls/alipay/without/payNotify
pay-postfee-url: http://testwxc.huowulian365.com/root/xls/alipay/without/payPostFee pay-postfee-url: http://testwxc.huowulian365.com/root/xls/alipay/without/payPostFee
refund-notify-url: http://testwxc.huowulian365.com/root/pay/refundNotify refund-notify-url: http://testwxc.huowulian365.com/root/pay/refundNotify
\ No newline at end of file
goods:
effective-sku-preload: 0 0 0 * * ?
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment