偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

第一次使用緩存,因?yàn)闆](méi)預(yù)熱,翻車(chē)了

存儲(chǔ)
我們使用 Caffeine.newBuilder().refreshAfterWrite(1, TimeUnit.MINUTES) 配置了緩存的自動(dòng)刷新機(jī)制,即每個(gè)緩存項(xiàng)在寫(xiě)入后的1分鐘內(nèi),如果有讀請(qǐng)求,Caffeine 會(huì)自動(dòng)觸發(fā)數(shù)據(jù)的刷新。

預(yù)熱一般指緩存預(yù)熱,一般用在高并發(fā)系統(tǒng)中,為了提升系統(tǒng)在高并發(fā)情況下的穩(wěn)定性的一種手段。

緩存預(yù)熱是指在系統(tǒng)啟動(dòng)之前或系統(tǒng)達(dá)到高峰期之前,通過(guò)預(yù)先將常用數(shù)據(jù)加載到緩存中,以提高緩存命中率和系統(tǒng)性能的過(guò)程。緩存預(yù)熱的目的是盡可能地避免緩存擊穿和緩存雪崩,還可以減輕后端存儲(chǔ)系統(tǒng)的負(fù)載,提高系統(tǒng)的響應(yīng)速度和吞吐量。

預(yù)熱的必要性

緩存預(yù)熱的好處有很多,如:

  1. 減少冷啟動(dòng)影響:當(dāng)系統(tǒng)重啟或新啟動(dòng)時(shí),緩存是空的,這被稱(chēng)為冷啟動(dòng)。冷啟動(dòng)可能導(dǎo)致首次請(qǐng)求處理緩慢,因?yàn)閿?shù)據(jù)需要從慢速存儲(chǔ)(如數(shù)據(jù)庫(kù))檢索。
  2. 提高數(shù)據(jù)訪問(wèn)速度:通過(guò)預(yù)先加載常用數(shù)據(jù)到緩存中,可以確保數(shù)據(jù)快速可用,從而加快數(shù)據(jù)訪問(wèn)速度。
  3. 平滑流量峰值:在流量高峰期之前預(yù)熱緩存可以幫助系統(tǒng)更好地處理高流量,避免在流量激增時(shí)出現(xiàn)性能下降。
  4. 保證數(shù)據(jù)的時(shí)效性:定期預(yù)熱可以保證緩存中的數(shù)據(jù)是最新的,特別是對(duì)于高度依賴(lài)于實(shí)時(shí)數(shù)據(jù)的系統(tǒng)。
  5. 減少對(duì)后端系統(tǒng)的壓力:通過(guò)緩存預(yù)熱,可以減少對(duì)數(shù)據(jù)庫(kù)或其他后端服務(wù)的直接查詢(xún),從而減輕它們的負(fù)載。

預(yù)熱的方法

緩存預(yù)熱的一般做法是在系統(tǒng)啟動(dòng)或系統(tǒng)空閑期間,將常用的數(shù)據(jù)加載到緩存中,主要做法有以下幾種:

系統(tǒng)啟動(dòng)時(shí)加載:在系統(tǒng)啟動(dòng)時(shí),將常用的數(shù)據(jù)加載到緩存中,以便后續(xù)的訪問(wèn)可以直接從緩存中獲取。

定時(shí)任務(wù)加載:定時(shí)執(zhí)行任務(wù),將常用的數(shù)據(jù)加載到緩存中,以保持緩存中數(shù)據(jù)的實(shí)時(shí)性和準(zhǔn)確性。

手動(dòng)觸發(fā)加載:在系統(tǒng)達(dá)到高峰期之前,手動(dòng)觸發(fā)加載常用數(shù)據(jù)到緩存中,以提高緩存命中率和系統(tǒng)性能。

用時(shí)加載:在用戶(hù)請(qǐng)求到來(lái)時(shí),根據(jù)用戶(hù)的訪問(wèn)模式和業(yè)務(wù)需求,動(dòng)態(tài)地將數(shù)據(jù)加載到緩存中。

緩存加載器:一些緩存框架提供了緩存加載器的機(jī)制,可以在緩存中不存在數(shù)據(jù)時(shí),自動(dòng)調(diào)用加載器加載數(shù)據(jù)到緩存中。

Redis預(yù)熱

在分布式緩存中,我們通常都是使用Redis,針對(duì)Redis的預(yù)熱,有以下幾個(gè)工具可供使用,幫助我們實(shí)現(xiàn)緩存的預(yù)熱:

RedisBloom:RedisBloom是Redis的一個(gè)模塊,提供了多個(gè)數(shù)據(jù)結(jié)構(gòu),包括布隆過(guò)濾器、計(jì)數(shù)器、和TopK數(shù)據(jù)結(jié)構(gòu)等。其中,布隆過(guò)濾器可以用于Redis緩存預(yù)熱,通過(guò)將預(yù)熱數(shù)據(jù)添加到布隆過(guò)濾器中,可以快速判斷一個(gè)鍵是否存在于緩存中。

