Skip to content

Commit 4f9770f

Browse files
Merge pull request #12 from guoshiqiufeng/dev
0.5.0
2 parents fa7977e + cc98856 commit 4f9770f

File tree

12 files changed

+170
-20
lines changed

12 files changed

+170
-20
lines changed

README-zh.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ https://guoshiqiufeng.github.io/spring-cloud-stream-redis/
3939
<dependency>
4040
<groupId>io.github.guoshiqiufeng.cloud</groupId>
4141
<artifactId>spring-cloud-stream-dependencies</artifactId>
42-
<version>0.4.0</version>
42+
<version>0.5.0</version>
4343
<type>import</type>
4444
</dependency>
4545
</dependencies>

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ https://guoshiqiufeng.github.io/spring-cloud-stream-redis/en/
4141
<dependency>
4242
<groupId>io.github.guoshiqiufeng.cloud</groupId>
4343
<artifactId>spring-cloud-stream-dependencies</artifactId>
44-
<version>0.4.0</version>
44+
<version>0.5.0</version>
4545
<type>import</type>
4646
</dependency>
4747
</dependencies>

binders/spring-cloud-stream-binder-redis-core/src/main/java/io/github/guoshiqiufeng/cloud/stream/binder/redis/support/converter/MessagingMessageConverter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
*/
1616
package io.github.guoshiqiufeng.cloud.stream.binder.redis.support.converter;
1717

18-
import org.jetbrains.annotations.NotNull;
18+
import jakarta.validation.constraints.NotNull;
1919
import org.springframework.data.redis.serializer.RedisSerializer;
2020
import org.springframework.messaging.Message;
2121
import org.springframework.messaging.MessageHeaders;

binders/spring-cloud-stream-binder-redis-core/src/main/java/io/github/guoshiqiufeng/cloud/stream/binder/redis/utils/RedisConnectionFactoryUtil.java

Lines changed: 56 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@
1515
*/
1616
package io.github.guoshiqiufeng.cloud.stream.binder.redis.utils;
1717

