最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

使用@Cacheable注解Redis時Redis宕機或其他原因連不上繼續(xù)調(diào)用原方法的解決方案

 更新時間:2025年05月22日 11:42:25   作者:牛肉胡辣湯  
在Spring Boot應(yīng)用中,我們經(jīng)常使用??@Cacheable??注解來緩存數(shù)據(jù),以提高應(yīng)用的性能,本文將探討如何在Redis不可用時,讓??@Cacheable??注解繼續(xù)調(diào)用原方法,確保服務(wù)的可用性和穩(wěn)定性,感興趣的朋友一起看看吧

@Cacheable注解Redis時,Redis宕機或其他原因連不上,繼續(xù)調(diào)用原方法的解決方案

在Spring Boot應(yīng)用中,我們經(jīng)常使用??@Cacheable??注解來緩存數(shù)據(jù),以提高應(yīng)用的性能。當選擇Redis作為緩存存儲時,如果Redis服務(wù)因某種原因不可用(如宕機、網(wǎng)絡(luò)問題等),默認情況下,??@Cacheable??注解會拋出異常,導(dǎo)致整個請求失敗。本文將探討如何在Redis不可用時,讓??@Cacheable??注解繼續(xù)調(diào)用原方法,確保服務(wù)的可用性和穩(wěn)定性。

1. 問題背景

1.1 ??@Cacheable??注解的基本使用

??@Cacheable??是Spring框架提供的一個注解,用于標識一個方法的結(jié)果需要被緩存。當該方法被調(diào)用時,Spring會先檢查緩存中是否存在對應(yīng)的數(shù)據(jù),如果存在,則直接返回緩存中的數(shù)據(jù);如果不存在,則執(zhí)行方法并將結(jié)果存入緩存。

1.2 Redis宕機的影響

當Redis服務(wù)宕機或網(wǎng)絡(luò)連接出現(xiàn)問題時,??@Cacheable??注解嘗試訪問Redis時會拋出異常,例如??org.springframework.data.redis.RedisConnectionFailureException??。這會導(dǎo)致方法調(diào)用失敗,影響用戶體驗和系統(tǒng)穩(wěn)定性。

2. 解決方案

2.1 使用自定義異常處理器

可以通過自定義異常處理器來捕獲Redis連接異常,并在捕獲到異常時繼續(xù)調(diào)用原方法。具體步驟如下:

2.1.1 創(chuàng)建自定義異常處理器

首先,創(chuàng)建一個自定義異常處理器類,用于處理Redis連接異常。

import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.cache.interceptor.CacheErrorHandler;
public class CustomCacheErrorHandler implements CacheErrorHandler {
    @Override
    public void handleCacheGetError(RuntimeException exception, Cache cache, Object key) {
        // 處理讀取緩存時的異常
        System.out.println("Cache get error: " + exception.getMessage());
    }
    @Override
    public void handleCachePutError(RuntimeException exception, Cache cache, Object key, Object value) {
        // 處理寫入緩存時的異常
        System.out.println("Cache put error: " + exception.getMessage());
    }
    @Override
    public void handleCacheEvictError(RuntimeException exception, Cache cache, Object key) {
        // 處理清除緩存時的異常
        System.out.println("Cache evict error: " + exception.getMessage());
    }
    @Override
    public void handleCacheClearError(RuntimeException exception, Cache cache) {
        // 處理清空緩存時的異常
        System.out.println("Cache clear error: " + exception.getMessage());
    }
}

2.1.2 配置自定義異常處理器

在Spring Boot配置文件中,配置自定義的異常處理器。

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.cache.annotation.EnableCaching;
@Configuration
@EnableCaching
public class CacheConfig {
    @Bean
    public CustomCacheErrorHandler customCacheErrorHandler() {
        return new CustomCacheErrorHandler();
    }
}

2.2 使用??@Cacheable??的??unless??屬性

??@Cacheable??注解提供了一個??unless??屬性,可以在緩存操作成功后決定是否將結(jié)果存入緩存。雖然這個屬性不能直接解決Redis宕機的問題,但可以結(jié)合其他邏輯來實現(xiàn)類似的效果。

2.3 使用??@Cacheable?的??cache-null-values??屬性

設(shè)置??@Cacheable??注解的??cache-null-values??屬性為??false??,這樣即使Redis不可用,也不會將??null??值存入緩存。