Redis Bulk loading:這是一個(gè)官方出的,基于Redis協(xié)議批量寫(xiě)入數(shù)據(jù)的工具

Redis Desktop Manager:Redis Desktop Manager是一個(gè)圖形化的Redis客戶(hù)端,可以用于管理Redis數(shù)據(jù)庫(kù)和進(jìn)行緩存預(yù)熱。通過(guò)Redis Desktop Manager,可以輕松地將預(yù)熱數(shù)據(jù)批量導(dǎo)入到Redis緩存中。

應(yīng)用啟動(dòng)時(shí)預(yù)熱

ApplicationReadyEvent

在應(yīng)用程序啟動(dòng)時(shí),可以通過(guò)監(jiān)聽(tīng)?wèi)?yīng)用啟動(dòng)事件,或者在應(yīng)用的初始化階段,將需要緩存的數(shù)據(jù)加載到緩存中。

ApplicationReadyEvent 是 Spring Boot 框架中的一個(gè)事件類(lèi),它表示應(yīng)用程序已經(jīng)準(zhǔn)備好接收請(qǐng)求,即應(yīng)用程序已啟動(dòng)且上下文已刷新。這個(gè)事件是在 ApplicationContext 被初始化和刷新,并且應(yīng)用程序已經(jīng)準(zhǔn)備好處理請(qǐng)求時(shí)觸發(fā)的。

基于ApplicationReadyEvent,我們可以在應(yīng)用程序完全啟動(dòng)并處于可用狀態(tài)后執(zhí)行一些初始化邏輯。使用 @EventListener 注解或?qū)崿F(xiàn) ApplicationListener 接口來(lái)監(jiān)聽(tīng)這個(gè)事件。例如,使用 @EventListener 注解:

@EventListener(ApplicationReadyEvent.class)
public void preloadCache() {
    // 在應(yīng)用啟動(dòng)后執(zhí)行緩存預(yù)熱邏輯
    // ...
}

Runner

如果你不想直接監(jiān)聽(tīng)ApplicationReadyEvent,在SpringBoot中,也可以通過(guò)CommandLineRunner 和 ApplicationRunner 來(lái)實(shí)現(xiàn)這個(gè)功能。

CommandLineRunner 和 ApplicationRunner 是 Spring Boot 中用于在應(yīng)用程序啟動(dòng)后執(zhí)行特定邏輯的接口。這解釋聽(tīng)上去就像是專(zhuān)門(mén)干這個(gè)事兒的。

import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

@Component
public class MyCommandLineRunner implements CommandLineRunner {

    @Override
    public void run(String... args) throws Exception {
        // 在應(yīng)用啟動(dòng)后執(zhí)行緩存預(yù)熱邏輯
        // ...
    }
}

import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

@Component
public class MyApplicationRunner implements ApplicationRunner {

    @Override
    public void run(ApplicationArguments args) throws Exception {
        // 在應(yīng)用啟動(dòng)后執(zhí)行緩存預(yù)熱邏輯
        // ...
    }

}

CommandLineRunner 和 ApplicationRunner的調(diào)用,是在SpringApplication的run方法中

其實(shí)就是callRunners(context, applicationArguments);的實(shí)現(xiàn):

private void callRunners(ApplicationContext context, ApplicationArguments args) {
    List<Object> runners = new ArrayList<>();
    runners.addAll(context.getBeansOfType(ApplicationRunner.class).values());
    runners.addAll(context.getBeansOfType(CommandLineRunner.class).values());
    AnnotationAwareOrderComparator.sort(runners);
    for (Object runner : new LinkedHashSet<>(runners)) {
        if (runner instanceof ApplicationRunner) {
            callRunner((ApplicationRunner) runner, args);
        }
        if (runner instanceof CommandLineRunner) {
            callRunner((CommandLineRunner) runner, args);
        }
    }
}

使用InitializingBean接口

實(shí)現(xiàn) InitializingBean 接口,并在 afterPropertiesSet 方法中執(zhí)行緩存預(yù)熱的邏輯。這樣,Spring 在初始化 Bean 時(shí)會(huì)調(diào)用 afterPropertiesSet 方法。

import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;

@Component
public class CachePreloader implements InitializingBean {

    @Override
    public void afterPropertiesSet() throws Exception {
        // 執(zhí)行緩存預(yù)熱邏輯
        // ...
    }
}

這個(gè)方法的調(diào)用我們?cè)赟pring的啟動(dòng)流程中也介紹過(guò),不再展開(kāi)了

使用@PostConstruct注解

類(lèi)似的,我們還可以使用 @PostConstruct 注解標(biāo)注一個(gè)方法,該方法將在 Bean 的構(gòu)造函數(shù)執(zhí)行完畢后立即被調(diào)用。在這個(gè)方法中執(zhí)行緩存預(yù)熱的邏輯。

