Skip to content

Commit

Permalink
Merge pull request #12 from guoshiqiufeng/dev
Browse files Browse the repository at this point in the history
0.5.0
  • Loading branch information
guoshiqiufeng authored Dec 31, 2024
2 parents fa7977e + cc98856 commit 4f9770f
Show file tree
Hide file tree
Showing 12 changed files with 170 additions and 20 deletions.
2 changes: 1 addition & 1 deletion README-zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ https://guoshiqiufeng.github.io/spring-cloud-stream-redis/
<dependency>
<groupId>io.github.guoshiqiufeng.cloud</groupId>
<artifactId>spring-cloud-stream-dependencies</artifactId>
<version>0.4.0</version>
<version>0.5.0</version>
<type>import</type>
</dependency>
</dependencies>
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ https://guoshiqiufeng.github.io/spring-cloud-stream-redis/en/
<dependency>
<groupId>io.github.guoshiqiufeng.cloud</groupId>
<artifactId>spring-cloud-stream-dependencies</artifactId>
<version>0.4.0</version>
<version>0.5.0</version>
<type>import</type>
</dependency>
</dependencies>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*/
package io.github.guoshiqiufeng.cloud.stream.binder.redis.support.converter;

import org.jetbrains.annotations.NotNull;
import jakarta.validation.constraints.NotNull;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHeaders;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
*/
package io.github.guoshiqiufeng.cloud.stream.binder.redis.utils;

import io.lettuce.core.RedisConnectionException;
import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.beans.BeanUtils;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
Expand All @@ -35,9 +37,13 @@
* @version 1.0
* @since 2024/8/28 15:52
*/
@Slf4j
@UtilityClass
public class RedisConnectionFactoryUtil {

private static final int MAX_RETRY_ATTEMPTS = 3;
private static final long RETRY_DELAY_MS = 1000;

/**
* get the RedisConnectionFactory
*
Expand All @@ -47,21 +53,61 @@ public class RedisConnectionFactoryUtil {
public RedisConnectionFactory getRedisConnectionFactory(@NonNull RedisProperties redisProperties) {
Assert.notNull(redisProperties,
"'properties' must not be null");
// add retry
int attempts = 0;
Exception lastException = null;

while (attempts < MAX_RETRY_ATTEMPTS) {
try {
return createConnectionFactory(redisProperties);
} catch (Exception e) {
lastException = e;
log.warn("Failed to create Redis connection factory, attempt {}/{}",
attempts + 1, MAX_RETRY_ATTEMPTS, e);

attempts++;
if (attempts < MAX_RETRY_ATTEMPTS) {
try {
Thread.sleep(RETRY_DELAY_MS);
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
throw new RedisConnectionException("Connection attempt interrupted", ie);
}
}
}
}

throw new RedisConnectionException("Failed to create Redis connection after " +
MAX_RETRY_ATTEMPTS + " attempts", lastException);
}

private RedisConnectionFactory createConnectionFactory(RedisProperties redisProperties) {
RedisProperties.ClientType clientType = redisProperties.getClientType();

if (clientType == RedisProperties.ClientType.JEDIS) {
// 使用 Jedis 作为 Redis 客户端
JedisConnectionFactory jedisConnectionFactory = configureJedisClient(redisProperties);
jedisConnectionFactory.start();
return jedisConnectionFactory;
} else {
// 使用 Lettuce 作为 Redis 客户端
LettuceConnectionFactory lettuceConnectionFactory = configureLettuceClient(redisProperties);
lettuceConnectionFactory.start();
return lettuceConnectionFactory;
try {
if (clientType == RedisProperties.ClientType.JEDIS) {
// use jedis client
JedisConnectionFactory factory = configureJedisClient(redisProperties);
factory.afterPropertiesSet();
validateConnection(factory);
return factory;
} else {
// use lettuce client
LettuceConnectionFactory factory = configureLettuceClient(redisProperties);
factory.afterPropertiesSet();
validateConnection(factory);
return factory;
}
} catch (Exception e) {
throw new RedisConnectionException("Error creating Redis connection factory", e);
}
}

private void validateConnection(RedisConnectionFactory factory) {
try (RedisConnection connection = factory.getConnection()) {
connection.ping();
}
}

private JedisConnectionFactory configureJedisClient(RedisProperties redisProperties) {
JedisClientConfiguration clientConfiguration = JedisClientConfiguration.builder()
Expand Down
3 changes: 3 additions & 0 deletions binders/spring-cloud-stream-binder-redis/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ dependencies {
annotationProcessor "org.springframework.boot:spring-boot-configuration-processor"
annotationProcessor "org.springframework.boot:spring-boot-autoconfigure"

implementation 'io.lettuce:lettuce-core'
implementation 'redis.clients:jedis'

testImplementation 'io.lettuce:lettuce-core'
testImplementation 'redis.clients:jedis'
testImplementation "org.springframework.boot:spring-boot-starter-test"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,15 @@
*/
package io.github.guoshiqiufeng.cloud.stream.binder.redis.health;

import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.boot.actuate.data.redis.RedisHealthIndicator;
import org.springframework.boot.actuate.health.Health;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.jedis.JedisClientConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettucePoolingClientConfiguration;

/**
* Health indicator for Redis binder.
Expand All @@ -27,7 +34,45 @@
*/
public class RedisBinderHealthIndicator extends RedisHealthIndicator {

private final RedisConnectionFactory connectionFactory;

public RedisBinderHealthIndicator(RedisConnectionFactory connectionFactory) {
super(connectionFactory);
this.connectionFactory = connectionFactory;
}

@Override
protected void doHealthCheck(Health.Builder builder) throws Exception {
try {
// 基础连接检查
super.doHealthCheck(builder);

// 连接池状态检查
checkConnectionPoolStatus(builder);

} catch (Exception e) {
builder.down().withException(e);
}
}

private void checkConnectionPoolStatus(Health.Builder builder) {
if (connectionFactory instanceof LettuceConnectionFactory lettuceFactory) {
LettuceClientConfiguration clientConfiguration = lettuceFactory.getClientConfiguration();
if (clientConfiguration instanceof LettucePoolingClientConfiguration poolConfig) {
GenericObjectPoolConfig<?> pool = poolConfig.getPoolConfig();
builder.withDetail("pool.maxTotal", pool.getMaxTotal())
.withDetail("pool.maxIdle", pool.getMaxIdle())
.withDetail("pool.minIdle", pool.getMinIdle());
} else {
builder.withDetail("pool", "Lettuce connection pool is not configured.");
}
} else if (connectionFactory instanceof JedisConnectionFactory jedisFactory) {
JedisClientConfiguration clientConfiguration = jedisFactory.getClientConfiguration();
clientConfiguration.getPoolConfig().ifPresent(pool -> {
builder.withDetail("pool.maxTotal", pool.getMaxTotal())
.withDetail("pool.maxIdle", pool.getMaxIdle())
.withDetail("pool.minIdle", pool.getMinIdle());
});
}
}
}
7 changes: 5 additions & 2 deletions docs/en/guide/actuator.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,10 @@ Example:
"redis": {
"status": "UP",
"details": {
"version": "7.1.2"
"version": "7.1.2",
"pool.maxTotal": 8,
"pool.maxIdle": 8,
"pool.minIdle": 0
}
}
}
Expand All @@ -52,4 +55,4 @@ Example:
}
}
}
```
```
25 changes: 25 additions & 0 deletions docs/en/guide/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,31 @@ spring:
The default is to use the `lettuce` client, if you need to switch to the jedis client, you can add a jedis dependency to
do so, with the same configuration parameters as spring-boot-starter-data-redis.

