整體項目介紹:
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);
}
}