import javax.annotation.PostConstruct;
import org.springframework.stereotype.Component;

@Component
public class CachePreloader {

    @PostConstruct
    public void preloadCache() {
        // 執(zhí)行緩存預(yù)熱邏輯
        // ...
    }
}

定時(shí)任務(wù)預(yù)熱

在啟動(dòng)過(guò)程中預(yù)熱有一個(gè)問(wèn)題,那就是一旦啟動(dòng)之后,如果需要預(yù)熱新的數(shù)據(jù),或者需要修改數(shù)據(jù),就不支持了,那么,在應(yīng)用的運(yùn)行過(guò)程中,我們也是可以通過(guò)定時(shí)任務(wù)來(lái)實(shí)現(xiàn)緩存的更新預(yù)熱的。

我們通常依賴(lài)這種方式來(lái)確保緩存中的數(shù)據(jù)是最新的,避免因?yàn)闃I(yè)務(wù)數(shù)據(jù)的變化而導(dǎo)致緩存數(shù)據(jù)過(guò)時(shí)。

在Spring中,想要實(shí)現(xiàn)一個(gè)定時(shí)任務(wù)也挺簡(jiǎn)單的,基于@Scheduled就可以輕易實(shí)現(xiàn).

@Scheduled(cron = "0 0 1 * * ?") // 每天凌晨1點(diǎn)執(zhí)行
public void scheduledCachePreload() {
    // 執(zhí)行緩存預(yù)熱邏輯
    // ...
}

也可以依賴(lài)xxl-job等定時(shí)任務(wù)實(shí)現(xiàn)。

緩存器預(yù)熱

些緩存框架提供了緩存加載器的機(jī)制,可以在緩存中不存在數(shù)據(jù)時(shí),自動(dòng)調(diào)用加載器加載數(shù)據(jù)到緩存中。這樣可以簡(jiǎn)化緩存預(yù)熱的邏輯。如Caffeine中就有這樣的功能:

import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.LoadingCache;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

@Service
public class MyCacheService {

    private final LoadingCache<String, String> cache;

    public MyCacheService() {
        this.cache = Caffeine.newBuilder()
                .refreshAfterWrite(1, TimeUnit.MINUTES)  // 配置自動(dòng)刷新,1分鐘刷新一次
                .build(key -> loadDataFromSource(key));  // 使用加載器加載數(shù)據(jù)
    }

    public String getValue(String key) {
        return cache.get(key);
    }

    private String loadDataFromSource(String key) {
        // 從數(shù)據(jù)源加載數(shù)據(jù)的邏輯
        // 這里只是一個(gè)示例,實(shí)際應(yīng)用中可能是從數(shù)據(jù)庫(kù)、外部服務(wù)等獲取數(shù)據(jù)
        System.out.println("Loading data for key: " + key);
        return "Value for " + key;
    }
}

在上面的例子中,我們使用 Caffeine.newBuilder().refreshAfterWrite(1, TimeUnit.MINUTES) 配置了緩存的自動(dòng)刷新機(jī)制,即每個(gè)緩存項(xiàng)在寫(xiě)入后的1分鐘內(nèi),如果有讀請(qǐng)求,Caffeine 會(huì)自動(dòng)觸發(fā)數(shù)據(jù)的刷新。

loadDataFromSource 方法是用于加載數(shù)據(jù)的自定義方法。你可以在這個(gè)方法中實(shí)現(xiàn)從數(shù)據(jù)源(例如數(shù)據(jù)庫(kù)、外部服務(wù))加載數(shù)據(jù)的邏輯。

責(zé)任編輯:武曉燕 來(lái)源: Hollis
相關(guān)推薦

2011-07-21 21:01:37

諾基亞塞班蘋(píng)果

2024-08-08 08:50:21

標(biāo)簽頁(yè)portTab

2017-03-22 15:38:28

代碼架構(gòu)Java

2022-05-06 11:27:23

虛擬人白皮書(shū)行業(yè)

2023-09-11 00:14:46

后端團(tuán)隊(duì)項(xiàng)目

2019-07-31 15:14:33

2022-08-15 08:16:56

shiroWeb認(rèn)證

2012-04-13 10:11:58

Windows 8泄露

2022-03-16 14:59:28

打包debian模板文件

2015-10-26 16:38:17

2022-06-21 09:26:28

開(kāi)源項(xiàng)目PR

2021-02-05 08:35:21

私活程序員

2017-09-01 14:00:04

操作系統(tǒng)蘋(píng)果OS X系統(tǒng)

2018-01-17 10:52:56

惠普聯(lián)想PC

2021-07-05 22:09:53

面試官CollectionsJDK7

2012-01-18 11:18:12

Web App

2015-11-02 14:42:12

2017-08-08 12:50:51

Serverless云端數(shù)據(jù)庫(kù)

2013-02-25 09:43:22

LambdasJava8

2018-11-21 14:51:00

Windows 功能系統(tǒng)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)