J2Cache + SpringBoot的应用

J2Cache + SpringBoot的应用

项目中之前用的是redis缓存,但是在循环查询时,redis偶尔也会出现连接超时的问题,说明redis虽然是内存中处理,速度比较快,但是还是会有开销。尤其是对于高频次请求时,也会有瓶颈。

1,引入maven依赖

<dependency>
            <groupId>net.oschina.j2cache</groupId>
            <artifactId>j2cache-spring-boot2-starter</artifactId>
            <version>2.8.0-release</version>
        </dependency>
        <dependency>
            <groupId>net.oschina.j2cache</groupId>
            <artifactId>j2cache-core</artifactId>
            <version>2.8.2-release</version>
            <exclusions>
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>slf4j-simple</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>slf4j-api</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>net.sf.ehcache</groupId>
            <artifactId>ehcache</artifactId>
        </dependency>

2,yml配置文件配置J2Cache相关属性

spring:
    # 接入redis
    redis:
      database: 11
      host: ##
      port: ##
      password: ##
      #客户端超时时间单位是毫秒 默认是2000
      timeout: 5000
      #最大空闲数
      maxIdle: 20
      #连接池的最大数据库连接数
      maxActive: -1
      #控制一个pool可分配多少个jedis实例,用来替换上面的maxActive
      maxTotal: 100
      #最大建立连接等待时间。如果超过此时间将接到异常
      maxWaitMillis: 100
      #连接的最小空闲时间
      minEvictableIdleTimeMillis: 864000000
      #每次释放连接的最大数目
      numTestsPerEvictionRun: 10
      #逐出扫描的时间间隔(毫秒) 如果为负数,则不运行逐出线程
      timeBetweenEvictionRunsMillis: 300000
      #是否在从池中取出连接前进行检验,如果检验失败,则从池中去除连接并尝试取出另一个
      testOnBorrow: true
      #在空闲时检查有效性
      testWhileIdle: false
j2cache:
  open-spring-cache: true
  cache-clean-mode: passive
  allow-null-values: true
  redis-client: lettuce #指定redis客户端使用lettuce,也可以使用Jedis
  l2-cache-open: true #开启二级缓存,false则表示只使用一级缓存
  # 事件通知的机制,j2cache从1.3.0版本开始支持JGroups和Redis Pub/Sub两种方式进行缓存事件的通知。
  # 此处我们使用基于redis的发布订阅模式来通知缓存的各个节点来进行缓存数据的同步(由j2cache进行实现,我们写上配置即可)
  broadcast: net.oschina.j2cache.cache.support.redis.SpringRedisPubSubPolicy
  #  broadcast: jgroups
  L1: #指定一级缓存提供者为caffeine
    provider_class: caffeine
  L2: #指定二级缓存提供者为redis
    provider_class: net.oschina.j2cache.cache.support.redis.SpringRedisProvider
    config_section: lettuce
  sync_ttl_to_redis: true
  default_cache_null_object: false
  serialization: fst
caffeine:
  properties: /caffeine.properties
# lettuce是redis的一个客户端,也可以使用jedis,都是用来操作redis的java客户端
lettuce:
  mode: single
  namespace:
  storage: generic
  channel: j2cache
  scheme: redis
  hosts: ${spring.redis.host}:${spring.redis.port}
  password: ${spring.redis.password}
  database: ${spring.redis.database}
  sentinelMasterId:
  maxTotal: 100
  maxIdle: 10
  minIdle: 10
  timeout: 10000

caffeine.properties

#########################################
# Caffeine configuration
# [name] = size, xxxx[s|m|h|d]
#########################################
# 默认区域,最多可以放入5000个缓存对象,缓存时间,s表示秒,m分钟,h小时,d天
default = 5000, 1d
# 定义的第二个缓存的区域
adrm.account = 5000, 2d
# 定义的第三个缓存的区域
adrm.dept = 1000, 4d
# 定义的第四个缓存的区域
adrm.person = 2000, 7d

对于缓存区域,可根据业务需求(缓存数量、过期时间不一样)自定义多个。区域名称随便自定义,当缓存区域名称能够在caffeine.properties中匹配上时,该缓存区域的过期时间,最大缓存对象就会用配置上的参数。如果匹配不上,则默认用default 区域的配置参数。

3,J2Cache 用法

	@Resource
    private CacheChannel cacheChannel;

    @Override
    public String getAgentShortNameByCache(Long id){
        Object agent = null;
        try {
        	// 该区域配置中没有设置,默认default的配置,超时时间1d
            agent = cacheChannel.get("adrm.agent", id.toString()).getValue();
        } catch (Exception e) {
            log.error("缓存获取代理商异常:", e);
        }
        if (null != agent) {
            return JSON.parseObject(agent.toString(), AgentPo.class).getAgentShortName();
        }
        AgentPo po = agentRepository.getById(id);
        if (null != po) {
            cacheChannel.set("adrm.agent", id.toString(), JSON.toJSONString(po));
            return po.getAgentShortName();
        }
        return "";
    }
    
	@Transactional(rollbackFor = Exception.class)
    @Override
    public boolean update(AgentPo agent) {
        boolean bool = agentRepository.updateById(agent);
        if (bool) {
            cacheChannel.evict(AdRedisKeyConstant.AGENT, agent.getId().toString());
        }
        return bool;
    }
   

	 /**
     * 根据工号查询用户名称
     * @param crmId
     * @return
     */
    public UserPo getByCrmId(String crmId) {
        if (StringUtils.isBlank(crmId)) {
            return null;
        }
        Object user = null;
        try {
            user = cacheChannel.get("adrm.person", crmId).getValue();
        } catch (Exception e) {
            log.error("缓存中根据人员crmId获取人员异常:", e);
        }
        if (null != user) {
            return JSON.parseObject(user.toString(), UserPo.class);
        }
        UserPo userPo = userRepository.lambdaQuery().eq(UserPo::getCrmId, crmId).one();
        if (ObjectUtil.isEmpty(userPo)) {
            return null;
        }
        // 该区域配置中有adrm.person的配置,超时时间7d
        cacheChannel.set("adrm.person", crmId, JSON.toJSONString(userPo));
        return userPo;
    }

代码未贴出全部,报错请修改。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值