spring-redis配置

本文详细介绍Spring框架下Redis的配置方式,包括使用XML配置文件、属性文件注入、高级URI注入等多种方法,并提供了具体示例。
spring-redis配置
1. applicationContext-redis.xml配置文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
    <!-- 定义受环境影响易变的变量 -->
    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
    <property name="ignoreResourceNotFound" value="true" />
    <property name="ignoreUnresolvablePlaceholders" value="true" />
    <property name="locations">
        <list>
            <value>classpath:redis-config.properties</value>
        </list>
    </property>
</bean>
    <!-- 公共POOL配置 -->
    <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
        <property name="maxTotal" value="1024" />
         <property name="maxIdle" value="8" /><!-- 最大空闲连接数, 默认8个 -->
        <property name="maxWaitMillis" value="15000"/><!-- 获取连接时的最大等待毫秒数 -->
        <property name="testOnBorrow" value="true" /><!-- 在获取连接的时候检查有效性, 默认false -->
        <property name="testWhileIdle" value="false"/><!-- 空闲是否检查是否有效,默认为false -->
        <property name="testOnReturn" value="true"/>
    </bean>


    <!-- jedis shard信息配置 -->
    <bean id="jedisShardInfo" class="redis.clients.jedis.JedisShardInfo">
        <constructor-arg index="0" value="192.168.1.204" />
        <constructor-arg index="1" value="6380" type="int"/> 
        <property name="password" value="123456" />
    </bean>

    <!-- jedis shard pool配置,提供给程序注入使用 -->
    <bean id="shardedJedisPool" class="redis.clients.jedis.ShardedJedisPool">
        <constructor-arg index="0" ref="jedisPoolConfig" />
        <constructor-arg index="1">
            <list>
                <ref bean="jedisShardInfo" />
            </list>
        </constructor-arg>
    </bean>

</beans>
2. 通过redis-config.properties文件注入

applicationContext-redis.xml相应地方更改为

<!-- jedis shard信息配置 -->
<bean id="jedisShardInfo" class="redis.clients.jedis.JedisShardInfo">
    <constructor-arg index="0" value="${redis.ip}" />
    <constructor-arg index="1" value="${redis.port}" type="int"/> 
    <property name="password" value="${redis.password}" />
</bean>

redis-config.properties文件:

redis.ip=192.168.1.204
redis.password=123456
redis.port=6379

注意:如果适用默认端口6379,使用自定义端口6380,如果不指定类型,构造时始终调用两个字符串的构造函数,所以当出现端口更改时,程序还是调用原来的构造函数. 故必须指定参数类型为int

<constructor-arg index="1" value="6380" type="int"/>
3. 高级uri注入,可选择db
<!-- jedis uri信息配置 -->
<bean id="uri" class="java.net.URI">
     <!-- jedis URI配置   redis://redis:password@ip:port/database   -->
    <constructor-arg index="0" value="redis://redis:123456@192.168.1.203:6379/2" />
</bean>
<bean id="jedis.shardInfo" class="redis.clients.jedis.JedisShardInfo">
    <constructor-arg index="0" ref="uri" />
</bean>

这个注入方法比较高级,可以选择Redis DB 可以选择相应的db(redis默认db=0),目前redis.clients.jedis.JedisShardInfo类中没有提供直接改变db的构造方法或者属性注入,个人认为这是目前改变db最快捷的方法;当然也有其他方法,比如自己重写当前类等

我还碰到一个更奇葩的问题,密码中存在“/”,导致不能正确读取到db,原因各位请看源码便知
解决方法:

<!-- jedis uri信息配置 -->
<bean id="uri" class="java.net.URI">
     <!-- jedis URI配置   redis://redis:password@ip:port/database   -->
    <constructor-arg index="0" value="redis://redis:123456@192.168.1.203:6379/2" />
</bean>
<bean id="jedis.shardInfo" class="redis.clients.jedis.JedisShardInfo">
    <constructor-arg index="0" ref="uri" />
    <property name="password" value="123/456" />
</bean>

PS:spring注入是先方法再属性,所以此方法可行!

