mirror of
http://git.pig4cloud.com/pig/pigx.git
synced 2026-11-08 04:39:00 +08:00
feat(idempotent): 增强幂等配置,支持 Redis 集群和哨兵模式
- 新增对 Redis 集群和哨兵模式的支持 - 更新 Redisson 客户端配置逻辑 - 添加 IdempotentAutoConfigurationTests 测试类,验证新配置的正确性 (cherry picked from commit b836af6dc0dfbe17b20740cfda9e417deae1967d)
This commit is contained in:
1 parent
c80d5bc44a
commit
39ea9a6eae
2 files changed
+130
-12
No files matched your search
+39
-12
@@ -5,8 +5,10 @@ import com.pig4cloud.pigx.common.idempotent.expression.ExpressionResolver;
|
||||
import com.pig4cloud.pigx.common.idempotent.expression.KeyResolver;
|
||||
import org.redisson.Redisson;
|
||||
import org.redisson.api.RedissonClient;
|
||||
import org.redisson.config.BaseConfig;
|
||||
import org.redisson.config.ClusterServersConfig;
|
||||
import org.redisson.config.Config;
|
||||
import org.redisson.config.SingleServerConfig;
|
||||
import org.redisson.config.SentinelServersConfig;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
@@ -40,31 +42,56 @@ public class IdempotentAutoConfiguration {
|
||||
}
|
||||
|
||||
/**
|
||||
* 幂等方面
|
||||
* 幂等 Redis 客户端
|
||||
*
|
||||
* @param redisson redisson 客户端
|
||||
* @param keyResolver KEY解析器
|
||||
* @return {@link IdempotentAspect }
|
||||
* @param redisProperties Redis 连接配置
|
||||
* @return Redisson 客户端
|
||||
*/
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(RedissonClient.class)
|
||||
public RedissonClient redissonClient(DataRedisProperties redisProperties) {
|
||||
Config config = new Config();
|
||||
SingleServerConfig singleServerConfig = config.useSingleServer()
|
||||
.setAddress("redis://" + redisProperties.getHost() + ":" + redisProperties.getPort())
|
||||
.setDatabase(redisProperties.getDatabase());
|
||||
BaseConfig<?> serverConfig;
|
||||
if (redisProperties.getSentinel() != null) {
|
||||
DataRedisProperties.Sentinel sentinel = redisProperties.getSentinel();
|
||||
SentinelServersConfig sentinelConfig = config.useSentinelServers()
|
||||
.setMasterName(sentinel.getMaster())
|
||||
.setDatabase(redisProperties.getDatabase());
|
||||
for (String node : sentinel.getNodes()) {
|
||||
sentinelConfig.addSentinelAddress("redis://" + node);
|
||||
}
|
||||
if (StringUtils.hasText(sentinel.getUsername())) {
|
||||
sentinelConfig.setSentinelUsername(sentinel.getUsername());
|
||||
}
|
||||
if (StringUtils.hasText(sentinel.getPassword())) {
|
||||
sentinelConfig.setSentinelPassword(sentinel.getPassword());
|
||||
}
|
||||
serverConfig = sentinelConfig;
|
||||
}
|
||||
else if (redisProperties.getCluster() != null) {
|
||||
ClusterServersConfig clusterConfig = config.useClusterServers();
|
||||
for (String node : redisProperties.getCluster().getNodes()) {
|
||||
clusterConfig.addNodeAddress("redis://" + node);
|
||||
}
|
||||
serverConfig = clusterConfig;
|
||||
}
|
||||
else {
|
||||
serverConfig = config.useSingleServer()
|
||||
.setAddress("redis://" + redisProperties.getHost() + ":" + redisProperties.getPort())
|
||||
.setDatabase(redisProperties.getDatabase());
|
||||
}
|
||||
|
||||
if (StringUtils.hasText(redisProperties.getUsername())) {
|
||||
singleServerConfig.setUsername(redisProperties.getUsername());
|
||||
serverConfig.setUsername(redisProperties.getUsername());
|
||||
}
|
||||
if (StringUtils.hasText(redisProperties.getPassword())) {
|
||||
singleServerConfig.setPassword(redisProperties.getPassword());
|
||||
serverConfig.setPassword(redisProperties.getPassword());
|
||||
}
|
||||
if (redisProperties.getConnectTimeout() != null) {
|
||||
singleServerConfig.setConnectTimeout((int) redisProperties.getConnectTimeout().toMillis());
|
||||
serverConfig.setConnectTimeout((int) redisProperties.getConnectTimeout().toMillis());
|
||||
}
|
||||
if (redisProperties.getTimeout() != null) {
|
||||
singleServerConfig.setTimeout((int) redisProperties.getTimeout().toMillis());
|
||||
serverConfig.setTimeout((int) redisProperties.getTimeout().toMillis());
|
||||
}
|
||||
|
||||
return Redisson.create(config);
|
||||
|
||||
+91
@@ -0,0 +1,91 @@
|
||||
package com.pig4cloud.pigx.common.idempotent;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.MockedStatic;
|
||||
import org.redisson.Redisson;
|
||||
import org.redisson.api.RedissonClient;
|
||||
import org.redisson.config.ClusterServersConfig;
|
||||
import org.redisson.config.Config;
|
||||
import org.redisson.config.SentinelServersConfig;
|
||||
import org.springframework.boot.data.redis.autoconfigure.DataRedisProperties;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.mockStatic;
|
||||
import static org.mockito.Mockito.withSettings;
|
||||
|
||||
class IdempotentAutoConfigurationTests {
|
||||
|
||||
@Test
|
||||
void usesClusterNodesInsteadOfDefaultSingleServer() {
|
||||
DataRedisProperties properties = new DataRedisProperties();
|
||||
properties.setUsername("cluster-user");
|
||||
properties.setPassword("cluster-password");
|
||||
properties.setConnectTimeout(Duration.ofSeconds(2));
|
||||
properties.setTimeout(Duration.ofSeconds(3));
|
||||
DataRedisProperties.Cluster cluster = new DataRedisProperties.Cluster();
|
||||
cluster.setNodes(List.of("redis-1:7000", "redis-2:7001", "redis-3:7002"));
|
||||
properties.setCluster(cluster);
|
||||
|
||||
RedissonClient client = mock(RedissonClient.class);
|
||||
try (MockedStatic<Redisson> redisson = mockStatic(Redisson.class,
|
||||
withSettings().mockMaker("mock-maker-inline"))) {
|
||||
redisson.when(() -> Redisson.create(any(Config.class))).thenAnswer(invocation -> {
|
||||
Config config = invocation.getArgument(0);
|
||||
assertThat(config.isClusterConfig()).as("必须使用集群模式连接").isTrue();
|
||||
ClusterServersConfig servers = config.useClusterServers();
|
||||
assertThat(servers.getNodeAddresses()).containsExactly(
|
||||
"redis://redis-1:7000", "redis://redis-2:7001", "redis://redis-3:7002");
|
||||
assertThat(servers.getUsername()).isEqualTo("cluster-user");
|
||||
assertThat(servers.getPassword()).isEqualTo("cluster-password");
|
||||
assertThat(servers.getConnectTimeout()).isEqualTo(2000);
|
||||
assertThat(servers.getTimeout()).isEqualTo(3000);
|
||||
return client;
|
||||
});
|
||||
assertThat(new IdempotentAutoConfiguration().redissonClient(properties)).isSameAs(client);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void usesSentinelConfigurationInsteadOfDefaultSingleServer() {
|
||||
DataRedisProperties properties = new DataRedisProperties();
|
||||
properties.setDatabase(2);
|
||||
properties.setUsername("data-user");
|
||||
properties.setPassword("data-password");
|
||||
properties.setConnectTimeout(Duration.ofSeconds(2));
|
||||
properties.setTimeout(Duration.ofSeconds(3));
|
||||
DataRedisProperties.Sentinel sentinel = new DataRedisProperties.Sentinel();
|
||||
sentinel.setMaster("mymaster");
|
||||
sentinel.setNodes(List.of("sentinel-1:26379", "sentinel-2:26379"));
|
||||
sentinel.setUsername("sentinel-user");
|
||||
sentinel.setPassword("sentinel-password");
|
||||
properties.setSentinel(sentinel);
|
||||
|
||||
RedissonClient client = mock(RedissonClient.class);
|
||||
try (MockedStatic<Redisson> redisson = mockStatic(Redisson.class,
|
||||
withSettings().mockMaker("mock-maker-inline"))) {
|
||||
redisson.when(() -> Redisson.create(any(Config.class))).thenAnswer(invocation -> {
|
||||
Config config = invocation.getArgument(0);
|
||||
assertThat(config.isSentinelConfig()).as("必须使用哨兵模式连接").isTrue();
|
||||
SentinelServersConfig servers = config.useSentinelServers();
|
||||
assertThat(servers.getMasterName()).isEqualTo("mymaster");
|
||||
assertThat(servers.getSentinelAddresses())
|
||||
.containsExactly("redis://sentinel-1:26379", "redis://sentinel-2:26379");
|
||||
assertThat(servers.getSentinelUsername()).isEqualTo("sentinel-user");
|
||||
assertThat(servers.getSentinelPassword()).isEqualTo("sentinel-password");
|
||||
assertThat(servers.getUsername()).isEqualTo("data-user");
|
||||
assertThat(servers.getPassword()).isEqualTo("data-password");
|
||||
assertThat(servers.getDatabase()).isEqualTo(2);
|
||||
assertThat(servers.getConnectTimeout()).isEqualTo(2000);
|
||||
assertThat(servers.getTimeout()).isEqualTo(3000);
|
||||
return client;
|
||||
});
|
||||
assertThat(new IdempotentAutoConfiguration().redissonClient(properties)).isSameAs(client);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in new issue
Block a user