整体项目介绍:
https://blog.csdn.net/wenjieyatou/article/details/80190886
优惠券项目一介绍:https://blog.csdn.net/wenjieyatou/article/details/80191083
优惠券项目二介绍:
https://blog.csdn.net/wenjieyatou/article/details/80203860
优惠券项目三介绍:
https://blog.csdn.net/wenjieyatou/article/details/80206069
优惠券项目四介绍:
https://blog.csdn.net/wenjieyatou/article/details/80207217
下面是优惠券项目五介绍:
1:采用redis做缓存,取当天有效的活动,活动下券组,券组下500张券存入缓存中。
2:加入定时任务,在每天12点时候更新缓存(这个时间可以通过热点数据来监控)
3:统计结果发现:
加入缓存后发送500张优惠券耗时只有2.7s,比之前的4.8s快了2.1s,大大的提升了性能
1:采用redis做缓存,取当天有效的活动,活动下券组,券组下500张券存入缓存中。
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import com.migr.common.util.JsonUtil;
import com.migr.common.util.StringUtils;
import com.peiyu.mem.dao.CpActivityDao;
import com.peiyu.mem.dao.CpActsubGroupDao;
import com.peiyu.mem.dao.CpapplylimitdtDao;
import com.peiyu.mem.dao.CpuselimitdtDao;
import com.peiyu.mem.domian.entity.CpActivity;
import com.peiyu.mem.domian.entity.CpActsubGroup;
import com.peiyu.mem.domian.entity.CpApplyLimitdt;
import com.peiyu.mem.domian.entity.CpUseLimitdt;
import com.peiyu.mem.redis.JedisTemplate;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Administrator on 2017/1/5.
*/
@Service
public class CouponActivityCacheManager {
private Logger log = Logger.getLogger(CouponActivityCacheManager.class);
@Autowired
private CpActivityDao activityDao;
@Autowired
private CpActsubGroupDao actsubGroupDao;
@Autowired
private CpapplylimitdtDao applyLimitdtDao;
@Autowired
private CpuselimitdtDao cpuselimitdtDao;
@Autowired
private JedisTemplate jedisTemplate;
@Autowired
private ThreadPoolTaskExecutor taskExecutor;
abstract class ListGetterHandler<T> {
/**
* 从库中加载数据
*
* @param search
* @return
*/
abstract List<T> getListFromDB(T search);
/**
* 从缓存中获取数据如果没有从库中加载,并刷新缓存
*
* @param key
* @param search
* @return
*/
public List<T> getListAndSetCache(final String key, T search, Class<T> type) {
List<T> list = new ArrayList<>();
String jsonList = jedisTemplate.get(key);
if (StringUtils.isBlank(jsonList)) {
final String lockKey = "lock:" + key;
if (jedisTemplate.hsetNX(lockKey, lockKey, "60") == 1) {//防止并发时候数据库被击穿(表示设置成功)
list = getListFromDB(search);
final List<T> finalList = list;
//异步刷新缓存
taskExecutor.execute(new Runnable() {
@Override
public void run() {
try {
String json = JsonUtil.g.toJson(finalList);
jedisTemplate.set(key, json, 24 * 60 * 60);
} catch (Exception e) {
log.error("刷新缓存失败", e);
} finally {
jedisTemplate.hdel(lockKey, lockKey);
}
}
});
}
}
if (StringUtils.isNotBlank(jsonList)) {
JsonArray array = new JsonParser().parse(jsonList).getAsJsonArray();
for (final JsonElement elem : array) {
list.add(JsonUtil.g.fromJson(elem, type));
}
return list;
}
return list;
}
}
private ListGetterHandler<CpActivity> activityListGetterHandler = new ListGetterHandler<CpActivity>() {
@Override
List<CpActivity> getListFromDB(CpActivity search) {
return activityDao.getCpActivityBySearch(search);
}
};
private ListGetterHandler<CpActsubGroup> actsubGroupListGetterHandler = new ListGetterHandler<CpActsubGroup>() {
@Override
List<CpActsubGroup> getListFromDB(CpActsubGroup search) {
return actsubGroupDao.getCpActsubGroupList(search);
}
};
private ListGetterHandler<CpApplyLimitdt> applyLimitdtListGetterHandler = new ListGetterHandler<CpApplyLimitdt>() {
@Override
List<CpApplyLimitdt> getListFromDB(CpApplyLimitdt search) {
return applyLimitdtDao.getCpApplyLimitdtsBySearch(search);
}
};
private ListGetterHandler<CpUseLimitdt> useLimitdtListGetterHandler = new ListGetterHandler<CpUseLimitdt>() {
@Override
List<CpUseLimitdt> getListFromDB(CpUseLimitdt search) {
return cpuselimitdtDao.getCpUseLimitdts(search);
}
};
/**
* 获取当天有效的优惠券活动
*
* @param search
* @return
*/
public List<CpActivity> getCpActivityList(CpActivity search) {
String key = String.format("activitys_%s_%s", search.getVendorId(), search.getSendType());
return activityListGetterHandler.getListAndSetCache(key, search, CpActivity.class);
}
/**
* 获取活动下的有效的优惠券
*
* @param search
* @return
*/
public List<CpActsubGroup> getCpActsubGroupList(CpActsubGroup search) {
String key = String.format("actSubGruops_%s_%s", search.getVendorId(), search.getActNo());
return actsubGroupListGetterHandler.getListAndSetCache(key, search, CpActsubGroup.class);
}
/**
* 获取活动的应用范围限制
*
* @param search
* @return
*/
public List<CpApplyLimitdt> getCpApplyLimitdtList(CpApplyLimitdt search) {
String key = String.format("applyLimits_%s_%s", search.getVendorId(), search.getOwnRecordCode());
return applyLimitdtListGetterHandler.getListAndSetCache(key, search, CpApplyLimitdt.class);
}
/**
* 获取活动使用范围限制
* @param search
* @return
*/
public List<CpUseLimitdt> getCpUseLimitList(CpUseLimitdt search) {
String key = String.format("useLimits_%s_%s", search.getVendorId(), search.getOwnRecordCode());
return useLimitdtListGetterHandler.getListAndSetCache(key, search, CpUseLimitdt.class);
}
}
2:加入定时任务,在每天12点时候更新缓存(这个时间可以通过热点数据来监控)
package com.peiyu.mem.service.impl;
import com.migr.common.util.JsonUtil;
import com.peiyu.mem.commen.SysConstants;
import com.peiyu.mem.dao.CpActivityDao;
import com.peiyu.mem.dao.CpActsubGroupDao;
import com.peiyu.mem.dao.CpapplylimitdtDao;
import com.peiyu.mem.dao.CpuselimitdtDao;
import com.peiyu.mem.domian.entity.CpActivity;
import com.peiyu.mem.domian.entity.CpActsubGroup;
import com.peiyu.mem.domian.entity.CpApplyLimitdt;
import com.peiyu.mem.domian.entity.CpUseLimitdt;
import com.peiyu.mem.redis.JedisTemplate;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Date;
import java.util.List;
/**
* Created by Administrator on 2017/1/10.
* 优惠券定时任务
*/
@Service
public class ActivityTimingTask {
@Autowired
private CpActivityDao activityDao;
@Autowired
private CpActsubGroupDao actsubGroupDao;
@Autowired
private CpapplylimitdtDao cpapplylimitdtDao;
@Autowired
private CpuselimitdtDao cpuselimitdtDao;
@Autowired
private JedisTemplate jedisTemplate;
/**
* 获取数据代理
*
* @param <T>
*/
abstract class CacheRefreshHandler<T> {
/**
* 数据库加载数据
*
* @param search
* @return
*/
abstract List<T> getListFromDB(T search);
/**
* 获取key值
*
* @param item
* @return
*/
abstract String getKey(T item);
/**
* 刷新活动通用方法
*
* @param search
*/
public void refreshCache(T search) {
List<T> list = getListFromDB(search);
if (CollectionUtils.isEmpty(list)) {
return;
}
String key = getKey(search);
jedisTemplate.set(key, JsonUtil.g.toJson(search));
}
}
public void TimingRefreshAllCache(){
try {
this.refreshActivityCache(new CpActivity());
this.refreshSubGroupCache(new CpActsubGroup());
this.refreshCpApplyLimitdt(new CpApplyLimitdt());
this.refreshCpUseLimitdt(new CpUseLimitdt());
}catch (Exception e){
System.out.println("刷新缓存失败");
}
}
/**
* 刷新当天活动缓存
*
* @param search
*/
protected void refreshActivityCache(CpActivity search) {
search.setEndDate(new Date());
search.setStatus(SysConstants.ACTIVITYSTATUS.CHECKED);
CacheRefreshHandler<CpActivity> refreshHandler = new CacheRefreshHandler<CpActivity>() {
@Override
List<CpActivity> getListFromDB(CpActivity search) {
return activityDao.getCpActivityBySearch(search);
}
@Override
String getKey(CpActivity item) {
return String.format("");
}
};
refreshHandler.refreshCache(search);
}
/**
* 刷新优惠券组的缓存
*
* @param search
*/
public void refreshSubGroupCache(CpActsubGroup search) {
CacheRefreshHandler<CpActsubGroup> actsubGroupCacheRefreshHandler = new CacheRefreshHandler<CpActsubGroup>() {
@Override
List<CpActsubGroup> getListFromDB(CpActsubGroup search) {
return actsubGroupDao.getCpActsubGroupList(search);
}
@Override
String getKey(CpActsubGroup item) {
return String.format("");
}
};
actsubGroupCacheRefreshHandler.refreshCache(search);
}
/**
* 刷新应用范围限制
* @param search
*/
public void refreshCpApplyLimitdt(CpApplyLimitdt search){
CacheRefreshHandler<CpApplyLimitdt> cacheRefreshHandler=new CacheRefreshHandler<CpApplyLimitdt>() {
@Override
List<CpApplyLimitdt> getListFromDB(CpApplyLimitdt search) {
return cpapplylimitdtDao.getCpApplyLimitdtsBySearch(search);
}
@Override
String getKey(CpApplyLimitdt item) {
return String.format("");
}
};
cacheRefreshHandler.refreshCache(search);
}
/**
* 刷新使用范围限制
* @param search
*/
public void refreshCpUseLimitdt(CpUseLimitdt search){
CacheRefreshHandler<CpUseLimitdt> cacheRefreshHandler=new CacheRefreshHandler<CpUseLimitdt>() {
@Override
List<CpUseLimitdt> getListFromDB(CpUseLimitdt search) {
return cpuselimitdtDao.getCpUseLimitdts(search);
}
@Override
String getKey(CpUseLimitdt item) {
return String.format("");
}
};
cacheRefreshHandler.refreshCache(search);
}
}