4. 最后附上redis.clients.jedis.JedisShardInfo源码:
package redis.clients.jedis;

import java.net.URI;

import redis.clients.jedis.exceptions.InvalidURIException;
import redis.clients.util.JedisURIHelper;
import redis.clients.util.ShardInfo;
import redis.clients.util.Sharded;

public class JedisShardInfo extends ShardInfo<Jedis> {

  public String toString() {
    return host + ":" + port + "*" + getWeight();
  }

  private int connectionTimeout;
  private int soTimeout;
  private String host;
  private int port;
  private String password = null;
  private String name = null;
  // Default Redis DB
  private int db = 0;

  public String getHost() {
    return host;
  }

  public int getPort() {
    return port;
  }

  public JedisShardInfo(String host) {
    super(Sharded.DEFAULT_WEIGHT);
    URI uri = URI.create(host);
    if (JedisURIHelper.isValid(uri)) {
      this.host = uri.getHost();
      this.port = uri.getPort();
      this.password = JedisURIHelper.getPassword(uri);
      this.db = JedisURIHelper.getDBIndex(uri);
    } else {
      this.host = host;
      this.port = Protocol.DEFAULT_PORT;
    }
  }

  public JedisShardInfo(String host, String name) {
    this(host, Protocol.DEFAULT_PORT, name);
  }

  public JedisShardInfo(String host, int port) {
    this(host, port, 2000);
  }

  public JedisShardInfo(String host, int port, String name) {
    this(host, port, 2000, name);
  }

  public JedisShardInfo(String host, int port, int timeout) {
    this(host, port, timeout, timeout, Sharded.DEFAULT_WEIGHT);
  }

  public JedisShardInfo(String host, int port, int timeout, String name) {
    this(host, port, timeout, timeout, Sharded.DEFAULT_WEIGHT);
    this.name = name;
  }

  public JedisShardInfo(String host, int port, int connectionTimeout, int soTimeout, int weight) {
    super(weight);
    this.host = host;
    this.port = port;
    this.connectionTimeout = connectionTimeout;
    this.soTimeout = soTimeout;
  }

  public JedisShardInfo(String host, String name, int port, int timeout, int weight) {
    super(weight);
    this.host = host;
    this.name = name;
    this.port = port;
    this.connectionTimeout = timeout;
    this.soTimeout = timeout;
  }

  public JedisShardInfo(URI uri) {
    super(Sharded.DEFAULT_WEIGHT);
    if (!JedisURIHelper.isValid(uri)) {
      throw new InvalidURIException(String.format(
        "Cannot open Redis connection due invalid URI. %s", uri.toString()));
    }

    this.host = uri.getHost();
    this.port = uri.getPort();
    this.password = JedisURIHelper.getPassword(uri);
    this.db = JedisURIHelper.getDBIndex(uri);
  }

  public String getPassword() {
    return password;
  }

  public void setPassword(String auth) {
    this.password = auth;
  }

  public int getConnectionTimeout() {
    return connectionTimeout;
  }

  public void setConnectionTimeout(int connectionTimeout) {
    this.connectionTimeout = connectionTimeout;
  }

  public int getSoTimeout() {
    return soTimeout;
  }

  public void setSoTimeout(int soTimeout) {
    this.soTimeout = soTimeout;
  }

  public String getName() {
    return name;
  }

  public int getDb() {
    return db;
  }

