Redis的多环境配置,实现多实例

it2022-05-05  117

有时候我们可能会遇到这样的场景,有多个业务使用redis做缓存。其他业务比较占用资源。由于redis是单线程,所以会影响到主业务,这个时候我们就需要使用不同的redis的库。这个时候通过springboot+redis的多实例配置就可以实现。

Maven依赖

(1)本文使用的redis依赖如下

<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-redis</artifactId> <version>1.4.6.RELEASE</version> </dependency>

在application.yml中加入reids 的配置信息

spring: main-redis: #redis的地址 host: localhost #redis 的端口 port: 6379 #redis 的连接超时时间(毫秒) timeout: 6000 #redis 的密码 默认为空 password: pool: #redis 连接池最大连接数 max-active: 10 #redis 连接池最大空闲连接 max-idle: 5 #redis 连接池最大阻塞等待时间 max-wait: 2 #redis 连接池最小空闲连接数 min-idle: 1 lesser-redis: host: localhost port: 6333 timeout: 6000 password: pool: max-active: 10 max-idle: 5 max-wait: 2 min-idle: 1

项目的目录结构如下:

这里主要提供了三个类进行不同环境的配置;

RedisAutoConfiguration 自动配置 /** * @author kmz */ @Configuration @EnableConfigurationProperties({RedisAutoConfiguration.MainRedisProperties.class,RedisAutoConfiguration.LesserRedisProperties.class}) public class RedisAutoConfiguration { /** * @Primary 注解告诉Spring遇到多个bean的时候,它为默认 * prefix 告诉spring读取前缀为spring.main-redis的配置信息 */ @Primary @ConfigurationProperties(prefix = "spring.main-redis") public static class MainRedisProperties extends RedisProperties { } @ConfigurationProperties(prefix = "spring.lesser-redis") public static class LesserRedisProperties extends RedisProperties { } /** * 通过配置获取RedisConnectionFactory * @param mainRedisProperties mainRedis的配置信息 * @return */ @Primary @Bean("mainRedisConnectionFactory") public static RedisConnectionFactory getMainRedisConnectionFactory(MainRedisProperties mainRedisProperties){ RedisConnectionConfiguration factory = new RedisConnectionConfiguration(mainRedisProperties); return factory.redisConnectionFactory(); } /** * 获取mainredis的StringRedisTemplate实例 * @param redisConnectionFactory 使用@Qulifier指定需要的factory * @return template */ @Primary @Bean("mainStringRedisTemplate") public static StringRedisTemplate getMainStringRedisTemplate( @Qualifier(value = "mainRedisConnectionFactory") RedisConnectionFactory redisConnectionFactory){ StringRedisTemplate template = new StringRedisTemplate(); template.setConnectionFactory(redisConnectionFactory); return template; } @Bean("lesserRedisConnectionFactory") public static RedisConnectionFactory getLesserRedisConnectionFactory(LesserRedisProperties lesserRedisProperties){ RedisConnectionConfiguration factory = new RedisConnectionConfiguration(lesserRedisProperties); return factory.redisConnectionFactory(); } @Bean("lesserStringRedisTemplate") public static StringRedisTemplate getLesserStringRedisTemplate( @Qualifier(value = "lesserRedisConnectionFactory") RedisConnectionFactory redisConnectionFactory){ StringRedisTemplate template = new StringRedisTemplate(); template.setConnectionFactory(redisConnectionFactory); return template; } } RedisConnectionConfiguration 连接配置(来自于源码) package com.example.redisautoconfiguration.config; import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; import org.springframework.util.StringUtils; import redis.clients.jedis.JedisPoolConfig; import java.net.URI; import java.net.URISyntaxException; /** * @author kmz * Redis连接的配置类 * from 源码 */ public class RedisConnectionConfiguration { private final RedisProperties properties; RedisConnectionConfiguration(RedisProperties properties) { this.properties = properties; } JedisConnectionFactory redisConnectionFactory() { return applyProperties(createJedisConnectionFactory()); } private JedisConnectionFactory applyProperties(JedisConnectionFactory factory) { configureConnection(factory); if (this.properties.isSsl()) { factory.setUseSsl(true); } factory.setDatabase(this.properties.getDatabase()); if (this.properties.getTimeout() > 0) { factory.setTimeout(this.properties.getTimeout()); } return factory; } private void configureConnection(JedisConnectionFactory factory) { if (StringUtils.hasText(this.properties.getUrl())) { configureConnectionFromUrl(factory); } else { factory.setHostName(this.properties.getHost()); factory.setPort(this.properties.getPort()); if (this.properties.getPassword() != null) { factory.setPassword(this.properties.getPassword()); } } } private void configureConnectionFromUrl(JedisConnectionFactory factory) { String url = this.properties.getUrl(); if (url.startsWith("rediss://")) { factory.setUseSsl(true); } try { URI uri = new URI(url); factory.setHostName(uri.getHost()); factory.setPort(uri.getPort()); if (uri.getUserInfo() != null) { String password = uri.getUserInfo(); int index = password.indexOf(":"); if (index >= 0) { password = password.substring(index + 1); } factory.setPassword(password); } } catch (URISyntaxException ex) { throw new IllegalArgumentException("Malformed 'spring.redis.url' " + url, ex); } } private JedisConnectionFactory createJedisConnectionFactory() { JedisPoolConfig poolConfig = this.properties.getPool() != null ? jedisPoolConfig() : new JedisPoolConfig(); return new JedisConnectionFactory(poolConfig); } private JedisPoolConfig jedisPoolConfig() { JedisPoolConfig config = new JedisPoolConfig(); RedisProperties.Pool props = this.properties.getPool(); config.setMaxTotal(props.getMaxActive()); config.setMaxIdle(props.getMaxIdle()); config.setMinIdle(props.getMinIdle()); config.setMaxWaitMillis(props.getMaxWait()); return config; } } RedisPRoperties 配置信息(来自于源码) package com.example.redisautoconfiguration.config; import java.util.List; /** * Configuration properties for Redis. * * @author Dave Syer * @author Christoph Strobl * @author Eddú Meléndez * @author Marco Aust */ public class RedisProperties { /** * Database index used by the connection factory. */ private int database = 0; /** * Redis url, which will overrule host, port and password if set. */ private String url; /** * Redis server host. */ private String host = "localhost"; /** * Login password of the redis server. */ private String password; /** * Redis server port. */ private int port = 6379; /** * Enable SSL. */ private boolean ssl; /** * Connection timeout in milliseconds. */ private int timeout; private Pool pool; private Sentinel sentinel; private Cluster cluster; public int getDatabase() { return this.database; } public void setDatabase(int database) { this.database = database; } public String getUrl() { return this.url; } public void setUrl(String url) { this.url = url; } public String getHost() { return this.host; } public void setHost(String host) { this.host = host; } public String getPassword() { return this.password; } public void setPassword(String password) { this.password = password; } public int getPort() { return this.port; } public void setPort(int port) { this.port = port; } public boolean isSsl() { return this.ssl; } public void setSsl(boolean ssl) { this.ssl = ssl; } public void setTimeout(int timeout) { this.timeout = timeout; } public int getTimeout() { return this.timeout; } public Sentinel getSentinel() { return this.sentinel; } public void setSentinel(Sentinel sentinel) { this.sentinel = sentinel; } public Pool getPool() { return this.pool; } public void setPool(Pool pool) { this.pool = pool; } public Cluster getCluster() { return this.cluster; } public void setCluster(Cluster cluster) { this.cluster = cluster; } /** * Pool properties. */ public static class Pool { /** * Max number of "idle" connections in the pool. Use a negative value to indicate * an unlimited number of idle connections. */ private int maxIdle = 8; /** * Target for the minimum number of idle connections to maintain in the pool. This * setting only has an effect if it is positive. */ private int minIdle = 0; /** * Max number of connections that can be allocated by the pool at a given time. * Use a negative value for no limit. */ private int maxActive = 8; /** * Maximum amount of time (in milliseconds) a connection allocation should block * before throwing an exception when the pool is exhausted. Use a negative value * to block indefinitely. */ private int maxWait = -1; public int getMaxIdle() { return this.maxIdle; } public void setMaxIdle(int maxIdle) { this.maxIdle = maxIdle; } public int getMinIdle() { return this.minIdle; } public void setMinIdle(int minIdle) { this.minIdle = minIdle; } public int getMaxActive() { return this.maxActive; } public void setMaxActive(int maxActive) { this.maxActive = maxActive; } public int getMaxWait() { return this.maxWait; } public void setMaxWait(int maxWait) { this.maxWait = maxWait; } } /** * Cluster properties. */ public static class Cluster { /** * Comma-separated list of "host:port" pairs to bootstrap from. This represents an * "initial" list of cluster nodes and is required to have at least one entry. */ private List<String> nodes; /** * Maximum number of redirects to follow when executing commands across the * cluster. */ private Integer maxRedirects; public List<String> getNodes() { return this.nodes; } public void setNodes(List<String> nodes) { this.nodes = nodes; } public Integer getMaxRedirects() { return this.maxRedirects; } public void setMaxRedirects(Integer maxRedirects) { this.maxRedirects = maxRedirects; } } /** * Redis sentinel properties. */ public static class Sentinel { /** * Name of Redis server. */ private String master; /** * Comma-separated list of host:port pairs. */ private String nodes; public String getMaster() { return this.master; } public void setMaster(String master) { this.master = master; } public String getNodes() { return this.nodes; } public void setNodes(String nodes) { this.nodes = nodes; } } }

