完成spring boot整合ehcache的搭建以支持服务本地堆缓存

接下来要做这个多级缓存架构,从底往上做,先做缓存数据的生产这一块

我们画图来简单介绍一下整个缓存数据生产服务的一个工作流程

1、商品详情页缓存数据生产服务的工作流程分析

(1)监听多个kafka topic,每个kafka topic对应一个服务(简化一下,监听一个kafka topic)
(2)如果一个服务发生了数据变更,那么就发送一个消息到kafka topic中
(3)缓存数据生产服务监听到了消息以后,就发送请求到对应的服务中调用接口以及拉取数据,此时是从mysql中查询的
(4)缓存数据生产服务拉取到了数据之后,会将数据在本地缓存中写入一份,就是ehcache中
(5)同时会将数据在redis中写入一份

 


因为之前跟大家提过,三级缓存,多级缓存,服务本地堆缓存 + redis分布式缓存 + nginx本地缓存组成的

每一层缓存在高并发的场景下,都有其特殊的用途,需要综合利用多级的缓存,才能支撑住高并发场景下各种各样的特殊情况

服务本地堆缓存,作用,预防redis层的彻底崩溃,作为缓存的最后一道防线,避免数据库直接裸奔

服务本地堆缓存,我们用什么来做缓存,难道我们自己手写一个类或者程序去管理内存吗???java最流行的缓存的框架,ehcache

所以我们也是用ehcache来做本地的堆缓存

spring boot + ehcache整合起来,演示一下是怎么使用的

spring boot整合ehcache

 

   <!-- caching -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-cache</artifactId>
        </dependency>
        <dependency>
            <groupId>net.sf.ehcache</groupId>
            <artifactId>ehcache</artifactId>
        </dependency>

 

# 缓存配置

spring.cache.type=ehcache
spring.cache.ehcache.config=classpath:ehcache.xml


ehcache.xml
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
updateCheck="false">

<!-- diskStore:ehcache其实是支持内存+磁盘+堆外内存,几个层级的缓存 -->
<!-- 在这里设置一下,但是一般不用的 -->
<diskStore path="java.io.tmpdir/Tmp_EhCache" />

<!-- defaultCache,是默认的缓存策略 -->
<!-- 如果你指定的缓存策略没有找到,那么就用这个默认的缓存策略 -->
<!-- external:如果设置为true的话,那么timeout就没有效果,缓存就会一直存在,一般默认就是false -->
<!-- maxElementsInMemory:内存中可以缓存多少个缓存条目,在实践中,你是需要自己去计算的,比如你计算你要缓存的对象是什么?有多大?最多可以缓存多少MB,或者多少个G的数据?除以每个对象的大小,计算出最多可以放多少个对象 -->
<!-- overflowToDisk:如果内存不够的时候,是否溢出到磁盘 -->
<!-- diskPersistent:是否启用磁盘持久化的机制,在jvm崩溃的时候和重启之间,不用 -->
<!-- timeToIdleSeconds:对象最大的闲置的时间,如果超出闲置的时间,可能就会过期,我们这里就不用了,缓存最多闲置5分钟就被干掉了 -->
<!-- timeToLiveSeconds:对象最多存活的时间,我们这里也不用,超过这个时间,缓存就过期,就没了 -->
<!-- memoryStoreEvictionPolicy:当缓存数量达到了最大的指定条目数的时候,需要采用一定的算法,从缓存中清除一批数据,LRU,最近最少使用算法,最近一段时间内,最少使用的那些数据,就被干掉了 -->
<defaultCache
eternal="false"
maxElementsInMemory="1000"
overflowToDisk="false"
diskPersistent="false"
timeToIdleSeconds="300"
timeToLiveSeconds="0"
memoryStoreEvictionPolicy="LRU" />

<!-- 手动指定的缓存策略 -->
<!-- 比如你一个应用吧,可能要缓存很多种不同的数据,比如说商品信息,或者是其他的一些数据 -->
<!-- 对不同的数据,缓存策略可以在这里配置多种 -->
<cache
name="local"
eternal="false"
maxElementsInMemory="1000"
overflowToDisk="false"
diskPersistent="false"
timeToIdleSeconds="300"
timeToLiveSeconds="0"
memoryStoreEvictionPolicy="LRU" />

<!-- ehcache这种东西,简单实用,是很快速的,1小时上手可以用在项目里了,没什么难度的 -->
<!-- ehcache这个技术,如果讲深了,里面的东西还是很多的,高级的feature,但是我们这里就不涉及了 -->

</ehcache>

  

持久化实体类:

 

package com.roncoo.eshop.entity;

/**
 * 商品信息
 * @author Administrator
 *
 */
public class ProductInfo {

	private Long id;
	private String name;
	private Double price;

	public ProductInfo() {

	}

	public ProductInfo(Long id, String name, Double price) {
		this.id = id;
		this.name = name;
		this.price = price;
	}

	public Long getId() {
		return id;
	}
	public void setId(Long id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Double getPrice() {
		return price;
	}
	public void setPrice(Double price) {
		this.price = price;
	}

}

  

缓存service接口:
public interface CacheService {

	/**
	 * 将商品信息保存到本地缓存中
	 * @param productInfo
	 * @return
	 */
	public ProductInfo saveLocalCache(ProductInfo productInfo);

	/**
	 * 从本地缓存中获取商品信息
	 * @param id
	 * @return
	 */
	public ProductInfo getLocalCache(Long id);

}

  持久化实现类:

/**
 * 缓存Service实现类
 * @author Administrator
 *
 */
@Service("cacheService")
public class CacheServiceImpl implements CacheService {

	public static final String CACHE_NAME = "local";

	/**
	 * 将商品信息保存到本地缓存中
	 * @param productInfo
	 * @return
	 */
	@CachePut(value = CACHE_NAME, key = "'key_'+#productInfo.getId()")
	@Override
	public ProductInfo saveLocalCache(ProductInfo productInfo) {
		return productInfo;
	}

	/**
	 * 从本地缓存中获取商品信息
	 * @param id
	 * @return
	 */
	@Cacheable(value = CACHE_NAME, key = "'key_'+#id")
	@Override
	public ProductInfo getLocalCache(Long id) {
		return null;
	}

}

  controller类:

package com.roncoo.eshop.controller;

import com.roncoo.eshop.entity.ProductInfo;
import com.roncoo.eshop.service.CacheService;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;



/**
 * 缓存Controller
 * @author Administrator
 *
 */
@Controller
public class CacheController {

	@Resource
	private CacheService cacheService;

	@RequestMapping("/testPutCache")
	@ResponseBody
	public String testPutCache(ProductInfo productInfo) {
		cacheService.saveLocalCache(productInfo);
		return "success";
	}

	@RequestMapping("/testGetCache")
	@ResponseBody
	public ProductInfo testGetCache(Long id) {
		return cacheService.getLocalCache(id);
	}

}

  接口实现并没有调用其他的持久化而是就加入了一个注解进行持久化操作

接下来设置一个值:

http://localhost:8080/testPutCache?id=1&name=zhangsan&price=21

  获取一个值:http://localhost:8080/testGetCache?id=1

 

posted @ 2022-02-09 23:07  三号小玩家  阅读(332)  评论(0编辑  收藏  举报
Title
三号小玩家的 Mail: 17612457115@163.com, 联系QQ: 1359720840 微信: QQ1359720840