  @Override
  public Jedis createResource() {
    return new Jedis(this);
  }

}
<think>嗯,用户想配置Spring Redis连接代理地址,而实际的Redis服务端地址他们不知道。首先,我需要回忆一下Spring Data Redis配置方式。通常,我们会用Lettuce或者Jedis作为客户端,这里可能涉及到集群配置,但用户提到的是代理地址,所以可能他们用的是像Redis Sentinel或者云服务提供的代理模式,比如AWS ElastiCache的集群模式。 用户的情况是,他们只知道代理的地址,而不知道后端具体的Redis节点。这时候,传统的集群配置可能需要节点地址,但代理模式可能只需要一个入口点。例如,云服务中的代理会处理请求的路由,所以应用程序只需要连接代理的地址和端口,而不需要知道所有节点的信息。 接下来,我得确定在Spring Boot中如何配置单节点连接,因为代理通常表现为一个单独的节点。用户可能在application.properties里配置spring.redis.host和spring.redis.port,指向代理的地址。但如果是哨兵模式,可能需要配置spring.redis.sentinel的相关属性。不过用户明确说是代理地址,可能不是哨兵,而是像Twemproxy或者云代理的情况。 然后,检查是否需要SSL或者其它安全配置,比如如果代理在云上,可能需要启用SSL和修改端口。例如,AWS ElastiCache的集群模式启用SSL时,端口可能会从6379变为6380。这时需要在配置中指定端口和开启SSL。 另外,连接池配置也很重要,特别是在代理模式下,合理的连接池参数可以提升性能。需要提醒用户根据实际情况调整max-active、max-idle等参数。 可能还需要考虑客户端 Lettuce 或 Jedis配置差异。Lettuce 是默认的,支持异步,而 Jedis 是传统的。如果用户有特殊需求,可能需要排除默认的Lettuce,引入Jedis依赖。 最后,验证配置是否正确,可以通过注入RedisTemplate并执行简单的操作,比如set和get,来测试连接是否成功。如果出现超时或连接拒绝,需要检查代理地址、端口、防火墙设置以及安全组规则是否正确。 总结下来,用户的场景可能是使用云服务的Redis代理,所以配置的重点在于正确设置代理的主机和端口,调整SSL和连接池参数,并根据客户端库的不同进行相应配置。</think>在 Spring Boot 中配置 Redis 代理地址的场景(例如 AWS ElastiCache、阿里云代理模式等),以下是具体实现步骤: #### 1. 基础配置 ```properties # application.properties # 直接指向代理地址(不需要知道底层节点) spring.redis.host=your-proxy-endpoint # 代理地址域名/IP spring.redis.port=6379 # 代理暴露的端口 spring.redis.password=your-password # 如果有密码验证 ``` #### 2. 云服务特殊配置(以 AWS 为例) ```properties # 启用 SSL 时可能需要配置(云服务常见) spring.redis.ssl=true spring.redis.port=6380 # AWS SSL 默认端口 ``` #### 3. 连接池调优 ```properties # 代理模式建议适当增大连接池 spring.redis.lettuce.pool.max-active=20 spring.redis.lettuce.pool.max-idle=10 spring.redis.lettuce.pool.min-idle=5 ``` #### 4. 强制单节点模式 ```java @Configuration public class RedisConfig { @Bean public RedisConnectionFactory redisConnectionFactory(RedisProperties properties) { RedisStandaloneConfiguration config = new RedisStandaloneConfiguration(); config.setHostName(properties.getHost()); config.setPort(properties.getPort()); config.setPassword(properties.getPassword()); return new LettuceConnectionFactory(config); // 使用 Lettuce 客户端 } } ``` #### 5. 客户端选择建议 ```xml <!-- pom.xml 强制使用 Jedis --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> <exclusions> <exclusion> <groupId>io.lettuce</groupId> <artifactId>lettuce-core</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> </dependency> ``` #### 验证配置是否生效 ```java @SpringBootTest public class RedisTest { @Autowired private RedisTemplate<String, String> redisTemplate; @Test void testConnection() { redisTemplate.opsForValue().set("testKey", "Hello Proxy"); assert "Hello Proxy".equals(redisTemplate.opsForValue().get("testKey")); } } ``` #### 常见问题排查方向 1. **连接超时**:检查代理地址的网络安全组/ACL规则 2. **认证失败**:确认密码是否包含特殊字符需要URL编码 3. **协议不匹配**:云服务可能需要使用 TLSv1.2 协议 4. **DNS解析**:建议代理地址使用IP地址避免DNS问题 对于完全托管的云服务(如阿里云、AWS),建议优先使用云厂商提供的 SDK 进行连接,这些 SDK 通常会处理: - 自动故障转移 - 热升级维护 - 读写分离 - 多可用区容灾等特性
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值