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

Springboot整合Redis主從實(shí)踐

 更新時(shí)間:2025年06月12日 14:23:47   作者:xiaomu_a  
這篇文章主要介紹了Springboot整合Redis主從的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

前言

SpringBoot版本:2.3.2.RELEASE

原配置

原yml配置內(nèi)容:

spring:
  # Redis服務(wù)器配置
  redis:
    host: 127.0.0.1
    # Redis服務(wù)器連接端口
    port: 6379
    # Redis服務(wù)器連接密碼
    password: redis@123
    #連接超時(shí)時(shí)間(毫秒)
    timeout: 30000ms
    jedis:
      # Redis服務(wù)器連接池
      pool:
        # 連接池最大連接數(shù)(使用負(fù)值表示沒有限制)
        maxIdle: 400
        #連接池中的最小空閑連接
        minIdle: 100
        #連接池中的最大空閑連接
        maxActive: 400
        # 連接池最大阻塞等待時(shí)間(使用負(fù)值表示沒有限制)
        maxWait: -1ms
    lettuce:
      pool:
        max-idle: 400
        min-idle: 100
        max-active: 400
        max-wait: -1ms

原RedisConfig配置類:

import com.alibaba.fastjson.support.spring.FastJsonRedisSerializer;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;

@Configuration
@EnableCaching
@AutoConfigureAfter(RedisAutoConfiguration.class)
public class RedisConfig {

    @Bean
    @ConditionalOnMissingBean(value = StringRedisTemplate.class, name = "stringRedisTemplate")
    public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory factory) {
        StringRedisTemplate template = new StringRedisTemplate();
        template.setConnectionFactory(factory);
        return template;
    }
}

現(xiàn)配置

現(xiàn)yml配置內(nèi)容:

spring:
  redis:
    # 主節(jié)點(diǎn)
    master:
      host: 127.0.0.1
      port: 6379
      password: redis@123
    # 副本節(jié)點(diǎn)
    replicas:
      - host: 127.0.0.1
        port: 6380
    #連接超時(shí)時(shí)間(毫秒)
    timeout: 30000ms
    jedis:
      # Redis服務(wù)器連接池
      pool:
        # 連接池最大連接數(shù)(使用負(fù)值表示沒有限制)
        maxIdle: 400
        #連接池中的最小空閑連接
        minIdle: 100
        #連接池中的最大空閑連接
        maxActive: 400
        # 連接池最大阻塞等待時(shí)間(使用負(fù)值表示沒有限制)
        maxWait: -1ms
    lettuce:
      pool:
        max-idle: 400
        min-idle: 100
        max-active: 400
        max-wait: -1ms

現(xiàn)RedisConfig配置類:

import com.alibaba.fastjson.support.spring.FastJsonRedisSerializer;
import com.juxiao.xchat.manager.cache.properties.RedisMasterReplicaProperties;
import io.lettuce.core.ClientOptions;
import io.lettuce.core.ReadFrom;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisPassword;
import org.springframework.data.redis.connection.RedisStaticMasterReplicaConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettucePoolingClientConfiguration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;

@Configuration
@EnableCaching
@AutoConfigureAfter(RedisAutoConfiguration.class)
@EnableConfigurationProperties({RedisMasterReplicaProperties.class, RedisProperties.class})
public class RedisConfig {

    private final RedisMasterReplicaProperties properties;
    private final RedisProperties redisProperties;

    public RedisConfig(RedisMasterReplicaProperties redisMasterReplicaProperties, RedisProperties redisProperties) {
        this.properties = redisMasterReplicaProperties;
        this.redisProperties = redisProperties;
    }

