当前位置: 首页 > news >正文

上海由多少家网站建设公司营销策划有限公司经营范围

上海由多少家网站建设公司,营销策划有限公司经营范围,网页地址怎么消除,ps做好的网站如何做链接一道经典面试题:缓存预热有哪些方案? 在系统业务高峰期到来之前,我们提前将一些热点数据加载到缓存中,进而提高系统的响应速度,这就是所谓的缓存预热。 那么怎么实现缓存预热呢? 一般来说,我…

一道经典面试题:缓存预热有哪些方案?

在系统业务高峰期到来之前,我们提前将一些热点数据加载到缓存中,进而提高系统的响应速度,这就是所谓的缓存预热。

那么怎么实现缓存预热呢?

一般来说,我们主要有三种思路:

  • 系统启动时加载缓存。
  • 定时任务加载缓存。
  • 使用缓存加载器。

每种里边往往又对应了不同的具体方案,我们逐一来看。

一 系统启动时加载缓存

这个就是利用系统启动时候的一些钩子函数,或者如事件监听机制或者是框架专为系统启动预留的方法,在这些方法中去加载缓存。

这里松哥给四个常见的思路。

1.1 启动监听事件

使用 ApplicationListener 监听 Spring Boot 启动完成的事件,如 ContextRefreshedEventApplicationReadyEvent,在事件触发后加载数据到缓存。

举个栗子:

import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;@Component
public class CacheWarmer implements ApplicationListener<ContextRefreshedEvent> {@Overridepublic void onApplicationEvent(ContextRefreshedEvent event) {// 假设有一个缓存管理器cacheManagercacheManager.put("key1", "松哥");cacheManager.put("key2", "江南一点雨");// ... 加载更多数据到缓存}
}

1.2 @PostConstruct 注解

使用 @PostConstruct 注解在 Spring Bean 初始化后立即执行缓存预热逻辑。

举个栗子:

import javax.annotation.PostConstruct;
import org.springframework.stereotype.Component;@Component
public class CachePreloader {private final CacheManager cacheManager;public CachePreloader(CacheManager cacheManager) {this.cacheManager = cacheManager;}@PostConstructpublic void preloadCache() {cacheManager.put("key1", "江南一点雨");cacheManager.put("key2", "松哥");// ... 加载更多数据到缓存}
}

1.3 CommandLineRunner 或 ApplicationRunner

实现 CommandLineRunnerApplicationRunner 接口,在 Spring Boot 启动后执行缓存预热。

CommandLineRunner 案例:

import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;@Component
public class MyCommandLineRunner implements CommandLineRunner {private final CacheManager cacheManager;public MyCommandLineRunner(CacheManager cacheManager) {this.cacheManager = cacheManager;}@Overridepublic void run(String... args) throws Exception {cacheManager.put("key1", "江南一点雨");cacheManager.put("key2", "松哥");// ... 加载更多数据到缓存}
}

ApplicationRunner 案例:

import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;@Component
public class MyApplicationRunner implements ApplicationRunner {private final CacheManager cacheManager;public MyApplicationRunner(CacheManager cacheManager) {this.cacheManager = cacheManager;}@Overridepublic void run(ApplicationArguments args) throws Exception {cacheManager.put("key1", "江南一点雨");cacheManager.put("key2", "松哥");// ... 加载更多数据到缓存}
}

1.4 InitializingBean接口

实现 InitializingBean 接口,并在 afterPropertiesSet 方法中执行缓存预热。

案例:

import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;@Component
public class CachePreloader implements InitializingBean {private final CacheManager cacheManager;public CachePreloader(CacheManager cacheManager) {this.cacheManager = cacheManager;}@Overridepublic void afterPropertiesSet() throws Exception {cacheManager.put("key1", "松哥");cacheManager.put("key2", "江南一点雨");// ... 加载更多数据到缓存}
}

在这些案例中,CacheManager是一个假设的缓存管理器,你需要根据实际使用的缓存技术(如 Redis、EhCache 等)来实现或注入相应的缓存管理器。这些代码片段展示了如何在 Spring Boot 应用启动后,通过不同的方式加载数据到缓存中,以减少应用启动后的首次加载延迟。

在系统启动时加载缓存往往有一个问题,就是这些缓存加载之后,不会主动更新。如果我们需要对缓存进行定期更新,那么就可以考虑使用定时任务去加载缓存。

二 定时任务加载缓存

一般来说,如果我们面对以下需求时,就可以考虑使用定时任务加载缓存。

