性能提升!Spring Boot使用Guava中3大神技

文摘   2024-11-09 10:00   新疆  

最新实战案例锦集:《Spring Boot3实战案例合集》持续更新,每天至少更新一篇文章,订阅后将赠送文章最后展示的所有MD文档(学习笔记)。

环境:Spring Boot3.2.5 + Guava



1. 简介

Guava 是 Google 开源的一个 Java 库,提供了一系列实用的功能和工具类,旨在简化常见的编程任务并提高代码质量和可维护性。Guava 包含了许多强大的功能,如集合扩展、缓存机制、并发工具、字符串处理、散列函数等。Guava的功能众多,本篇文章将只对缓存布隆过滤器限流做详细介绍。

  • 缓存

    Guava 提供了一个高性能的本地缓存机制,通过 Cache 类实现。Cache 支持自动过期、最大容量限制和加载策略等功能。它简化了缓存的管理和使用,适用于需要频繁访问且计算成本高的数据。

  • 布隆过滤器

    Guava 的 BloomFilter 是一种空间高效的概率数据结构,用于判断一个元素是否存在于集合中。它通过哈希函数将元素映射到一个位数组,支持快速的成员查询,但可能会有少量误报。布隆过滤器常用于大数据场景,如搜索引擎、数据库索引和网络爬虫,用于快速排除不存在的元素,减少不必要的计算和IO操作。

  • 限流

    Guava 提供了 RateLimiter 类来实现限流功能,通过令牌桶算法控制请求的速率。RateLimiter 可以限制每秒处理的请求数量,防止系统因突发流量而过载。它适用于需要控制访问频率的场景,如API调用、数据库访问和网络请求,确保系统稳定性和可用性。

     

接下来,我们将详细介绍以上3个功能在Spring Boot项目中的使用。

2. 实战案例

2.1 环境准备

<dependency>  <groupId>com.google.guava</groupId>  <artifactId>guava</artifactId>  <version>33.3.1-jre</version></dependency>

当前使用的是最新版本(2024/11/09)。

2.2 缓存

缓存在各种使用场景中都非常有用。例如,当你需要多次获取某个输入的值,而该值的计算或检索成本很高时,你应该考虑使用缓存。

Guava CacheConcurrentMap 相似,但又不完全相同。最根本的区别在于,ConcurrentMap 会持久保存所有添加到其中的元素,直到它们被明确删除。而Guava Cache 通常会自动驱逐条目,以限制内存占用。在某些情况下,即使不驱逐条目,LoadingCache 仍然很有用,因为它的自动缓存加载功能。如下示例:

LoadingCache<Long, User> cache = CacheBuilder.newBuilder()    .maximumSize(1000)    .expireAfterWrite(10, TimeUnit.MINUTES)    .build(       new CacheLoader<Long, User>() {         @Override         public User load(Long key) {           System.out.println("从DB加载数据") ;           return new User(1L, "Pack", 33) ;         }       });System.out.println(cache.get(1L)) ;System.out.println(cache.get(1L)) ;System.out.println(cache.get(1L)) ;

运行上面代码输出结果

DB加载数据User [id=1, name=Pack, age=33]User [id=1, name=Pack, age=33]User [id=1, name=Pack, age=33]

只有第一次会执行我们CacheLoader#load方法去加载数据,一旦加载后就会存于缓存中,后续直接从缓存中获取。

从Callable加载数据

当我们从缓存中获取数据时调用get方法,都可以传递第二个参数Callable,如下:

get(K, Callable<V>)

如果缓存中没有指定的key,则会调用Callable回调方法获取数据加载到缓存中,如下示例:

Cache<Long, User> cache = CacheBuilder.newBuilder()    .maximumSize(1000)    .expireAfterWrite(10, TimeUnit.MINUTES)    .build() ;User ret = cache.get(1L, () -> {  System.out.println("从DB加载数据") ;  return new User(1L, "Pack", 33) ;}) ;System.out.println(ret) ;ret = cache.get(1L, () -> {  System.out.println("从DB加载数据") ;  return new User(1L, "Pack", 33) ;}) ;System.out.println(ret) ;

输出结果

DB加载数据User [id=1, name=Pack, age=33]User [id=1, name=Pack, age=33]

缓存中已经存在,所以第二次不会执行Callable回调。

Spring全家桶实战案例源码
spring, springboot, springcloud 案例开发详解
 最新文章