18+
import io.lettuce.core.RedisConnectionException;
1819
import lombok.experimental.UtilityClass;
20+
import lombok.extern.slf4j.Slf4j;
1921
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
2022
import org.springframework.beans.BeanUtils;
2123
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
@@ -35,9 +37,13 @@
3537
* @version 1.0
3638
* @since 2024/8/28 15:52
3739
*/
40+
@Slf4j
3841
@UtilityClass
3942
public class RedisConnectionFactoryUtil {
4043

44+
private static final int MAX_RETRY_ATTEMPTS = 3;
45+
private static final long RETRY_DELAY_MS = 1000;
46+
4147
/**
4248
* get the RedisConnectionFactory
4349
*
@@ -47,21 +53,61 @@ public class RedisConnectionFactoryUtil {
4753
public RedisConnectionFactory getRedisConnectionFactory(@NonNull RedisProperties redisProperties) {
4854
Assert.notNull(redisProperties,
4955
"'properties' must not be null");
56+
// add retry
57+
int attempts = 0;
58+
Exception lastException = null;
59+
60+
while (attempts < MAX_RETRY_ATTEMPTS) {
61+
try {
62+
return createConnectionFactory(redisProperties);
63+
} catch (Exception e) {
64+
lastException = e;
65+
log.warn("Failed to create Redis connection factory, attempt {}/{}",
66+
attempts + 1, MAX_RETRY_ATTEMPTS, e);
67+
68+
attempts++;
69+
if (attempts < MAX_RETRY_ATTEMPTS) {
70+
try {
71+
Thread.sleep(RETRY_DELAY_MS);
72+
} catch (InterruptedException ie) {
73+
Thread.currentThread().interrupt();
74+
throw new RedisConnectionException("Connection attempt interrupted", ie);
75+
}
76+
}
77+
}
78+
}
79+
80+
throw new RedisConnectionException("Failed to create Redis connection after " +
81+
MAX_RETRY_ATTEMPTS + " attempts", lastException);
82+
}
83+
84+
private RedisConnectionFactory createConnectionFactory(RedisProperties redisProperties) {
5085
RedisProperties.ClientType clientType = redisProperties.getClientType();
5186

52-
if (clientType == RedisProperties.ClientType.JEDIS) {
53-
// 使用 Jedis 作为 Redis 客户端
54-
JedisConnectionFactory jedisConnectionFactory = configureJedisClient(redisProperties);
55-
jedisConnectionFactory.start();
56-
return jedisConnectionFactory;
57-
} else {
58-
// 使用 Lettuce 作为 Redis 客户端
59-
LettuceConnectionFactory lettuceConnectionFactory = configureLettuceClient(redisProperties);
60-
lettuceConnectionFactory.start();
61-
return lettuceConnectionFactory;
87+
try {
88+
if (clientType == RedisProperties.ClientType.JEDIS) {
89+
// use jedis client
90+
JedisConnectionFactory factory = configureJedisClient(redisProperties);
91+
factory.afterPropertiesSet();
92+
validateConnection(factory);
93+
return factory;
94+
} else {
95+
// use lettuce client
96+
LettuceConnectionFactory factory = configureLettuceClient(redisProperties);
97+
factory.afterPropertiesSet();
98+
validateConnection(factory);
99+
return factory;
100+
}
101+
} catch (Exception e) {
102+
throw new RedisConnectionException("Error creating Redis connection factory", e);
62103
}
63104
}
64105

106+
private void validateConnection(RedisConnectionFactory factory) {
107+
try (RedisConnection connection = factory.getConnection()) {
108+
connection.ping();
109+
}
110+
}
65111

66112
private JedisConnectionFactory configureJedisClient(RedisProperties redisProperties) {
67113
JedisClientConfiguration clientConfiguration = JedisClientConfiguration.builder()

binders/spring-cloud-stream-binder-redis/build.gradle

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ dependencies {
55
annotationProcessor "org.springframework.boot:spring-boot-configuration-processor"
66
annotationProcessor "org.springframework.boot:spring-boot-autoconfigure"
77

8+
implementation 'io.lettuce:lettuce-core'
9+
implementation 'redis.clients:jedis'
10+
811
testImplementation 'io.lettuce:lettuce-core'
912
testImplementation 'redis.clients:jedis'
1013
testImplementation "org.springframework.boot:spring-boot-starter-test"

binders/spring-cloud-stream-binder-redis/src/main/java/io/github/guoshiqiufeng/cloud/stream/binder/redis/health/RedisBinderHealthIndicator.java

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,15 @@
1515
*/
1616
package io.github.guoshiqiufeng.cloud.stream.binder.redis.health;
1717

18+
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
1819
import org.springframework.boot.actuate.data.redis.RedisHealthIndicator;
20+
import org.springframework.boot.actuate.health.Health;
1921
import org.springframework.data.redis.connection.RedisConnectionFactory;
22+
import org.springframework.data.redis.connection.jedis.JedisClientConfiguration;
23+
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
24+
import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration;
25+
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
26+
import org.springframework.data.redis.connection.lettuce.LettucePoolingClientConfiguration;
2027

2128
/**
2229
* Health indicator for Redis binder.
@@ -27,7 +34,45 @@
2734
*/
2835
public class RedisBinderHealthIndicator extends RedisHealthIndicator {
2936

37+
private final RedisConnectionFactory connectionFactory;
38+
3039
public RedisBinderHealthIndicator(RedisConnectionFactory connectionFactory) {
3140
super(connectionFactory);
41+
this.connectionFactory = connectionFactory;
42+
}
43+
44+
@Override
45+
protected void doHealthCheck(Health.Builder builder) throws Exception {
46+
try {
47+
// 基础连接检查
48+
super.doHealthCheck(builder);
49+
50+
// 连接池状态检查
51+
checkConnectionPoolStatus(builder);
52+
53+
} catch (Exception e) {
54+
builder.down().withException(e);
55+
}
56+
}
57+
58+
private void checkConnectionPoolStatus(Health.Builder builder) {
59+
if (connectionFactory instanceof LettuceConnectionFactory lettuceFactory) {
60+
LettuceClientConfiguration clientConfiguration = lettuceFactory.getClientConfiguration();
61+
if (clientConfiguration instanceof LettucePoolingClientConfiguration poolConfig) {
62+
GenericObjectPoolConfig<?> pool = poolConfig.getPoolConfig();
63+
builder.withDetail("pool.maxTotal", pool.getMaxTotal())
64+
.withDetail("pool.maxIdle", pool.getMaxIdle())
65+
.withDetail("pool.minIdle", pool.getMinIdle());
66+
} else {
67+
builder.withDetail("pool", "Lettuce connection pool is not configured.");
68+
}
69+
} else if (connectionFactory instanceof JedisConnectionFactory jedisFactory) {
70+
JedisClientConfiguration clientConfiguration = jedisFactory.getClientConfiguration();
71+
clientConfiguration.getPoolConfig().ifPresent(pool -> {
72+
builder.withDetail("pool.maxTotal", pool.getMaxTotal())
73+
.withDetail("pool.maxIdle", pool.getMaxIdle())
74+
.withDetail("pool.minIdle", pool.getMinIdle());
75+
});
76+
}
3277
}
3378
}

docs/en/guide/actuator.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,10 @@ Example:
4242
"redis": {
4343
"status": "UP",
4444
"details": {
45-
"version": "7.1.2"
45+
"version": "7.1.2",
46+
"pool.maxTotal": 8,
47+
"pool.maxIdle": 8,
48+
"pool.minIdle": 0
4649
}
4750
}
4851
}
@@ -52,4 +55,4 @@ Example:
5255
}
5356
}
5457
}
55-
```
58+
```

