Skip to content

guangxush/SpringBoot_GuavaCache

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

18 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

SpringBoot_GuavaCache

  • 使用Guava做缓存,将数据库查询结果保存在缓存里面,下次查询可以直接从内存中取值

  • 直接测试查询一本书的数据:http://localhost:8080/booksys/book/3

    第一次查询现实数据库查询语句,第二次查询直接从内存中读取

  • 查询全部的书籍数据(未删除并且审核通过):http://localhost:8080/booksys/book/books

基本原理

  • 如果某个请求需要频繁的去数据库中请求数据,当用户量较大且服务器性能较低的时候会导致服务效率低下,QPS较低

image.png

  • 这时我们可以把这些固定的请求,先用一个线程去数据库里面查询,然后把他放入缓存中,这样后序的线程再请求的时候就会直接从缓存中取数据,从而提高了查询性能也缓解了数据库的压力

image.png

什么时候使用缓存

如果你的需求满足以下条件可以使用Cahce缓存数据

  • 愿意消耗一些内存空间来提升速度
  • 预料到某些键会被查询一次以上
  • 缓存中存放的数据总量不会超过内存容量

项目场景

我们这里设计了一张图书信息表,用于查询,因为一般网站的主页上都会显示最新上架的一些图书,可以把这些固定的查询图书的信息放到缓存里,这里使用SpringBoot+Guava的技术方案;

image.png

基本配置

pom.xml引入依赖“

<dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>18.0</version> </dependency> 

application.yml中配置缓存大小和缓存时间

# guava guava: cache: maximumSize: 10000 expire: 15 

查询语句

缓存设置

private LoadingCache<Long, Book> booksCache = CacheBuilder.newBuilder() .recordStats() .maximumSize(1000) .expireAfterAccess(10, TimeUnit.DAYS) .build( new CacheLoader<Long, Book>() { @Override public Book load(Long id) throws Exception { List<Book> bookVOList = findAllBookById(Collections.singletonList(id)); if (bookVOList != null && bookVOList.size() != 0) { return bookVOList.get(0); } return new Book(BOOK_NAME, BOOK_AUTHOR, PUBLISH_HOUSE); } } ); 

数据库查询请求

public List<Book> findAllBookById(List<Long> ids) { List<Book> books = new ArrayList<>(); Optional<List<Book>> booksOption = bookRepo.findAllById(ids); if (booksOption.isPresent()) { books = booksOption.get(); } return books; } 

最终查询请求

public Book fetchBookById(Long id) { if (id == null) { log.error("the id is null"); throw new NullPointerException("the id is null"); } //从缓存中获取 try { Book book = booksCache.get(id); if (book != null) { return book; } } catch (ExecutionException e) { log.error("take book from guava cache error, id : {}", id, e); } //从数据库中查询 List<Book> vos = findAllBookById(Lists.newArrayList(id)); if (vos.isEmpty()) { //返回默认值 Book book = new Book(); book.setId(id); book.setName(BOOK_NAME); book.setAuthor(BOOK_AUTHOR); book.setPublishHouse(PUBLISH_HOUSE); return book; } return vos.get(0); } 

外部请求Controller

@RequestMapping(path = "/{id}", method = RequestMethod.GET) public Book findBookInfoById(@PathVariable("id")Long id){ Book book = bookService.fetchBookById(id); if(book!=null){ return book; }else{ return null; } } 

请求结果查看

直接测试查询一本书的数据:http://localhost:8080/booksys/book/3 第一次查询现实数据库查询语句 image.png

第二次查询直接从内存中读取,SQL还是原来的一条 image.png

因此有了缓存,我们可以减少很多计算压力,提高应用程序的QPS。

项目源码

项目源码

About

SpringBoot Guava Chache

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published