優惠券項目五

整體項目介紹:

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


}

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