xmemcached缓存

来源:互联网 发布:淘宝主图视频内存大小 编辑:程序博客网 时间:2024/05/21 22:53
package com.idoo.ott.core.cache;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeoutException;

import net.rubyeye.xmemcached.KeyIterator;
import net.rubyeye.xmemcached.MemcachedClient;
import net.rubyeye.xmemcached.XMemcachedClient;
import net.rubyeye.xmemcached.exception.MemcachedException;

import org.apache.commons.lang.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@SuppressWarnings("deprecation")
public class CacheHandlerImpl {

    private Map<String, Object> cacheKeys;

    private MemcachedClient memcachedClient;

    private Logger logger = LoggerFactory.getLogger(getClass());

    public void freshCache(JoinPoint jp) {
        String serviceClsName = jp.getTarget().getClass().getSimpleName();
        if (cacheKeys != null && cacheKeys.size() > 0
                && cacheKeys.containsKey(serviceClsName)) {        
            logger.info("refresh cache keys: " + cacheKeys.get(serviceClsName));
            freshCacheByName(serviceClsName);
        }
    }

    public void freshCacheByName(String cacheName) {
        if (cacheKeys != null && cacheKeys.size() > 0
                && cacheKeys.containsKey(cacheName)) {
            logger.info(cacheName + " refresh cache keys:"
                    + cacheKeys.get(cacheName));
            List<String> keys = getAllKeys();
            cacheName = String.valueOf(cacheKeys.get(cacheName));

            if ("#flushAll".equals(cacheName)) {
                this.deleteCache(cacheName);
                return;
            }
            // 逗号分开
            if (StringUtils.isNotBlank(cacheName)) {
                String caches[] = cacheName.split(",");
                for (String key : caches) {
                    clearCache(key, keys);
                }
            }

        }
    }

    private void clearCache(String cacheKey, List<String> cacheKeys) {
        for (String key : cacheKeys) {
            if (key.indexOf(cacheKey) > -1) {
                this.deleteCache(key);
            }
        }
    }
    /**
     * 二次缓存清理,避免脏数据产生
     * @author 905706
     * @param key
     */
    private void deleteCache(final String key){
        this.delete(key);
        new Thread(){
            public void run(){
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e1) {
                    e1.printStackTrace();
                }
                delete(key);
            }
        }.start();
        
    }
    public boolean delete(String key){
        try {
            if("#flushAll".equalsIgnoreCase(key)){
                memcachedClient.flushAll();
            }else{
                memcachedClient.delete(key);
            }
            return true;
        } catch (TimeoutException e) {
            logger.error(key + ":fresh cache error", e);
            return false;
        } catch (InterruptedException e) {
            logger.error(key + ":fresh cache error", e);
            return false;
        } catch (MemcachedException e) {
            logger.error(key + ":fresh cache error", e);
            return false;
        }
    }

    public List<String> getAllKeys() {
        List<String> list = new ArrayList<String>();
        Map<InetSocketAddress, Map<String, String>> servers;
        try {
            servers = this.memcachedClient.getStats();
            if (servers != null && servers.size() > 0) {
                Iterator<InetSocketAddress> itserver = servers.keySet()
                        .iterator();
                while (itserver.hasNext()) {
                    InetSocketAddress isa = itserver.next();
                    KeyIterator ki = this.memcachedClient.getKeyIterator(isa);
                    while (ki.hasNext()) {
                        list.add(ki.next());
                    }
                }
            }
        } catch (MemcachedException e) {
            logger.error("fresh cache error", e);
        } catch (InterruptedException e) {
            logger.error("fresh cache error", e);
        } catch (TimeoutException e) {
            logger.error("fresh cache error", e);
        }

        return list;
    }

    public static void main(String[] args) throws IOException,
            TimeoutException, InterruptedException, MemcachedException {
        CacheHandlerImpl handlerImpl = new CacheHandlerImpl();
        List<InetSocketAddress> addressList = new ArrayList<InetSocketAddress>();
        addressList.add(new InetSocketAddress("172.21.11.201", 12000));
        addressList.add(new InetSocketAddress("172.21.11.202", 12000));
        handlerImpl.memcachedClient = new XMemcachedClient(addressList);
        List<String> list = handlerImpl.getAllKeys();
        handlerImpl.memcachedClient.flushAll();
        System.out.println("flush all");
    }

    public void setCacheKeys(Map<String, Object> cacheKeys) {
        this.cacheKeys = cacheKeys;
    }

    public Map<String, Object> getCacheKeys() {
        return cacheKeys;
    }

    public void setMemcachedClient(MemcachedClient memcachedClient) {
        this.memcachedClient = memcachedClient;
    }

    public MemcachedClient getMemcachedClient() {
        return memcachedClient;
    }

    @Override
    protected void finalize() throws Throwable {
        super.finalize();
        if (this.memcachedClient != null)
            this.memcachedClient.shutdown();
        this.memcachedClient = null;
    }

}

applicationContext-aop.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jee="http://www.springframework.org/schema/jee"
    xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
    http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">

    <bean name="memcachedClient"
        class="net.rubyeye.xmemcached.utils.XMemcachedClientFactoryBean"
        destroy-method="shutdown">
        <property name="servers">
            <value>${memcached.server}</value>
        </property>
        <!-- server's weights -->
        <property name="weights">
            <list>
                <value>1</value>
                <value>1</value>
            </list>
        </property>
        <!-- nio connection pool size -->
        <property name="connectionPoolSize" value="1"></property>
        <!-- Use binary protocol,default is TextCommandFactory -->
        <property name="commandFactory">
            <bean class="net.rubyeye.xmemcached.command.TextCommandFactory"></bean>
        </property>
        <!-- Distributed strategy -->
        <property name="sessionLocator">
            <bean class="net.rubyeye.xmemcached.impl.KetamaMemcachedSessionLocator"></bean>
        </property>
        <!-- Serializing transcoder -->
        <property name="transcoder">
            <bean class="net.rubyeye.xmemcached.transcoders.SerializingTranscoder" />
        </property>
        <!-- ByteBuffer allocator -->
        <property name="bufferAllocator">
            <bean class="net.rubyeye.xmemcached.buffer.SimpleBufferAllocator"></bean>
        </property>
        <!-- Failure mode -->
        <property name="failureMode" value="false" />
    </bean>
    <bean id="cacheHandler" class="com.idoo.ott.core.cache.CacheHandlerImpl">
        <property name="memcachedClient" ref="memcachedClient"></property>
        <property name="cacheKeys">
            <map>
                <!-- key service类名  媒资同步接口 -->
                <entry key="AssetAddService"
                    value="getAssetList,getAssetListByPackageCode,getAssetDetail,getRecommendResource,getRelateAsset,getAssetTrailer,searchByKeyWord" />
            
                <!-- 栏目同步接口 -->
                <entry key="ColumnDelService" value="getCatalog" />
                <entry key="ColumnSynService" value="getCatalog" />

            
            </map>
        </property>
    </bean>

    <!-- <aop:aspectj-autoproxy /> -->
    <aop:config>
        <aop:aspect ref="cacheHandler">
            <aop:pointcut id="pointcut"
                expression="execution(* com.idoo.ott.iservice*..*.execute*(..))" /> <!-- 对所有的类以add开头的任何方法使用该方法。可以看spring参考手册 -->
            <!-- method 指出before要调用的方法 -->
            <aop:after-returning method="freshCache"
                pointcut-ref="pointcut" />
        </aop:aspect>
    </aop:config>
</beans>
0 0
原创粉丝点击