@Cacheable(value = "myCache", cacheNullValues = false)
public User getUserById(Long id) {
    return userRepository.findById(id).orElse(null);
}

2.4 使用降級策略

在Redis不可用時,可以采用降級策略,例如從數(shù)據(jù)庫中直接獲取數(shù)據(jù)。這可以通過自定義的緩存管理器來實現(xiàn)。

import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.cache.concurrent.ConcurrentMapCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.Optional;
@Configuration
public class CustomCacheManager {
    @Bean
    public CacheManager cacheManager() {
        return new ConcurrentMapCacheManager("myCache") {
            @Override
            public Cache getCache(String name) {
                Cache cache = super.getCache(name);
                if (cache == null) {
                    // 如果Redis不可用,使用本地緩存
                    cache = new ConcurrentMapCache(name);
                }
                return cache;
            }
        };
    }
}

我們可以在Redis不可用時,確保??@Cacheable???注解繼續(xù)調(diào)用原方法,從而提高系統(tǒng)的穩(wěn)定性和可用性。具體實現(xiàn)方式包括自定義異常處理器、使用??unless???和??cache-null-values??屬性、以及降級策略。在使用Spring框架結(jié)合Redis實現(xiàn)緩存功能時,如果Redis宕機或由于其他原因?qū)е逻B接不上Redis,可以通過配置??CacheManager??來實現(xiàn)當緩存不可用時自動回退到原始方法的調(diào)用。這樣可以保證系統(tǒng)的可用性和穩(wěn)定性。

以下是一個具體的實現(xiàn)示例:

添加依賴:首先確保你的項目中已經(jīng)添加了Spring Boot和Redis的相關(guān)依賴。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId>
</dependency>

配置Redis連接:在application.properties中配置Redis連接信息。

spring.redis.host=localhost
spring.redis.port=6379

自定義CacheManager:創(chuàng)建一個自定義的CacheManager,在其中處理Redis不可用的情況。

import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import java.time.Duration;
import java.util.HashMap;
import java.util.Map;
@Configuration
@EnableCaching
public class CacheConfig {
    @Bean
    public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofHours(1)) // 設(shè)置默認過期時間
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));
        Map<String, RedisCacheConfiguration> cacheConfigurations = new HashMap<>();
        cacheConfigurations.put("myCache", config);
        return new FallbackRedisCacheManager(redisConnectionFactory, config, cacheConfigurations);
    }
}

實現(xiàn)FallbackRedisCacheManager:創(chuàng)建一個自定義的CacheManager,在Redis不可用時回退到內(nèi)存緩存。

import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.cache.concurrent.ConcurrentMapCache;
import org.springframework.cache.support.SimpleCacheManager;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFailureException;
import java.util.Arrays;
import java.util.List;
public class FallbackRedisCacheManager extends RedisCacheManager {
    private final CacheManager fallbackCacheManager;
    public FallbackRedisCacheManager(RedisConnectionFactory connectionFactory, RedisCacheConfiguration defaultCacheConfiguration, Map<String, RedisCacheConfiguration> initialCacheConfigurations) {
        super(connectionFactory, defaultCacheConfiguration, initialCacheConfigurations);
        SimpleCacheManager simpleCacheManager = new SimpleCacheManager();
        simpleCacheManager.setCaches(Arrays.asList(new ConcurrentMapCache("fallbackCache")));
        simpleCacheManager.afterPropertiesSet();
        this.fallbackCacheManager = simpleCacheManager;
    }
    @Override
    public Cache getCache(String name) {
        try {
            return super.getCache(name);
        } catch (RedisConnectionFailureException e) {
            return fallbackCacheManager.getCache(name);
        }
    }
}

使用@Cacheable注解:在需要緩存的方法上使用@Cacheable注解。

import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
@Service
public class MyService {
    @Cacheable(value = "myCache", key = "#id")
    public String getData(String id) {
        // 模擬數(shù)據(jù)獲取過程
        System.out.println("Fetching data from database for ID: " + id);
        return "Data for ID: " + id;
    }
}

通過上述配置,當Redis不可用時,??FallbackRedisCacheManager??會捕獲到??RedisConnectionFailureException??異常,并回退到內(nèi)存緩存。這樣可以確保即使Redis宕機,系統(tǒng)仍然能夠正常運行并返回數(shù)據(jù)。在使用Spring Cache與Redis結(jié)合時,如果Redis出現(xiàn)宕機或連接問題,可以通過配置??CacheManager??和實現(xiàn)自定義的??CacheErrorHandler??來確保即使緩存不可用,業(yè)務(wù)邏輯也能正常運行。以下是一個詳細的解決方案示例:

