首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Spring MVC 整合 Redis 單機與集群完整指南:Jedis 與 Spring Data Redis 兩種方案

     編輯:Java 綜合教學

Spring MVC 整合 Redis 單機與集群完整指南:Jedis 與 Spring Data Redis 兩種方案

Redis 作為高性能內存數據結構存儲,是現代 Web 系統緩存層首選。本文系統講解 Spring MVC 環境下操作 Redis 單機與集群的兩種主流方案:原生 Jedis 手動注入 與 Spring Data Redis 封裝集成,並給出生產級配置範例。

一、基礎依賴

<!-- Spring 4.3.2+ -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>4.3.2.RELEASE</version>
</dependency>

<!-- Jedis 2.9.0+ -->
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>2.9.0</version>
</dependency>

<!-- Spring Data Redis 1.7.2+ (集群支持需要此版本) -->
<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-redis</artifactId>
    <version>1.7.2.RELEASE</version>
</dependency>

二、方案一:原生 Jedis 手動注入(輕量、可控)

1. 單機客戶端封裝

public class JedisClient {
    private static final String HOST = "192.168.31.121";
    private static final JedisClient INSTANCE = new JedisClient();

    private JedisPoolConfig poolConfig() {
        JedisPoolConfig cfg = new JedisPoolConfig();
        cfg.setMaxIdle(10);
        cfg.setMaxTotal(100);
        cfg.setMaxWaitMillis(3000);
        return cfg;
    }

    public Boolean add(String key, String value) {
        try (JedisPool pool = new JedisPool(poolConfig(), HOST);
             Jedis jedis = pool.getResource()) {
            if (jedis.exists(key)) throw new RuntimeException("Key 已存在");
            jedis.set(key, value);
            return true;
        }
    }

    public String get(String key) {
        try (JedisPool pool = new JedisPool(poolConfig(), HOST);
             Jedis jedis = pool.getResource()) {
            return jedis.get(key);
        }
    }
    // 單例獲取...
}

2. 集群客戶端封裝

public class JedisClusterClient {
    private static final JedisClusterClient INSTANCE = new JedisClusterClient();
    private static final Set<HostAndPort> NODES = new HashSet<>();

    static {
        NODES.add(new HostAndPort("192.168.31.245", 7000));
        NODES.add(new HostAndPort("192.168.31.245", 7001));
        NODES.add(new HostAndPort("192.168.31.245", 7002));
        NODES.add(new HostAndPort("192.168.31.210", 7003));
        NODES.add(new HostAndPort("192.168.31.210", 7004));
        NODES.add(new HostAndPort("192.168.31.210", 7005));
    }

    public void save() {
        try (JedisCluster jc = new JedisCluster(NODES, poolConfig())) {
            jc.set("cluster", "this is a redis cluster");
            System.out.println(jc.get("cluster"));
        }
    }
}

3. Spring 整合

@Service
public class RedisService {
    public String get(String key) {
        return JedisClient.getInstance().get(key);
    }
}

@Controller
@RequestMapping("redisAllInOne")
public class RedisController {
    @Autowired RedisService redisService;
    @GetMapping("get")
    @ResponseBody
    public String get(String key) { return redisService.get(key); }
}

三、方案二:Spring Data Redis 官方集成(推薦生產)

1. 屬性配置 redis.properties

redis.maxIdle=300
redis.maxWait=3000
redis.testOnBorrow=true
redis.host=192.168.31.121
redis.port=6379
redis.password=password
redis.timeout=3000

2. 單機配置 redis-context.xml