    public LettuceConnectionFactory redisConnectionFactory(boolean readFromMaster) {
        RedisStaticMasterReplicaConfiguration config = new RedisStaticMasterReplicaConfiguration(
                properties.getMaster().getHost(), properties.getMaster().getPort()
        );
        String password = properties.getMaster().getPassword();
        if (StringUtils.isNotBlank(password)) {
            config.setPassword(RedisPassword.of(password));
        }
        for (RedisMasterReplicaProperties.Node replica : properties.getReplicas()) {
            config.addNode(replica.getHost(), replica.getPort());
        }

        // 連接池配置
        LettucePoolingClientConfiguration.LettucePoolingClientConfigurationBuilder builder =
                LettucePoolingClientConfiguration.builder().commandTimeout(redisProperties.getTimeout());
        // 使用 application.yml 中的 lettuce.pool 參數(shù)
        RedisProperties.Pool poolProps = redisProperties.getLettuce().getPool();
        if (poolProps != null) {
            builder.poolConfig(poolConfig(poolProps));
        }
        // 優(yōu)先從副本讀取
        builder.readFrom(readFromMaster ? ReadFrom.MASTER : ReadFrom.REPLICA_PREFERRED);
        // 斷開連接時(shí)拒絕命令[而不是再等待連接超時(shí)時(shí)間后再報(bào)錯(cuò)]、啟用自動(dòng)重連
        builder.clientOptions(ClientOptions.builder()
                .disconnectedBehavior(ClientOptions.DisconnectedBehavior.REJECT_COMMANDS)
                .autoReconnect(true)
                .build());
        LettucePoolingClientConfiguration lettucePoolingClientConfiguration = builder.build();
        // 構(gòu)建連接工廠
        LettuceConnectionFactory factory = new LettuceConnectionFactory(config, lettucePoolingClientConfiguration);
        // 禁用共享連接 默認(rèn)是true
        // factory.setShareNativeConnection(false);
        // 初始化工廠 否則調(diào)用StringRedisTemplate時(shí)會(huì)空指針 【因?yàn)閞edisConnectionFactory 方法沒有使用@Bean注解將LettuceConnectionFactory交給Spring工廠管理 所以需要手動(dòng)調(diào)用afterPropertiesSet方法初始化連接工廠】
        factory.afterPropertiesSet();
        return factory;
    }

    // 連接池參數(shù)綁定
    private GenericObjectPoolConfig<?> poolConfig(RedisProperties.Pool poolProps) {
        GenericObjectPoolConfig<?> config = new GenericObjectPoolConfig<>();
        config.setMaxTotal(poolProps.getMaxActive());
        config.setMaxIdle(poolProps.getMaxIdle());
        config.setMinIdle(poolProps.getMinIdle());
        config.setMaxWaitMillis(poolProps.getMaxWait().toMillis());
        return config;
    }

    @Bean
    @ConditionalOnMissingBean(name = "redisTemplate")
    public RedisTemplate<Object, Object> redisTemplate(LettuceConnectionFactory redisConnectionFactory) {
        redisConnectionFactory.setShareNativeConnection(false);
        RedisTemplate<Object, Object> template = new RedisTemplate<>();
        //使用fastjson序列化
        FastJsonRedisSerializer<Object> serializer = new FastJsonRedisSerializer<>(Object.class);
        // value值的序列化采用fastJsonRedisSerializer
        template.setValueSerializer(serializer);
        template.setHashValueSerializer(serializer);
        // key的序列化采用StringRedisSerializer
        template.setKeySerializer(new StringRedisSerializer());
        template.setHashKeySerializer(new StringRedisSerializer());
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }

    @Bean("masterStringRedisTemplate")
    @ConditionalOnMissingBean(name = "masterStringRedisTemplate")
    public StringRedisTemplate masterStringRedisTemplate() {
        StringRedisTemplate template = new StringRedisTemplate();
        template.setConnectionFactory(redisConnectionFactory(true));
        return template;
    }

    @Bean("replicaStringRedisTemplate")
    @ConditionalOnMissingBean(name = "replicaStringRedisTemplate")
    public StringRedisTemplate replicaStringRedisTemplate() {
        StringRedisTemplate template = new StringRedisTemplate();
        template.setConnectionFactory(redisConnectionFactory(false));
        return template;
    }
}

