ReactiveRedisTemplate配置使用
在Spring Data Redis中同时支持了Jedis客户端和Lettuce客户端。但是仅Lettuce是支持Reactive方式的操作,所以如果你希望使用Reactive方式那你只能选择Lettuce客户端。
应用启动后,Spring会自动生成ReactiveRedisTemplate(它的底层框架是Lettuce)。 ReactiveRedisTemplate与RedisTemplate使用类似,但它提供的是异步的,响应式Redis交互方式。 这里再强调一下,响应式编程是异步的,ReactiveRedisTemplate发送Redis请求后不会阻塞线程,当前线程可以去执行其他任务。 等到Redis响应数据返回后,ReactiveRedisTemplate再调度线程处理响应数据。 响应式编程可以通过优雅的方式实现异步调用以及处理异步结果,正是它的最大的意义。
依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>
简单配置
配置文件
spring.redis.host=192.168.56.102
spring.redis.port=6379
spring.redis.password=
spring.redis.timeout=5000
配置bean
//配置序列化器
@Bean
public RedisSerializationContext redisSerializationContext() {
RedisSerializationContext.RedisSerializationContextBuilder builder = RedisSerializationContext.newSerializationContext();
builder.key(StringRedisSerializer.UTF_8);
builder.value(RedisSerializer.json());
builder.hashKey(StringRedisSerializer.UTF_8);
builder.hashValue(StringRedisSerializer.UTF_8);
return builder.build();
}
@Bean
public ReactiveRedisTemplate reactiveRedisTemplate(ReactiveRedisConnectionFactory connectionFactory) {
RedisSerializationContext serializationContext = redisSerializationContext();
ReactiveRedisTemplate reactiveRedisTemplate = new ReactiveRedisTemplate(connectionFactory,serializationContext);
return reactiveRedisTemplate;
}
详尽配置
配置文件
## flow limit
myconf.flow.limit.redis.client=RedisTemplate
spring.redis.flow.limit.master=mymaster
spring.redis.flow.limit.nodes=tcp://127.0.0.1:6379
spring.redis.flow.limit.password=default_password
spring.redis.flow.limit.type=standalone
配置类
package com.myobj.im.service.conf;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties(prefix = "spring.redis")
@Data
public class RedisConfigProperties {
private Property flow;
@Data
public static class Property {
//configuration
private String type = "standalone";
private String master = "mymaster";
private String nodes;
private String password = "default_password";
// jedis lettuce
private String connectionFactory = "jedis";
private Integer maxRedirects = 5;
private Integer maxAttempts = 5;
private Integer soTimeout = 5000;
//pool
private Integer maxIdle;
private Integer minIdle;
private Integer maxTotal = 100;
private Long maxWait = 5000L;
private Long readTimeout = 60000L;
private Long connectTimeout = 2000L;
private Boolean isSsl = false;
private Boolean testOnBorrow;
private Boolean testOnCreate;
private Boolean testOnReturn;
private Long timeBetweenEvictionRuns;
private Long minEvictableIdleTimeMillis;
}
}
redisTemplate生成的工具类
public final class RedisUtils {
private RedisUtils() {
}
private static final String DEFAULT_PASSWORD = "default_password";
private static final String CLUSTER = "cluster";
private static final String SENTINEL = "sentinel";
public static ReactiveRedisConnectionFactory reactiveRedisConnectionFactory(
RedisConfigProperties.Property property, ClientResources clientResources) {
return (ReactiveRedisConnectionFactory) connectionFactory(property, clientResources,
LettuceConnectionFactory.class);
}
public static RedisConnectionFactory connectionFactory(
RedisConfigProperties.Property property) {
Class clazz = JedisConnectionFactory.class;
if ("lettuce".equals(property.getConnectionFactory())) {
clazz = LettuceConnectionFactory.class;
}
return connectionFactory(property, null, clazz);
}
public static RedisConnectionFactory connectionFactory(
RedisConfigProperties.Property property,
ClientResources clientResources,
Class<? extends RedisConnectionFactory> clazz) {
JedisClientConfiguration jedisClientConfiguration = getJedisClientConfiguration(property);
LettuceClientConfiguration lettuceClientConfiguration =
getPoolClientConfiguration(property, clientResources);
RedisConfiguration configuration = getRedisConfiguration(property);
if (configuration instanceof RedisClusterConfiguration) {
RedisClusterConfiguration clusterConfiguration =
(RedisClusterConfiguration) configuration;
if (JedisConnectionFactory.class.equals(clazz)) {
JedisConnectionFactory connectionFactory = new JedisConnectionFactory(
clusterConfiguration, jedisClientConfiguration);
connectionFactory.afterPropertiesSet();
return connectionFactory;
} else if (LettuceConnectionFactory.class.equals(clazz)) {
LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(
clusterConfiguration, lettuceClientConfiguration);
connectionFactory.afterPropertiesSet();
return connectionFactory;
}
// not match connection factory
} else if (configuration instanceof RedisSentinelConfiguration) {
if (JedisConnectionFactory.class.equals(clazz)) {
JedisConnectionFactory connectionFactory =
new JedisConnectionFactory((RedisSentinelConfiguration) configuration,
jedisClientConfiguration);
connectionFactory.afterPropertiesSet();
return connectionFactory;
} else if (LettuceConnectionFactory.class.equals(clazz)) {
LettuceConnectionFactory connectionFactory =
new LettuceConnectionFactory((RedisSentinelConfiguration) configuration,
lettuceClientConfiguration);
connectionFactory.afterPropertiesSet();
return connectionFactory;
}
} else if (configuration instanceof RedisStandaloneConfiguration) {
if (JedisConnectionFactory.class.equals(clazz)) {
JedisConnectionFactory connectionFactory =
new JedisConnectionFactory((RedisStandaloneConfiguration) configuration,
jedisClientConfiguration);
connectionFactory.afterPropertiesSet();
return connectionFactory;
} else if (LettuceConnectionFactory.class.equals(clazz)) {
LettuceConnectionFactory connectionFactory =
new LettuceConnectionFactory((RedisStandaloneConfiguration) configuration,
lettuceClientConfiguration);
connectionFactory.afterPropertiesSet();
return connectionFactory;
}
}
return null;
}
private static RedisConfiguration getRedisConfiguration(
RedisConfigProperties.Property property) {
List<String> uris = new ArrayList<>(Arrays.asList(property.getNodes().split(",")));
if (CLUSTER.equalsIgnoreCase(property.getType())) {
RedisClusterConfiguration redisClusterConfiguration = new RedisClusterConfiguration();
redisClusterConfiguration.setMaxRedirects(property.getMaxRedirects());
List<RedisNode> nodeList = new ArrayList<>();
for (String uriString : uris) {
URI uri = URI.create(uriString);
RedisNode redisNode = new RedisNode(uri.getHost(), uri.getPort());
nodeList.add(redisNode);
}
redisClusterConfiguration.setClusterNodes(nodeList);
if (!property.getPassword().equals(DEFAULT_PASSWORD)) {
redisClusterConfiguration.setPassword(RedisPassword.of(property.getPassword()));
}
return redisClusterConfiguration;
} else if (SENTINEL.equals(property.getType())) {
RedisSentinelConfiguration redisSentinelConfiguration =
new RedisSentinelConfiguration();
redisSentinelConfiguration.setMaster(property.getMaster());
List<RedisNode> nodeList = new ArrayList<>();
uris.forEach(uriString -> {
URI uri = URI.create(uriString);
RedisNode redisNode = new RedisNode(uri.getHost(), uri.getPort());
nodeList.add(redisNode);
});
if (!property.getPassword().equals(DEFAULT_PASSWORD)) {
redisSentinelConfiguration.setPassword(RedisPassword.of(property.getPassword()));
}
redisSentinelConfiguration.setSentinels(nodeList);
return redisSentinelConfiguration;
}
RedisStandaloneConfiguration configuration = new RedisStandaloneConfiguration();
URI uri = URI.create(uris.get(0));
configuration.setHostName(uri.getHost());
configuration.setPort(uri.getPort());
if (!property.getPassword().equals(DEFAULT_PASSWORD)) {
configuration.setPassword(RedisPassword.of(property.getPassword()));
}
return configuration;
}
public static JedisClientConfiguration getJedisClientConfiguration(
RedisConfigProperties.Property property) {
JedisPoolConfig jedisPoolConfig = getJedisPoolConfig(property);
JedisClientConfiguration.JedisClientConfigurationBuilder builder =
JedisClientConfiguration.builder();
if (Boolean.TRUE.equals(property.getIsSsl())) {
builder.useSsl();
}
return builder
.usePooling()
.poolConfig(jedisPoolConfig)
.and()
.readTimeout(Duration.ofMillis(property.getReadTimeout()))
.connectTimeout(Duration.ofMillis(property.getConnectTimeout()))
.build();
}
public static LettuceClientConfiguration getPoolClientConfiguration(
RedisConfigProperties.Property property, ClientResources clientResources) {
JedisPoolConfig jedisPoolConfig = getJedisPoolConfig(property);
LettucePoolingClientConfiguration.LettucePoolingClientConfigurationBuilder builder =
LettucePoolingClientConfiguration.builder();
builder.poolConfig(jedisPoolConfig);
if (clientResources != null) {
builder.clientResources(clientResources);
}
if (Boolean.TRUE.equals(property.getIsSsl())) {
builder.useSsl();
}
if (CLUSTER.equalsIgnoreCase(property.getType())) {
ClusterTopologyRefreshOptions clusterTopologyRefreshOptions = ClusterTopologyRefreshOptions
.builder()
.closeStaleConnections(true)
.enablePeriodicRefresh()
.enableAllAdaptiveRefreshTriggers()
.enableAdaptiveRefreshTrigger()
.build();
ClusterClientOptions clientOptions =
ClusterClientOptions.builder().topologyRefreshOptions(clusterTopologyRefreshOptions)
.build();
builder.clientOptions(clientOptions);
}
return builder.build();
}
private static JedisPoolConfig getJedisPoolConfig(RedisConfigProperties.Property property) {
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
if (property.getMaxTotal() != null) {
jedisPoolConfig.setMaxTotal(property.getMaxTotal());
}
if (property.getMaxIdle() != null) {
jedisPoolConfig.setMaxIdle(property.getMaxIdle());
}
if (property.getMinIdle() != null) {
jedisPoolConfig.setMinIdle(property.getMinIdle());
}
if (property.getMaxWait() != null) {
jedisPoolConfig.setMaxWaitMillis(property.getMaxWait());
}
if (property.getTimeBetweenEvictionRuns() != null) {
jedisPoolConfig.setTimeBetweenEvictionRunsMillis(property.getTimeBetweenEvictionRuns());
}
if (property.getMinEvictableIdleTimeMillis() != null) {
jedisPoolConfig.setMinEvictableIdleTimeMillis(property.getMinEvictableIdleTimeMillis());
}
if (property.getTestOnBorrow() != null) {
jedisPoolConfig.setTestOnBorrow(property.getTestOnBorrow());
}
if (property.getTestOnCreate() != null) {
jedisPoolConfig.setTestOnCreate(property.getTestOnCreate());
}
if (property.getTestOnReturn() != null) {
jedisPoolConfig.setTestOnReturn(property.getTestOnReturn());
}
return jedisPoolConfig;
}
}
配置templateBean对象
@Primary
@Bean(name = "reactiveFlowRedisConnectionFactory")
public ReactiveRedisConnectionFactory flowLimitReactiveConnectionFactory(
RedisConfigProperties redisConfigProperties) {
ClientResources clientResources = DefaultClientResources.builder()
.ioThreadPoolSize(clientCore)
.computationThreadPoolSize(clientCore)
.build();
return RedisUtils
.reactiveRedisConnectionFactory(redisConfigProperties.getFlow(), clientResources);
}
@Primary
@Bean(name = "reactiveRedisFlowTemplate")
public ReactiveStringRedisTemplate flowLimitTemplate(
@Qualifier("reactiveFlowRedisConnectionFactory")
ReactiveRedisConnectionFactory reactiveRedisConnectionFactory) {
return new ReactiveStringRedisTemplate(reactiveRedisConnectionFactory);
}
使用
。。。。。。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 记一次.NET内存居高不下排查解决与启示