测试类

package com.example.redisautoconfiguration; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @SpringBootTest public class RedisTest { /** * 默认 main */ @Autowired StringRedisTemplate mainStringRedisTemplate; /** * 指定template实例 */ @Autowired @Qualifier("lesserStringRedisTemplate") StringRedisTemplate lesserStringRedisTemplate; @Test public void test(){ System.out.println("begin"); mainStringRedisTemplate.opsForValue().set("test","this is 6379"); lesserStringRedisTemplate.opsForValue().set("test","this is 6333"); } }

在本地以不同端口号启动多个redis服务

1.在mac中redis的默认安装目录为/user/loacl/ 2.在这个目录下找到redis,进入后找到redis.conf配置文件 3.复制一份重命名为6333redis.conf,将其端口号改为6333(详情请自行百度) 4.redis使用redis-server方式启动默认使用6379的端口配置文件,可以用redis-server 配置文件名 。用指定的配置文件启动redis服务 5.使用redis-cli(默认6379) -p 6333 进入两个redis库用于查看是否成功。

具体操作如下: 6379: 6333:

测试代码运行前后

运行前 6379: 6333: 测试代码运行后: 6379: 6333: 这样就实现了redis不同库的多环境配置。 代码的demo这github上有,有需要可自行查看: redis-autoconfiguration

最新回复(0)