1. 添加依賴

首先,確保你的項目中已經(jīng)添加了Spring Boot Starter Cache和Spring Boot Starter Data Redis的依賴:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-cache</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
</dependencies>

2. 配置RedisTemplate

配置??RedisTemplate??以使用JSON序列化方式存儲對象:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
public class RedisConfig {
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(connectionFactory);
        template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
        template.setHashKeySerializer(new StringRedisSerializer());
        template.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
        return template;
    }
}

3. 配置CacheManager

配置??CacheManager??以使用Redis作為緩存存儲:

import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import java.time.Duration;
@Configuration
@EnableCaching
public class CacheConfig {
    @Bean
    public CacheManager cacheManager(RedisConnectionFactory connectionFactory) {
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofMinutes(60)) // 設(shè)置緩存過期時間為60分鐘
                .disableCachingNullValues();
        return RedisCacheManager.builder(connectionFactory)
                .cacheDefaults(config)
                .build();
    }
}

4. 實現(xiàn)自定義的CacheErrorHandler

實現(xiàn)自定義的??CacheErrorHandler??,以便在緩存操作失敗時進行處理:

import org.springframework.cache.Cache;
import org.springframework.cache.Cache.ValueException;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.interceptor.CacheErrorHandler;
@Configuration
public class CacheConfig extends CachingConfigurerSupport {
    @Override
    public CacheErrorHandler errorHandler() {
        return new CacheErrorHandler() {
            @Override
            public void handleCacheGetError(RuntimeException exception, Cache cache, Object key) {
                // 處理緩存讀取錯誤
                System.out.println("Cache get error: " + exception.getMessage());
            }
            @Override
            public void handleCachePutError(RuntimeException exception, Cache cache, Object key, Object value) {
                // 處理緩存寫入錯誤
                System.out.println("Cache put error: " + exception.getMessage());
            }
            @Override
            public void handleCacheEvictError(RuntimeException exception, Cache cache, Object key) {
                // 處理緩存刪除錯誤
                System.out.println("Cache evict error: " + exception.getMessage());
            }
            @Override
            public void handleCacheClearError(RuntimeException exception, Cache cache) {
                // 處理緩存清除錯誤
                System.out.println("Cache clear error: " + exception.getMessage());
            }
        };
    }
}

5. 使用@Cacheable注解

在需要緩存的方法上使用??@Cacheable??注解:

import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
@Service
public class UserService {
    @Cacheable(value = "users", key = "#userId")
    public User getUserById(String userId) {
        // 模擬從數(shù)據(jù)庫獲取用戶信息
        System.out.println("Fetching user from database: " + userId);
        return new User(userId, "John Doe");
    }
}

6. 測試

你可以通過模擬Redis宕機或斷開連接來測試上述配置是否生效。例如,可以臨時關(guān)閉Redis服務(wù),然后調(diào)用??getUserById??方法,查看是否能夠正常返回數(shù)據(jù)。

總結(jié)

通過以上配置,當Redis不可用時,??CacheErrorHandler??會捕獲到緩存操作的異常,并打印錯誤信息。同時,由于??@Cacheable??注解的默認行為是當緩存不可用時直接調(diào)用原方法,因此業(yè)務(wù)邏輯不會受到影響。這樣可以確保系統(tǒng)的高可用性和穩(wěn)定性。

