Java项目的性能优化样例

场景一:高并发频繁的数据库访问
解决方案:

  1. 总所周知的是:加缓存,最常见的是:加缓存中间件如 Redis,当然了这里要说的不是这个,增加一个中间件多少有点费事儿;

  2. 通过Java类的方式解决
    POM添加jar包

    //添加依赖
    <dependency>
    		<groupId>com.google.guava</groupId>
    		<artifactId>guava</artifactId>
    		<version>20.0</version>
    	</dependency>
    
    

    //在 service 层或者 DAO 层创建了一个名为 consumerCache 的缓存池,这里用Optional包了一层是因为 Cache.get(Key)方法不能返回和存储null,如果是null会报错,具体原因感兴趣的可以看看 Cache 的源码

    
    //导包路径 import com.google.common.cache.CacheBuilder;
    //		  import com.google.common.cache.Cache;
    private final Cache<Long, Optional<List<PartnerCallbackDef>>> consumerCache = CacheBuilder
            .newBuilder()
            .maximumSize(1000) //最大数量
            .expireAfterWrite(3, TimeUnit.MINUTES) //缓存过期时间和时间单位
            .build();
    
    
    

    在查数据库的时候先尝试从缓存中获取,如果缓存中没有再执行数据库查询,将数据库查询结果缓存并返回,发生异常时会捕获并记录日志,然后返回一个空的Optional对象,在接受方法返回结果进行下一步处理的时候用 isPresent() 判断一下就好了。

     private Optional<List<PartnerCallbackDef>> getConsumerCache(final Long key) {
        try {
            return consumerCache.get(key, () -> Optional.ofNullable(partnerCallbackDefDao.getByTypeAndPartnerId(Constants.CALLBACK_DEF_TYPE_CONSUMER, key)));
        } catch (ExecutionException e) {
            LogUtils.error(log, "读取缓存数据异常", e);
            return Optional.empty();
        }
    }
    

    PartnerCallbackDefDao 中的方法 getByTypeAndPartnerId 没有什么特殊逻辑,就是对数据库的访问

    public List<PartnerCallbackDef> getByTypeAndPartnerId(String type, Long partnerId) {
        return mapper.getByTypeAndPartnerId(type, partnerId);
    }
    

    这样很简单的就实现了对数据库访问的缓存,在调用getConsumerCache方法获取指定ID的数据时,会先从缓存中获取,缓存中获取不到或缓存过期时才会从数据集中从新拉取,并且在 Cache.get(Key) 方法中,只要我们保证方法的入参 Key 是线程安全的,那么方法 Cache.get(Key) 就是线程安全的。

更新中....

你可能感兴趣的:(java,性能优化,数据库)