优惠券项目五

整体项目介绍:

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);
    }


}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章