到此這篇關(guān)于使用@Cacheable注解Redis時Redis宕機或其他原因連不上繼續(xù)調(diào)用原方法的解決方案的文章就介紹到這了,更多相關(guān)@Cacheable注解 Redis宕機內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Spring?Bean獲取方式的實例化方式詳解

    Spring?Bean獲取方式的實例化方式詳解

    工作中需要對一個原本加載屬性文件的工具類修改成對數(shù)據(jù)庫的操作當然,ado層已經(jīng)寫好,但是需要從Spring中獲取bean,然而,工具類并沒有交給Spring來管理,所以需要通過方法獲取所需要的bean。于是整理了Spring獲取bean的幾種方法
    2023-03-03
  • Java實現(xiàn)跳躍表(skiplist)的簡單實例

    Java實現(xiàn)跳躍表(skiplist)的簡單實例

    這篇文章主要介紹了Java編程中跳躍表的概念和實現(xiàn)原理,并簡要敘述了它的結(jié)構(gòu),具有一定參考價值,需要的朋友可以了解下。
    2017-09-09
  • Intellij 下 mybatis 插件 MyBatisCodeHelperPro破解步驟詳解

    Intellij 下 mybatis 插件 MyBatisCodeHelperPro破解步驟詳解

    這篇文章主要介紹了Intellij 下 mybatis 插件 MyBatisCodeHelperPro破解步驟,本文分步驟給大家介紹的非常詳細,對大家的學(xué)習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-09-09
  • JAVA實現(xiàn)Token自動續(xù)期機制的示例代碼

    JAVA實現(xiàn)Token自動續(xù)期機制的示例代碼

    本文主要介紹了JAVA實現(xiàn)Token自動續(xù)期機制的示例代碼,通過動態(tài)調(diào)整會話生命周期平衡安全性與用戶體驗,解決固定有效期Token帶來的風險與不便,感興趣的可以了解一下
    2025-09-09
  • Java執(zhí)行hadoop的基本操作實例代碼

    Java執(zhí)行hadoop的基本操作實例代碼

    這篇文章主要介紹了Java執(zhí)行hadoop的基本操作實例代碼的相關(guān)資料,需要的朋友可以參考下
    2017-04-04
  • Struts2通過自定義標簽實現(xiàn)權(quán)限控制的方法

    Struts2通過自定義標簽實現(xiàn)權(quán)限控制的方法

    這篇文章主要介紹了Struts2通過自定義標簽實現(xiàn)權(quán)限控制的方法,介紹了定義Struts2的自定義標簽的三個步驟以及詳細解釋,需要的朋友可以參考下。
    2017-09-09
  • IDEA中Maven Dependencies出現(xiàn)紅色波浪線的原因及解決方法

    IDEA中Maven Dependencies出現(xiàn)紅色波浪線的原因及解決方法

    在使用 IntelliJ IDEA 開發(fā) Java 項目時,尤其是基于 Maven 的項目,您可能會遇到 Maven Dependencies 中出現(xiàn)紅色波浪線的問題,這通常意味著項目的依賴無法被正確解析或下載,本文將詳細介紹該問題的原因及解決方法,并附有圖文說明,需要的朋友可以參考下
    2025-06-06
  • win10和win7下java開發(fā)環(huán)境配置教程

    win10和win7下java開發(fā)環(huán)境配置教程

    這篇文章主要為大家詳細介紹了win7下Java開發(fā)環(huán)境配置教程,win10下Java開發(fā)環(huán)境配置,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-06-06
  • SpringMVC框架REST架構(gòu)體系原理分析

    SpringMVC框架REST架構(gòu)體系原理分析

    REST:Representational State Transfer,資源表現(xiàn)層狀態(tài)轉(zhuǎn)換,是目前&#12112;較主流的&#12032;種互聯(lián)網(wǎng)軟件架構(gòu),它結(jié)構(gòu)清晰、標準規(guī)范、易于理解、便于擴展
    2021-09-09
  • java實現(xiàn)多數(shù)據(jù)源切換方式

    java實現(xiàn)多數(shù)據(jù)源切換方式

    本文介紹實現(xiàn)多數(shù)據(jù)源切換的四步方法:導(dǎo)入依賴、配置文件、啟動類注解、使用@DS標記mapper和服務(wù)層,通過注解實現(xiàn)數(shù)據(jù)源動態(tài)切換,適用于實際開發(fā)中的多數(shù)據(jù)源場景
    2025-08-08

最新評論

宁远县| 永靖县| 海盐县| 诏安县| 清镇市| 夏邑县| 合山市| 思茅市| 高平市| 开化县| 绥芬河市| 荔浦县| 武宣县| 新宁县| 驻马店市| 铜梁县| 罗江县| 宜都市| 大冶市| 喀喇沁旗| 高阳县| 静乐县| 阿图什市| 抚顺县| 蒲江县| 电白县| 连南| 卫辉市| 普格县| 中牟县| 嘉禾县| 兴国县| 出国| 兴仁县| 阆中市| 永春县| 杨浦区| 雅安市| 浦北县| 永和县| 安远县|