docs/en/guide/config.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,31 @@ spring:
5555
The default is to use the `lettuce` client, if you need to switch to the jedis client, you can add a jedis dependency to
5656
do so, with the same configuration parameters as spring-boot-starter-data-redis.
5757

58+
- jedis dependencies
59+
<CodeGroup>
60+
<CodeGroupItem title="Maven" active>
61+
62+
```xml:no-line-numbers:no-v-pre
63+
<dependency>
64+
<groupId>redis.clients</groupId>
65+
<artifactId>jedis</artifactId>
66+
</dependency>
67+
```
68+
69+
</CodeGroupItem>
70+
71+
<CodeGroupItem title="Gradle">
72+
73+
```groovy:no-line-numbers:no-v-pre
74+
dependencies {
75+
implementation platform("redis.clients:jedis")
76+
}
77+
```
78+
79+
</CodeGroupItem>
80+
</CodeGroup>
81+
82+
- configuration
5883
```yaml:no-line-numbers
5984
spring:
6085
cloud:

docs/guide/actuator.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,10 @@ management:
4242
"redis": {
4343
"status": "UP",
4444
"details": {
45-
"version": "7.1.2"
45+
"version": "7.1.2",
46+
"pool.maxTotal": 8,
47+
"pool.maxIdle": 8,
48+
"pool.minIdle": 0
4649
}
4750
}
4851
}
@@ -52,4 +55,4 @@ management:
5255
}
5356
}
5457
}
55-
```
58+
```

docs/guide/config.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,31 @@ spring:
5454

5555
默认与 使用`lettuce`客户端,如需切换 jedis 客户端,可以添加 jedis 依赖 即可,配置参数与 spring-boot-starter-data-redis 一致。
5656

57+
- jedis依赖
58+
<CodeGroup>
59+
<CodeGroupItem title="Maven" active>
60+
61+
```xml:no-line-numbers:no-v-pre
62+
<dependency>
63+
<groupId>redis.clients</groupId>
64+
<artifactId>jedis</artifactId>
65+
</dependency>
66+
```
67+
68+
</CodeGroupItem>
69+
70+
<CodeGroupItem title="Gradle">
71+
72+
```groovy:no-line-numbers:no-v-pre
73+
dependencies {
74+
implementation platform("redis.clients:jedis")
75+
}
76+
```
77+
78+
</CodeGroupItem>
79+
</CodeGroup>
80+
81+
- 配置
5782
```yaml:no-line-numbers
5883
spring:
5984
cloud:

0 commit comments

Comments
 (0)