新增RedisMasterReplicaProperties配置類:

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

import java.util.ArrayList;
import java.util.List;

@Data
@ConfigurationProperties(prefix = "spring.redis")
public class RedisMasterReplicaProperties {

    /**
     * 主節(jié)點(diǎn)
     */
    private Node master;
    /**
     * 從節(jié)點(diǎn)
     */
    private List<Node> replicas = new ArrayList<>();

    @Data
    public static class Node {
        /**
         * 主機(jī)地址
         */
        private String host;
        /**
         * 端口
         */
        private int port;
        /**
         * 密碼(主從模式master、slave密碼必須設(shè)置一樣的)
         */
        private String password;
    }
}

測試

    @Resource(name = "masterStringRedisTemplate")
    private StringRedisTemplate masterStringRedisTemplate;
    @Resource(name = "replicaStringRedisTemplate")
    private StringRedisTemplate replicaStringRedisTemplate;

    @GetMapping("/test")
    public String test() {
        
        masterStringRedisTemplate.opsForValue().set("imu:test", "Hello6");

        String value = replicaStringRedisTemplate.opsForValue().get("imu:test");
        return value;
    }

LettuceConnectionFactory.setShareNativeConnection 方法的作用

代碼中這一行被注釋,保持了原本的默認(rèn)配置true

// 禁用共享連接 默認(rèn)是true
// factory.setShareNativeConnection(false);

在 Spring Data Redis 中,LettuceConnectionFactory 是一個(gè)用于管理 Redis 連接的工廠類,而 setShareNativeConnection(boolean shareNativeConnection) 方法用于控制是否 共享底層的 Redis 連接。

true(默認(rèn)):

  • 適用于 大多數(shù)應(yīng)用,多個(gè) Redis 操作共享同一個(gè)底層連接,減少資源占用。
  • 適用于 Spring Boot + RedisTemplate 場景。

false:

  • 適用于 高并發(fā)、多線程環(huán)境,避免多個(gè)線程爭搶同一個(gè) Redis 連接。
  • 適用于 WebFlux、Reactive、Pipeline 等場景。

一般來說,除非你的 Redis 操作出現(xiàn) 多線程連接爭用問題,否則 不用手動(dòng)修改 setShareNativeConnection,保持默認(rèn)值即可!??