  1. 数据依赖性:当缓存的数据依赖于外部系统或数据库的定期更新,且这些更新不是实时触发的,而是按照一定的时间间隔发生时,可以通过定时任务来预热缓存。
  2. 数据量大:如果预热的数据量非常大,一次性加载可能会对系统性能产生影响,可以通过定时任务分批次逐步加载数据到缓存中。
  3. 依赖多个数据源:当缓存的数据需要从多个数据源聚合时,可以通过定时任务来协调这些数据源的更新,确保缓存的数据一致性和准确性。
  4. 业务逻辑复杂:如果缓存预热的业务逻辑比较复杂,涉及到多步骤处理或者需要等待某些异步操作完成,定时任务可以在特定时间点触发这些复杂的业务逻辑。
  5. 资源分配:在资源受限的环境中,为了避免在应用启动时占用过多资源,可以通过定时任务在系统资源较为空闲的时候进行缓存预热。

举个栗子:假设有一个电商网站,商品信息每天凌晨由供应商更新,并且更新操作不是实时的。在这种情况下,可以设置一个定时任务,在每天凌晨更新完成后,将最新的商品信息加载到缓存中,以便用户在白天访问时能够快速获取到最新的商品数据。

在 Spring 框架中,我们可以使用 @Scheduled 注解来实现定时任务:

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;@Component
public class CacheWarmUpTask {private final CacheManager cacheManager;public CacheWarmUpTask(CacheManager cacheManager) {this.cacheManager = cacheManager;}@Scheduled(cron = "0 0 1 * * ?") // 每天凌晨1点执行public void warmUpCache() {// 执行缓存预热逻辑cacheManager.put("key1", "江南一点雨");cacheManager.put("key2", "松哥");// ... 加载更多数据到缓存}
}

@Scheduled 注解用于指定定时任务的执行计划,cron 表达式定义了任务的执行时间。这样,每天凌晨 1 点,定时任务就会执行,将数据加载到缓存中。

三 使用缓存加载器

缓存加载器(Cache Loader)用于在缓存中自动加载数据。

当缓存中缺少请求的数据时,缓存加载器会被触发,以便从原始数据源(如数据库、文件系统或其他服务)中加载数据并将其放入缓存中。

缓存加载器的主要目的是减少直接从原始数据源加载数据的延迟,提高数据访问的速度。

缓存加载器通常与缓存库或框架一起使用,如 Guava Cache、EhCache、Caffeine 等。在 Spring Cache abstract 中,也可以通过自定义的缓存管理器来实现缓存加载器的功能。

3.1 使用缓存加载器步骤

  1. 定义缓存加载器逻辑:首先,我们需要定义一个加载数据的逻辑,这个逻辑会在缓存中缺失数据时被调用。
  2. 配置缓存:在缓存配置中指定缓存加载器。
  3. 预加载数据:在应用启动时或在特定时间点,通过调用缓存的获取方法来触发缓存加载器,从而预先加载数据到缓存中。
  4. 定时任务:如果需要定期更新缓存,可以结合定时任务(如 Spring 的 @Scheduled 注解)来定期触发缓存加载器。

3.2 举个栗子

Caffeine 是一个高性能的 Java 缓存库,它提供了丰富的缓存策略和灵活的配置选项。Caffeine 并没有直接的缓存预热 API,但是可以通过在应用启动时预先加载数据到缓存中来实现缓存预热的效果。

下面是使用 Caffeine 进行缓存预热的步骤:

