Ehcache-v3.x API集成,简单搞定

Ehcache是什么?

EhCache 是一个纯Java的进程内缓存框架,具有快速、精干等特点,是Hibernate中默认的CacheProvider,是一个应用缓存,基于服务进程实现。

为什么要用Ehcache?

那有的人就有疑问了,这么多分布式缓存组件,为什么要用Ehcache?没错,说的也是对的,就拿Redis来说,确实好用、简单。但看官们有没有想一个问题,大量的访问量,Redis的负载也是飙升的,有的人就会说了,Redis单机十万的QPS担心这些干嘛,没错也是对的,但是要基于复杂度低的查询,另外,应用操作Redis连接的耗时、网络IO这些都有可能成为Redis的瓶颈(官网也提出了这一点),所以在一些业务场景(数据不经常变动的、高频查询的)可以在Redis上做一层二级缓存,减少Redis连接耗时、网络IO对吞吐量的影响。

为什么集成Ehcache-3.x?

用过Ehcache的伙伴应该知道,2.x和3.x,2.x是net.sf.ehcache,而3.x是org.ehcache,在Ehcache3.x中新增了支持堆外内存存储特性:
在这里插入图片描述
相对于2.x存入堆内,减少了GC触发,不影响业务代码中的对象heap空间。

实操

maven依赖

<dependency>
	<groupId>org.ehcache</groupId>
	<artifactId>ehcache</artifactId>
	<version>3.8.1</version>
</dependency>

工具类

public class EhCacheUtils {

    /**
     * EhCache管理实例,定义过期策略、资源池大小、预置缓存创建等。
     */
    private static CacheManager cacheManager;

    /**
     * 是否开启EhCache缓存
     */
    private static boolean ehcacheSwitch = EhCacheConstant.EHCACHE_SWITCH;

    static {
        ResourcePoolsBuilder resourcePoolsBuilder = ResourcePoolsBuilder.newResourcePoolsBuilder()
                //不设置key个数,只设置大小
                .offheap(EhCacheConstant.NON_HEAP_SIZE, MemoryUnit.MB);
        //过期策略,有个存活时间设置
        ExpiryPolicy expiryPolicy = ExpiryPolicyBuilder
                .timeToLiveExpiration(Duration.ofMinutes(EhCacheConstant.NON_HEAP_LIVE_EXPIRY));
        //指定的key和value的类型序列化
        CacheConfiguration config = CacheConfigurationBuilder.newCacheConfigurationBuilder(String.class, String.class, resourcePoolsBuilder)
                //指定过期策略
                .withExpiry(expiryPolicy)
                .build();
        CacheManagerBuilder cacheManagerBuilder = CacheManagerBuilder.newCacheManagerBuilder()
                //自定义预置缓存,目前只存在一个缓存桶,使用key进行区分
                .withCache(EhCacheConstant.PRE_CACHE_NAME, config);
        cacheManager = cacheManagerBuilder.build();
        //初始化
        cacheManager.init();
    }

    /**
     * 创建新EhCache缓存
     *
     * @param cacheName         缓存名(唯一)
     * @param nonHeapSize       堆外内存大小限制, 单位: MB
     * @param nonHeapLiveExpiry 存活时间限制,单位:Min/分钟, 创建后一段时间过期
     * @return
     */
    public static Cache createCache(String cacheName, long nonHeapSize, long nonHeapLiveExpiry) {
        Cache cache = getCache(cacheName);
        if (cache == null) {
            cache = cacheManager.createCache(cacheName, CacheConfigurationBuilder.newCacheConfigurationBuilder(String.class, String.class,
                    ResourcePoolsBuilder.newResourcePoolsBuilder()
                            //不设置个数,只设置大小
                            .offheap(nonHeapSize, MemoryUnit.MB))
                    .withExpiry(ExpiryPolicyBuilder
                            .timeToLiveExpiration(Duration.ofMinutes(nonHeapLiveExpiry))).build());
        }
        return cache;
    }

    /**
     * 移除EhCache缓存
     *
     * @param cacheName 缓存名(唯一)
     */
    public static void removeCache(String cacheName) {
        cacheManager.removeCache(cacheName);
    }

    /**
     * 获取缓存桶信息
     *
     * @param cacheName 缓存桶名称(唯一)
     * @return
     */
    private static Cache getCache(String cacheName) {
        Cache<String, String> cache = cacheManager.getCache(cacheName, String.class, String.class);
        if (cache == null) {
            log.error("Get cache fail, Fail cache name: {}", cacheName);
            return null;
        }
        return cache;
    }

    /**
     * 存储数据,指定缓存桶、key、值
     *
     * @param cacheName 缓存桶名称(唯一)
     * @param key       缓存key(唯一)
     * @param value     缓存值
     */
    public static void put(String cacheName, String key, String value) {
        if (!ehcacheSwitch) {
            return;
        }
        Cache cache = getCache(cacheName);
        if (cache != null && !cache.containsKey(key)) {
            cache.put(key, value);
        }
    }

    /**
     * 获取数据,指定缓存桶、key
     *
     * @param cacheName 缓存桶名称(唯一)
     * @param key       缓存key(唯一)
     */
    public static String get(String cacheName, String key) {
        if (!ehcacheSwitch) {
            return null;
        }
        Cache cache = getCache(cacheName);
        if (cache != null && cache.containsKey(key)) {
            return (String) cache.get(key);
        }
        return null;
    }

    /**
     * 移除数据,指定缓存桶、key
     *
     * @param cacheName 缓存桶名称(唯一)
     * @param key       缓存key(唯一)
     */
    public static void remove(String cacheName, String key) {
        if (!ehcacheSwitch) {
            return;
        }
        Cache cache = getCache(cacheName);
        if (cache != null && cache.containsKey(key)) {
            cache.remove(key);
        }
    }

    /**
     * 批量移除数据,指定缓存桶、key,如果想删除所有,强烈使用cleanCache方法
     *
     * @param cacheName 缓存桶名称(唯一)
     * @param keys      缓存key(集合)
     */
    public static void removeBatch(String cacheName, Set<String> keys) {
        if (!ehcacheSwitch) {
            return;
        }
        Cache cache = getCache(cacheName);
        if (cache != null) {
            cache.removeAll(keys);
        }
    }

    /**
     * 清楚缓存同所有数据,指定缓存桶
     *
     * @param cacheName 缓存桶名称(唯一)
     */
    public static void cleanCache(String cacheName) {
        if (!ehcacheSwitch) {
            return;
        }
        Cache cache = getCache(cacheName);
        if (cache != null) {
        	 cache.clear();
        }
    }

多业务可以对桶(cacheName)进行划分,你可以理解桶对应Redis的索引库。对Ehcache的缓存同步,可以使用redis发布订阅或者MQ都可以通知删除key即可。

总结:
总的来说使用了Ehcache对接口提升效果显而易见的,减少Redis连接、网络IO,主要就是快,当然还是有缺点的,虽然Ehcache支持分布式,如果真的要使用Ehcache实现分布式缓存,这将是一个极大的工作量,还是老老实实用第三方组件吧。

码字不易~讲解不易!!!点个赞再走。记住,我还是那个会撩头发的程序猿!!!

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值