java集成memcached、redis防止缓存穿透

时间:2022-06-13 10:46:50

下载相关jar,安装Memcached,安装教程:http://www.runoob.com/memcached/memcached-install.html

spring配置memcached

<bean id="memcachedPool" class="com.danga.MemCached.SockIOPool"
        factory-method="getInstance" init-method="initialize" destroy-method="shutDown">
        <constructor-arg>
            <value>memCachedPool</value>
        </constructor-arg>
        <property name="servers">
            <list>
                <value>127.0.0.1:11211</value>
            </list>
        </property>
        <property name="initConn">
            <value>20</value>
        </property>
        <property name="minConn">
            <value>10</value>
        </property>
        <property name="maxConn">
            <value>50</value>
        </property>
        <property name="maintSleep">
            <value>3000</value>
        </property>
        <property name="nagle">
            <value>false</value>
        </property>
        <property name="socketTO">
            <value>100</value>
        </property>
    </bean>
    <!-- 缓存的配置 -->
    <bean id="memCachedClient" class="com.danga.MemCached.MemCachedClient">
        <constructor-arg>
            <value>memCachedPool</value>
        </constructor-arg>
    </bean>

缓存穿透的原理代码,不多解释:

import java.util.Date;
import javax.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Service;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.danga.MemCached.MemCachedClient;
/**
 * 防止缓存穿透(透过缓存直接访问数据库)
 * synchronized会锁定当前方法的话,对所有线程进行排序,放在方法上会影响程序效率
 * @author
 */
@Service
public class MemcachedService {
    Log log = LogFactory.getLog( this .getClass());   
    @Resource
    private MemCachedClient memcachedClient;   
    /**
     * 避免缓存穿透
     * 读取缓存
     * @param key    缓存的key
     * @param expire    缓存的失效时间
     * @param clazz    缓存的类型
     * @param locadback    如果缓存失效,怎么获取
     * @return
     */
    public <T>    T findCache(String key,Date expire,TypeReference<T> clazz,CacheLoadback<T> locadback){
        String json = memcachedClient.get(key) + "";
        if(StringUtils.isNotEmpty(json) && !json.equalsIgnoreCase("null")){
            log.info("------读取缓存数据=================="+key);
            return JSON.parseObject(json, clazz);
        }else{
            synchronized (this) {
                json = memcachedClient.get(key)+"";
                if(StringUtils.isNotEmpty(json) && !json.equalsIgnoreCase("null")){
                    return JSON.parseObject(json, clazz);
                }
                T result = locadback.load();
                if(result != null){
                    memcachedClient.set(key, JSON.toJSON(result), expire);
                }
                return result;
            }
        }
    }  
}

业务实现层代码

@Resource
    private MemcachedService memcachedService;

@Override
    public List<SensorDataVO1> getSensorDataVO2s(String sensorId,String passway,int curPage,int pageSize) {
        //将方法名作为key值
        String method = Thread.currentThread().getStackTrace()[1].getMethodName();
        return memcachedService.findCache(method+sensorId+passway+curPage+pageSize,DateUtils.addMinutes(new Date(), 10), new TypeReference<List<SensorDataVO1>>(){},new CacheLoadback<List<SensorDataVO1>>() {
            @Override
            public List<SensorDataVO1> load() {
                return sensorDataDao.getSensorDataVO1s(sensorId,passway,curPage,pageSize);
            }
        });   
    }

interface层:

public interface CacheLoadback<T> {
    public T load();
}