  1. 定义缓存:首先,你需要定义一个 Caffeine 缓存实例,并配置相应的缓存策略。
  2. 预加载数据:在应用启动时,通过显式调用缓存的 get 方法或使用 getAll 方法来加载数据到缓存中。
  3. 监听器:如果需要在缓存加载时执行额外的操作,可以配置 CacheLoader 的监听器。
  4. 异步加载:如果数据加载是异步的,可以使用 AsyncLoadingCache 接口来处理异步加载的情况。

代码案例

定义缓存

import com.github.benmanes.caffeine.cache.CacheLoader;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.LoadingCache;import java.util.concurrent.TimeUnit;public class CacheInitializer {public static LoadingCache<String, String> createCache() {CacheLoader<String, String> loader = new CacheLoader<String, String>() {@Overridepublic String load(String key) {// 模拟从数据库或其他数据源加载数据return "Value for " + key;}};return Caffeine.newBuilder().expireAfterWrite(10, TimeUnit.MINUTES) // 设置写入后过期时间.maximumSize(1000) // 设置最大缓存项数.build(loader);}
}

预加载数据

import com.github.benmanes.caffeine.cache.LoadingCache;import java.util.Arrays;
import java.util.concurrent.ExecutionException;public class CacheWarmUp {private final LoadingCache<String, String> cache;public CacheWarmUp(LoadingCache<String, String> cache) {this.cache = cache;}public void warmUp() throws ExecutionException {// 预加载数据到缓存Arrays.asList("key1", "key2", "key3").forEach(key -> {try {cache.get(key); // 这将触发加载器加载数据} catch (ExecutionException e) {e.printStackTrace();}});}
}

在 Spring Boot 应用中使用

import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;@Component
public class CacheWarmUpRunner implements CommandLineRunner {private final LoadingCache<String, String> cache;public CacheWarmUpRunner(LoadingCache<String, String> cache) {this.cache = cache;}@Overridepublic void run(String... args) {try {new CacheWarmUp(cache).warmUp();} catch (Exception e) {e.printStackTrace();}}
}

在这个示例中,CacheInitializer 类定义了一个 Caffeine 缓存实例,CacheWarmUp 类包含了预加载数据到缓存的逻辑。CacheWarmUpRunner 是一个 Spring Boot 的 CommandLineRunner,它在应用启动时调用 CacheWarmUp 类来预加载数据。

通过这种方式,你可以在应用启动时预先加载数据到 Caffeine 缓存中,从而实现缓存预热。这对于提高应用的响应速度和减少首次加载延迟非常有帮助。

上面的案例本质上还是利用了 CommandLineRunner,不过,LoadingCache 在配置的时候,其实也可以设置一个自动刷新的时间,这样就不需要 CommandLineRunner 了,系统会自动执行。

好啦,缓存预热的三种思路,小伙伴们平时都是怎么做的?欢迎留言讨论。

http://www.hkea.cn/news/549084/

相关文章:

  • 奉贤建设机械网站制作长沙网址seo
  • 上海企业网站模板建站常用的网络推广方法
  • 大连零基础网站建设教学培训济南seo优化公司
  • html 做网站案例简单网站推广建设
  • 践行新使命忠诚保大庆网站建设线上广告
  • 定制网站建设服务商商家联盟营销方案
  • 集团官网建设公司外贸seo推广公司
  • 佛山新网站制作平台网站诊断工具
  • 做PPT的网站canvawhois查询
  • 营销型网站建设吉林定制化网站建设
  • 个人网上公司注册流程图新站优化案例
  • 做se要明白网站明星百度指数排名
  • 网页微博草稿箱在哪西安seo推广优化
  • 嘉兴微信网站建设谷歌首页
  • 什么网站做海报b站不收费网站
  • 如何自己做个简单网站seo知识点
  • 有哪些做批发的网站有哪些手续百度推广优化是什么意思
  • 用阿里巴巴店铺做公司网站怎么样引擎搜索有哪些
  • 网页制作软件属于什么软件类别简述seo的优化流程
  • 网站建设 公司新闻谷歌排名网站优化
  • 怎样做自己的vip解析网站佛山外贸seo
  • 我的网站在百度搜不到了seo是什么职业做什么的
  • 网站私信界面国外网站seo免费
  • wordpress mysql类惠州网站seo
  • 为什么做网站必须要用域名举出最新的网络营销的案例
  • 电子请柬网站开发百度竞价推广登录入口
  • 网站设计与推广国际时事新闻2022最新
  • 柬埔寨网站开发营销技巧和营销方法
  • 网站建立价格长沙网站外包公司
  • 王建设医生个人网站免费google账号注册入口