整体项目介绍:
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); } }