Sfoglia il codice sorgente

仅当配置了 spring.redis.sentinel.master 时生效;未配 Sentinel 时仍走自动配置。

dujian 1 mese fa
parent
commit
8c193081fd

+ 114 - 114
alien-store/src/main/java/shop/alien/store/config/RedisLettuceConfig.java

@@ -1,114 +1,114 @@
-package shop.alien.store.config;
-
-import io.lettuce.core.RedisURI;
-import io.lettuce.core.sentinel.api.sync.RedisSentinelCommands;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.boot.autoconfigure.AutoConfigureBefore;
-import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
-import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.Primary;
-import org.springframework.data.redis.connection.RedisPassword;
-import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
-import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration;
-import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
-import org.springframework.util.StringUtils;
-
-import java.util.List;
-import java.util.Map;
-
-/**
- * 使用 Sentinel 时:启动阶段向 Sentinel 查询当前 Master 地址,并只建立到该 Master 的独立连接(单节点)。
- * 不建 MasterReplica 拓扑,从根源上避免请求被路由到只读副本导致 READONLY。
- * 仅当配置了 spring.redis.sentinel.master 时生效;未配 Sentinel 时仍走自动配置。
- */
-@Slf4j
-@Configuration
-@AutoConfigureBefore(RedisAutoConfiguration.class)
-public class RedisLettuceConfig {
-
-    @Bean
-    @Primary
-    @ConditionalOnProperty(
-            prefix = "spring.redis.sentinel",
-            name = "master",
-            matchIfMissing = false)
-    public LettuceConnectionFactory redisConnectionFactory(
-            RedisProperties properties,
-            @Value("${spring.redis.master-port:#{null}}") Integer masterPortOverride) {
-        log.info("RedisLettuceConfig: 使用 Sentinel 解析 Master 并创建仅连 Master 的 Redis 连接(避免 READONLY)");
-        RedisProperties.Sentinel sentinel = properties.getSentinel();
-        String masterName = sentinel.getMaster();
-        String[] firstSentinel = parseFirstSentinelNode(sentinel.getNodes());
-        if (firstSentinel == null) {
-            throw new IllegalStateException("spring.redis.sentinel.nodes 未配置或格式错误");
-        }
-        String sentinelHost = firstSentinel[0];
-        int sentinelPort = Integer.parseInt(firstSentinel[1]);
-
-        // 向 Sentinel 查询当前 Master 地址
-        String masterHost;
-        int masterPort;
-        io.lettuce.core.RedisClient probeClient = null;
-        try {
-            probeClient = io.lettuce.core.RedisClient.create(
-                    RedisURI.create("redis://" + sentinelHost + ":" + sentinelPort));
-            try (io.lettuce.core.sentinel.api.StatefulRedisSentinelConnection<String, String> probeConn =
-                    probeClient.connectSentinel()) {
-                RedisSentinelCommands<String, String> sync = probeConn.sync();
-                Map<String, String> master = sync.master(masterName);
-                if (master == null || !master.containsKey("ip") || !master.containsKey("port")) {
-                    throw new IllegalStateException("Sentinel 未返回 master 地址: " + masterName);
-                }
-                masterHost = master.get("ip");
-                masterPort = Integer.parseInt(master.get("port"));
-                // 若配置了 spring.redis.master-port(如宿主机映射 30012),用其覆盖 Sentinel 返回的端口
-                if (masterPortOverride != null) {
-                    masterPort = masterPortOverride;
-                }
-                log.info("Redis Sentinel 当前 Master: {}:{} (masterName={})", masterHost, masterPort, masterName);
-            }
-        } finally {
-            if (probeClient != null) {
-                probeClient.shutdown();
-            }
-        }
-
-        // 仅连接该 Master 单节点,不建 MasterReplica,避免请求打到副本
-        RedisStandaloneConfiguration standaloneConfig = new RedisStandaloneConfiguration(masterHost, masterPort);
-        standaloneConfig.setDatabase(properties.getDatabase());
-        if (StringUtils.hasText(properties.getPassword())) {
-            standaloneConfig.setPassword(RedisPassword.of(properties.getPassword()));
-        }
-
-        LettuceClientConfiguration.LettuceClientConfigurationBuilder builder = LettuceClientConfiguration.builder();
-        if (properties.getTimeout() != null) {
-            builder.commandTimeout(properties.getTimeout());
-        }
-        LettuceClientConfiguration clientConfig = builder.build();
-
-        LettuceConnectionFactory factory = new LettuceConnectionFactory(standaloneConfig, clientConfig);
-        return factory;
-    }
-
-    private static String[] parseFirstSentinelNode(List<String> nodes) {
-        if (nodes == null || nodes.isEmpty()) {
-            return null;
-        }
-        for (String node : nodes) {
-            for (String one : node.split(",")) {
-                String hostPort = one.trim();
-                if (!hostPort.isEmpty()) {
-                    String[] parts = hostPort.split(":");
-                    String host = parts[0].trim();
-                    String port = parts.length > 1 ? parts[1].trim() : "26379";
-                    return new String[]{host, port};
-                }
-            }
-        }
-        return null;
-    }
-}
+//package shop.alien.store.config;
+//
+//import io.lettuce.core.RedisURI;
+//import io.lettuce.core.sentinel.api.sync.RedisSentinelCommands;
+//import lombok.extern.slf4j.Slf4j;
+//import org.springframework.boot.autoconfigure.AutoConfigureBefore;
+//import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
+//import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
+//import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+//import org.springframework.beans.factory.annotation.Value;
+//import org.springframework.context.annotation.Bean;
+//import org.springframework.context.annotation.Configuration;
+//import org.springframework.context.annotation.Primary;
+//import org.springframework.data.redis.connection.RedisPassword;
+//import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
+//import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration;
+//import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
+//import org.springframework.util.StringUtils;
+//
+//import java.util.List;
+//import java.util.Map;
+//
+///**
+// * 使用 Sentinel 时:启动阶段向 Sentinel 查询当前 Master 地址,并只建立到该 Master 的独立连接(单节点)。
+// * 不建 MasterReplica 拓扑,从根源上避免请求被路由到只读副本导致 READONLY。
+// * 仅当配置了 spring.redis.sentinel.master 时生效;未配 Sentinel 时仍走自动配置。
+// */
+//@Slf4j
+//@Configuration
+//@AutoConfigureBefore(RedisAutoConfiguration.class)
+//public class RedisLettuceConfig {
+//
+//    @Bean
+//    @Primary
+//    @ConditionalOnProperty(
+//            prefix = "spring.redis.sentinel",
+//            name = "master",
+//            matchIfMissing = false)
+//    public LettuceConnectionFactory redisConnectionFactory(
+//            RedisProperties properties,
+//            @Value("${spring.redis.master-port:#{null}}") Integer masterPortOverride) {
+//        log.info("RedisLettuceConfig: 使用 Sentinel 解析 Master 并创建仅连 Master 的 Redis 连接(避免 READONLY)");
+//        RedisProperties.Sentinel sentinel = properties.getSentinel();
+//        String masterName = sentinel.getMaster();
+//        String[] firstSentinel = parseFirstSentinelNode(sentinel.getNodes());
+//        if (firstSentinel == null) {
+//            throw new IllegalStateException("spring.redis.sentinel.nodes 未配置或格式错误");
+//        }
+//        String sentinelHost = firstSentinel[0];
+//        int sentinelPort = Integer.parseInt(firstSentinel[1]);
+//
+//        // 向 Sentinel 查询当前 Master 地址
+//        String masterHost;
+//        int masterPort;
+//        io.lettuce.core.RedisClient probeClient = null;
+//        try {
+//            probeClient = io.lettuce.core.RedisClient.create(
+//                    RedisURI.create("redis://" + sentinelHost + ":" + sentinelPort));
+//            try (io.lettuce.core.sentinel.api.StatefulRedisSentinelConnection<String, String> probeConn =
+//                    probeClient.connectSentinel()) {
+//                RedisSentinelCommands<String, String> sync = probeConn.sync();
+//                Map<String, String> master = sync.master(masterName);
+//                if (master == null || !master.containsKey("ip") || !master.containsKey("port")) {
+//                    throw new IllegalStateException("Sentinel 未返回 master 地址: " + masterName);
+//                }
+//                masterHost = master.get("ip");
+//                masterPort = Integer.parseInt(master.get("port"));
+//                // 若配置了 spring.redis.master-port(如宿主机映射 30012),用其覆盖 Sentinel 返回的端口
+//                if (masterPortOverride != null) {
+//                    masterPort = masterPortOverride;
+//                }
+//                log.info("Redis Sentinel 当前 Master: {}:{} (masterName={})", masterHost, masterPort, masterName);
+//            }
+//        } finally {
+//            if (probeClient != null) {
+//                probeClient.shutdown();
+//            }
+//        }
+//
+//        // 仅连接该 Master 单节点,不建 MasterReplica,避免请求打到副本
+//        RedisStandaloneConfiguration standaloneConfig = new RedisStandaloneConfiguration(masterHost, masterPort);
+//        standaloneConfig.setDatabase(properties.getDatabase());
+//        if (StringUtils.hasText(properties.getPassword())) {
+//            standaloneConfig.setPassword(RedisPassword.of(properties.getPassword()));
+//        }
+//
+//        LettuceClientConfiguration.LettuceClientConfigurationBuilder builder = LettuceClientConfiguration.builder();
+//        if (properties.getTimeout() != null) {
+//            builder.commandTimeout(properties.getTimeout());
+//        }
+//        LettuceClientConfiguration clientConfig = builder.build();
+//
+//        LettuceConnectionFactory factory = new LettuceConnectionFactory(standaloneConfig, clientConfig);
+//        return factory;
+//    }
+//
+//    private static String[] parseFirstSentinelNode(List<String> nodes) {
+//        if (nodes == null || nodes.isEmpty()) {
+//            return null;
+//        }
+//        for (String node : nodes) {
+//            for (String one : node.split(",")) {
+//                String hostPort = one.trim();
+//                if (!hostPort.isEmpty()) {
+//                    String[] parts = hostPort.split(":");
+//                    String host = parts[0].trim();
+//                    String port = parts.length > 1 ? parts[1].trim() : "26379";
+//                    return new String[]{host, port};
+//                }
+//            }
+//        }
+//        return null;
+//    }
+//}