- jedis dependencies
<CodeGroup>
<CodeGroupItem title="Maven" active>

```xml:no-line-numbers:no-v-pre
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
```

</CodeGroupItem>

<CodeGroupItem title="Gradle">

```groovy:no-line-numbers:no-v-pre
dependencies {
implementation platform("redis.clients:jedis")
}
```

</CodeGroupItem>
</CodeGroup>

- configuration
```yaml:no-line-numbers
spring:
cloud:
Expand Down
7 changes: 5 additions & 2 deletions docs/guide/actuator.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,10 @@ management:
"redis": {
"status": "UP",
"details": {
"version": "7.1.2"
"version": "7.1.2",
"pool.maxTotal": 8,
"pool.maxIdle": 8,
"pool.minIdle": 0
}
}
}
Expand All @@ -52,4 +55,4 @@ management:
}
}
}
```
```
25 changes: 25 additions & 0 deletions docs/guide/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,31 @@ spring:

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

- jedis依赖
<CodeGroup>
<CodeGroupItem title="Maven" active>

```xml:no-line-numbers:no-v-pre
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
```

</CodeGroupItem>

<CodeGroupItem title="Gradle">

```groovy:no-line-numbers:no-v-pre
dependencies {
implementation platform("redis.clients:jedis")
}
```

</CodeGroupItem>
</CodeGroup>

- 配置
```yaml:no-line-numbers
spring:
cloud:
Expand Down
4 changes: 2 additions & 2 deletions ext.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ ext {
]

libraries = [
springBoot3Version = '3.2.11',
springCloudStreamVersion = '4.1.3'
springBoot3Version = '3.4.0',
springCloudStreamVersion = '4.2.0'
]

lib = [
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# {x-release-please-start-version}
APP_VERSION=0.4.0
APP_VERSION=0.5.0
# {x-release-please-end-version}
APP_GROUP=io.github.guoshiqiufeng.cloud

0 comments on commit 4f9770f

Please sign in to comment.