而:

  • shareNativeConnection = true
  • (默認(rèn))時(shí),Spring 只會(huì)創(chuàng)建 一個(gè)共享的 StatefulRedisConnection,那么 連接池的 max-active、max-idle、min-idle 這些配置不會(huì)生效。
  • shareNativeConnection = false 時(shí),每次請(qǐng)求都會(huì)新建連接,這時(shí)連接池才會(huì)管理多個(gè)連接,此時(shí) max-active 等參數(shù)才會(huì)起作用。
  • 也就是說我們在yml配置文件中配置的連接池信息都將不起作用
    jedis:
      # Redis服務(wù)器連接池
      pool:
        # 連接池最大連接數(shù)(使用負(fù)值表示沒有限制)
        maxIdle: 400
        #連接池中的最小空閑連接
        minIdle: 100
        #連接池中的最大空閑連接
        maxActive: 400
        # 連接池最大阻塞等待時(shí)間(使用負(fù)值表示沒有限制)
        maxWait: -1ms
    lettuce:
      pool:
        max-idle: 400
        min-idle: 100
        max-active: 400
        max-wait: -1ms

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • SpringCloud?Nacos服務(wù)分級(jí)存儲(chǔ)模型詳解

    SpringCloud?Nacos服務(wù)分級(jí)存儲(chǔ)模型詳解

    Nacos服務(wù)分級(jí)存儲(chǔ)模型是Nacos存儲(chǔ)服務(wù)注冊信息和配置信息的核心模型之一,本文將對(duì)?Nacos?服務(wù)分級(jí)存儲(chǔ)模型進(jìn)行深入解析,感興趣的朋友一起看看吧
    2024-02-02
  • Tomcat版本與Java版本的關(guān)系及說明

    Tomcat版本與Java版本的關(guān)系及說明

    這篇文章主要介紹了Tomcat版本與Java版本的關(guān)系及說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2025-04-04
  • 基于java構(gòu)造方法Vector查找元素源碼分析

    基于java構(gòu)造方法Vector查找元素源碼分析

    本篇文章是關(guān)于ava構(gòu)造方法Vector源碼分析系列文章,本文主要介紹了Vector查找元素的源碼分析,有需要的朋友可以借鑒參考下,希望可以有所幫助
    2021-09-09
  • mybatis初始化SqlSessionFactory失敗的幾個(gè)原因分析

    mybatis初始化SqlSessionFactory失敗的幾個(gè)原因分析

    這篇文章主要介紹了mybatis初始化SqlSessionFactory失敗的幾個(gè)原因分析,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • Guava中這些Map技巧可以讓代碼量減少了50%

    Guava中這些Map技巧可以讓代碼量減少了50%

    guava提供了非常強(qiáng)大的操作,可以讓我們把java代碼寫的很簡潔,下面這篇文章主要給大家介紹了關(guān)于Guava中這些Map使用技巧可以讓代碼量減少了50%的相關(guān)資料,需要的朋友可以參考下
    2022-11-11
  • 3分鐘快速搞懂Java的橋接方法示例

    3分鐘快速搞懂Java的橋接方法示例

    這篇文章主要介紹了3分鐘快速搞懂Java的橋接方法示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-02-02
  • springboot植入pagerHelper的超詳細(xì)教程

    springboot植入pagerHelper的超詳細(xì)教程

    這篇文章主要介紹了springboot植入pagerHelper的超詳細(xì)教程,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-01-01
  • SpringBoot+MyBatis-Plus+Dynamic-Datasource讀寫分離完整指南

    SpringBoot+MyBatis-Plus+Dynamic-Datasource讀寫分離完整指南

    在SpringBoot項(xiàng)目中,使用MyBatis-Plus和Dynamic-Datasource實(shí)現(xiàn)讀寫分離是一種常見且高效的架構(gòu)選擇,下面就來詳細(xì)介紹一下SpringBoot讀寫分離,感興趣的可以了解一下
    2025-11-11
  • SpringBoot整合消息隊(duì)列RabbitMQ

    SpringBoot整合消息隊(duì)列RabbitMQ

    SpringBoot整合RabbitMQ很容易,但是整合的目的是為了使用,那要使用RabbitMQ就要對(duì)其有一定的了解,不然容易整成一團(tuán)漿糊。因?yàn)檎f到底,SpringBoot只是在封裝RabbitMQ的API,讓其更容易使用而已,廢話不多說,讓我們一起整它
    2023-03-03
  • SpringBoot全局配置long轉(zhuǎn)String丟失精度問題解決方案

    SpringBoot全局配置long轉(zhuǎn)String丟失精度問題解決方案

    這篇文章主要介紹了SpringBoot全局配置long轉(zhuǎn)String丟失精度問題解決方案,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-08-08

最新評(píng)論

运城市| 常宁市| 大洼县| 四子王旗| 屏南县| 新民市| 河间市| 胶州市| 湄潭县| 桐庐县| 桐庐县| 崇明县| 张北县| 武鸣县| 九龙城区| 台东市| 临桂县| 西青区| 竹溪县| 射洪县| 仁寿县| 玉田县| 肇庆市| 乡城县| 东兴市| 岳池县| 三原县| 鹿泉市| 昭平县| 墨江| 哈密市| 高邑县| 尤溪县| 财经| 安庆市| 漯河市| 嘉鱼县| 孟津县| 营口市| 漳平市| 百色市|