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);
    }

使用

。。。。。。

参考

Reactive Spring实战 -- 响应式Redis交互

posted @   MorningBell  阅读(1721)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 记一次.NET内存居高不下排查解决与启示
点击右上角即可分享
微信分享提示