<beans ...>
    <!-- 連接池 -->
    <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
        <property name="maxIdle" value="${redis.maxIdle}"/>
        <property name="maxWaitMillis" value="${redis.maxWait}"/>
        <property name="testOnBorrow" value="${redis.testOnBorrow}"/>
    </bean>

    <!-- 連接工廠 -->
    <bean id="connectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
        <property name="poolConfig" ref="poolConfig"/>
        <property name="hostName" value="${redis.host}"/>
        <property name="port" value="${redis.port}"/>
        <property name="timeout" value="${redis.timeout}"/>
        <property name="database" value="1"/> <!-- DB 索引 -->
    </bean>

    <!-- 序列化器 -->
    <bean id="stringRedisSerializer" class="org.springframework.data.redis.serializer.StringRedisSerializer"/>

    <!-- RedisTemplate -->
    <bean id="commonRedisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
        <property name="connectionFactory" ref="connectionFactory"/>
        <property name="keySerializer" ref="stringRedisSerializer"/>
        <property name="valueSerializer" ref="stringRedisSerializer"/>
        <property name="hashKeySerializer" ref="stringRedisSerializer"/>
        <property name="hashValueSerializer" ref="stringRedisSerializer"/>
    </bean>

    <!-- 第二個 Template 對應 DB 2 -->
    <bean id="connectionFactory1" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
        <property name="poolConfig" ref="poolConfig"/>
        <property name="hostName" value="${redis.host}"/>
        <property name="port" value="${redis.port}"/>
        <property name="timeout" value="${redis.timeout}"/>
        <property name="database" value="2"/>
    </bean>
    <bean id="cacheRedisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
        <property name="connectionFactory" ref="connectionFactory1"/>
        <property name="keySerializer" ref="stringRedisSerializer"/>
        <property name="valueSerializer" ref="stringRedisSerializer"/>
        <property name="hashKeySerializer" ref="stringRedisSerializer"/>
        <property name="hashValueSerializer" ref="stringRedisSerializer"/>
    </bean>
</beans>

3. 集群配置 redis-cluster-context.xml

<beans ...>
    <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig"> ... </bean>

    <bean id="redisClusterConfig" class="org.springframework.data.redis.connection.RedisClusterConfiguration">
        <property name="maxRedirects" value="3"/>
        <property name="clusterNodes">
            <set>
                <bean class="org.springframework.data.redis.connection.RedisNode">
                    <constructor-arg name="host" value="192.168.31.245"/>
                    <constructor-arg name="port" value="7000"/>
                </bean>
                <!-- 其餘 5 個節點 -->
            </set>
        </property>
    </bean>

    <bean id="redis4CacheConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
        <constructor-arg name="clusterConfig" ref="redisClusterConfig"/>
        <property name="poolConfig" ref="poolConfig"/>
        <property name="timeout" value="${redis.timeout}"/>
    </bean>

    <bean id="clusterRedisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
        <property name="connectionFactory" ref="redis4CacheConnectionFactory"/>
        <property name="keySerializer" ref="stringRedisSerializer"/>
        <property name="valueSerializer" ref="stringRedisSerializer"/>
        <property name="hashKeySerializer" ref="stringRedisSerializer"/>
        <property name="hashValueSerializer" ref="stringRedisSerializer"/>
    </bean>
</beans>

4. 統一入口:RedisTemplate 封裝

@Repository
public class RedisCache {
    @Resource(name = "cacheRedisTemplate")
    private RedisTemplate<String, String> redisTemplate;

    public void put(Object key, Object value) {
        if (value == null) return;
        final String k = key.toString();
        final Object v = value;
        final long ttl = 86400;
        redisTemplate.execute((RedisCallback<Long>) con -> {
            byte[] kb = k.getBytes();
            byte[] vb = serialize(v);
            con.set(kb, vb);
            if (ttl > 0) con.expire(kb, ttl);
            return 1L;
        });
    }

    public Object get(Object key) {
        final String k = key.toString();
        return redisTemplate.execute((RedisCallback<Object>) con -> {
            byte[] vb = con.get(k.getBytes());
            return vb == null ? null : deserialize(vb);
        });
    }
    // 序列化/反序列化方法省略...
}

四、關鍵注意事項

問題解決方案
版本不兼容Spring Data Redis 1.7.2+ 才支持集群,需匹配 Spring 4.3+
實體對象存儲Value 必須實現 Serializable 接口
序列化選擇String 值用 StringRedisSerializer;對象用 GenericJackson2JsonRedisSerializer 或 JDK 序列化
連接池調優maxTotal 根據業務併發設置,testOnBorrow=true 保證連接有效
集群槽位確保節點配置覆蓋所有 16384 槽位,maxRedirects 防止無限重定向

五、方案選型建議

  • 簡單項目/微服務:原生 Jedis,依賴少、啟動快、完全可控
  • 企業級應用/多環境:Spring Data Redis,統一異常轉換、聲明式事務支持、多 Template 隔離 DB、集成 Spring Cache 抽象
  • 集群環境:必須用 Spring Data Redis 1.7+ 或 JedisCluster 直連

掌握雙方案,根據項目規模與運維能力靈活選擇,讓 Redis 真正成為系統性能的加速器。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved