少年阿賓

          那些青春的歲月

            BlogJava :: 首頁 :: 聯系 :: 聚合  :: 管理
            500 Posts :: 0 Stories :: 135 Comments :: 0 Trackbacks

          使用simple-spring-memcached統一緩存的使用

          如何在一個中型的Java應用中使用Memcached緩存數據不是個簡單的問題。當某個緩存數據需要在多個系統間共享和失效時,必須要有統一的規劃才能保證不出錯。經過各種實踐,目前系統在使用Memcached緩存數據全部采用Simple-Spring-Memcached框架來完成,并統一規劃各系統Spring和Cache key的配置。
          下面對在使用過程中需要注意的點做一個詳細說明:

          Cache整體規劃

          目前我們系統中有兩個不同的Memcached服務器:

          1. session memcached服務器:主要存儲用戶的session
          2. app memcached服務器: 主要用于緩存應用數據

          由于應用所有的緩存數據都放在app緩存上,為避免各應用的緩存數據出現沖突,必須規劃好它們的命名空間。所幸Simple-Spring-Memcached支持namespace的概念,因此對各應用的namespace前綴規定如下:

          應用NAMESPACE前綴
          goodscentergoodscenter
          tradetrade
          uicuic

          這個namespace在生成key時,將放在最前面,稍后會有例子詳述。
          同一個應用中存在許多需要緩存的對象,因此約定namespace前綴之后再加上緩存對象的類名。
          例子如下:

          應用緩存對象完整的NAMESPACE最終生成的KEY
          tradeTcRate (id為42)trade:TcRatetrade:TcRate:12
          goodscenterGoodsDo(id為42)goodscenter:GoodsDogoodscenter:GoodsDo:12

          key的生成規則

          Simple-Spring-Memcached提供的針對單個對象的注解接口提供了兩種key生成方式,詳情見此文

          1. AssignCache類注解通過assignKey指定cache的key
          2. SingleCache類注解通過ParameterValueKeyProvider注解指定生成key的方法

          對于第一種只要求必須保證key不與其它的沖突,且namesapce符合規則。
          第二種時,約定緩存的數據對象必須實現有帶CacheKeyMethod的cacheKey方法,參考實現如下:

              @CacheKeyMethod     public String cacheKey() {         return this.getId();     }
          目前@CacheKeyMethod只支持返回String的方法,需要改造成可接受Long,Integer型的。當前必須有單獨的方法來作為緩存Key的生成器
          真實存放到Memcached的key的生成規則是:namespace:key。
          如goodscenter的id為42的domain對象GoodsDo,按上述方式生成的key為:goodscenter:GoodsDo:42

          spring配置說明

          關于Simple-Spring-Memcached具體XML配置如下:

          <beans xmlns="http://www.springframework.org/schema/beans"        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"        xmlns:context="http://www.springframework.org/schema/context"        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">      <import resource="classpath:simplesm-context.xml"/>      <aop:aspectj -autoproxy/>     <context:annotation -config/>      <bean name="appCache" class="com.google.code.ssm.CacheFactory">         <property name="cacheClientFactory">             <bean class="com.google.code.ssm.providers.xmemcached.MemcacheClientFactoryImpl"/>         </property>         <property name="addressProvider">             <bean class="com.google.code.ssm.config.DefaultAddressProvider">                 <!--memcached服務器ip:port 可以是多個,格式為: 127.0.0.1:11211,192.168.100.11:11211-->                 <property name="address" value="{memcached.server}"/>             </bean>         </property>         <property name="configuration">             <!-- memcached連接器的配置,具體的配置項參考這個類 -->             <bean class="com.google.code.ssm.providers.XMemcachedConfiguration">                 <!--是否使用一致性哈希-->                 <property name="consistentHashing" value="true"/>                 <!--連接池-->                 <property name="connectionPoolSize" value="10"/>                 <property name="optimizeGet" value="true"/>              </bean>         </property>         <property name="cacheName">             <!-- 該Memcached配置的Cache名稱 一個應用中存在多個Memcached時,各個配置的cacheName必須不同。如果該值未設,系統默認為default -->             <value>appCache</value>         </property>     </bean> </beans>

          Java代碼中使用說明

          a. 注解方式使用

          直接使用注解來處理緩存及失效非常簡單,下面是相應的例子:
          讀取緩存:

          EventGoodsServiceClientImpl.java
              @Override     @ReadThroughSingleCache(namespace = "goodscenter:EventGoodsDo", expiration = 60)     @CacheName("appCache")     public EventGoodsDo queryEventGoodsDo(@ParameterValueKeyProvider(order = 0) long goodsId, @ParameterValueKeyProvider(order = 1) long eventId) {         return getRemoteServiceBean().queryEventGoodsDo(goodsId, eventId);     }

          更新緩存:

          EventGoodsDaoImpl.java
          @BridgeMethodMappings(value = {@BridgeMethodMapping(erasedParamTypes ={Object.class},targetParamTypes = {com.hqb360.promotion.dao.entity.EventGoods.class},methodName = "update")}) public class EventGoodsDaoImpl&lt;EventGoods&gt; extends BaseDaoImpl&lt;EventGoods&gt; implements EventGoodsDao&lt;EventGoods&gt; {      @Override     public DaoStatementName getDaoStatementName() {         return new DefaultDaoStatementName() {             public String getDomainName() {                 return "EventGoods";             }         };     }      @Override     @InvalidateSingleCache(namespace = "goodscenter:EventGoodsDo")     @CacheName("appCache")     public void update(@ParameterValueKeyProvider EventGoods obj) throws DataAccessException {         super.update(obj);     } }
          EventGoods.java
              @CacheKeyMethod     public String getCacheKey() {         return goodsId + CACHE_ID_SEPARATOR + eventId;     }      public static final String CACHE_ID_SEPARATOR = "/";
          上述代碼需要注意的點
          1. 多個方法參數都作為cacheKey時,ParameterValueKeyProvider必須指明其order值
          2. 多個方法參數作為cacheKey時,參數之間在 / 號分隔
          3. EventGoodsDaoImpl類中的update方法參數接收的是一個泛型對象,因此必須在該類上配置BridgeMethodMappings。具體配置見示例

          b. 以bean的方式使用Cache對象

          某些場景我們希望更便捷地自己手動來管理緩存數據,此時需要使用Simple-Spring-Memcached配置中定義的bean。以上面的配置文件為例,使用方法如下
          bean的注入:

          @Autowired private Cache appCache;

          bean的使用:

          appCache.set(Constants.CACHE_KEY + members.getMemberId(), 3600,cacheValue);

          Posted in Java

           

          posted on 2013-04-03 18:45 abin 閱讀(3731) 評論(0)  編輯  收藏 所屬分類: memcache
          主站蜘蛛池模板: 同江市| 苍溪县| 佳木斯市| 高陵县| 加查县| 溧阳市| 南丹县| 东至县| 清镇市| 额济纳旗| 类乌齐县| 承德县| 娄烦县| 阿鲁科尔沁旗| 宾阳县| 咸阳市| 易门县| 红原县| 永仁县| 东莞市| 阳山县| 原阳县| 绍兴市| 阿合奇县| 曲麻莱县| 自治县| 奈曼旗| 保山市| 德兴市| 河东区| 彭州市| 闻喜县| 清新县| 花莲县| 赣榆县| 崇州市| 德令哈市| 土默特右旗| 三穗县| 霸州市| 灵璧县|