Spring boot 使用多個RedisTemplate

來源:互聯網
上載者:User

標籤:伺服器   contex   logger   結果   source   Nid   指定   tap   xid   

問題描述

想在一個JAVA Class 向同一個Redis執行個體的不同 dbindex 寫入資料,非常類似於StackOverflowe上的[How can select dbIndex when I use RedisTemplate in Spring-Data-Redis?。在這篇文章中描述了如何使用Spring boot訪問Redis,在建立JedisConnectionFactory的時候指定dbindex:

JedisConnectionFactory factory = new JedisConnectionFactory();...factory.setDatabase(databaseId);//set dbindex

因此,大概思路是配置2個RedisTemplate,其中一個RedisTemplate負責訪問dbindex=1的資料庫;另一個RedisTemplate負責訪問dbindex=3的資料庫。

根據這篇文章,因此通過 @Bean(name=) 產生多個RedisTemplate。但是由於產生RedisTemplate需要傳入JedisConnectionFactory執行個體,而我們是在JedisConnectionFactory中指定了訪問Redis的哪個資料庫(dbindex)。因此,就在建立JedisConnectionFactory執行個體的時候,使用 @Scope(scopeName = "prototype") 註解,這樣的話Jedis串連工廠就不再是單例模式了。因此,就有兩個JedisConnectionFactory執行個體,每個執行個體通過jedisConnectionFactory.setDatabase()設定不同的dbindex。這種方式可能非常愚蠢,會引起嚴重的效能問題。

下面,來看看具體是怎麼配置的:

    @Scope(scopeName = "prototype")    public JedisConnectionFactory jedisConnectionFactory() {    JedisPoolConfig config = getRedisConfig();    JedisConnectionFactory factory = new JedisConnectionFactory(config);    factory.setUsePool(true);    factory.setHostName(host);    factory.setPort(port);    return factory;    }

每調用一次jedisConnectionFactory() 返回一個新的JedisConnectionFactory執行個體。

然後定義2個RedisTemplate Bean,jedisConnectionFactory.setDatabase() 方法分別設定不同的dbindex

 import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Value;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.Scope;import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;import org.springframework.data.redis.core.RedisTemplate;import org.springframework.data.redis.serializer.StringRedisSerializer;import redis.clients.jedis.JedisPoolConfig;import java.util.Map;/** * Created by Administrator on 2018/4/9. */@Configurationpublic class LoginMacRedisConfig {    private static final Logger logger = LoggerFactory.getLogger(LoginMacRedisConfig.class);    @Value("1")    private int logmacDatabaseId;    @Value("3")    private int mobmaskDatabaseId;    @Bean    public JedisPoolConfig getRedisConfig() {    JedisPoolConfig config = new JedisPoolConfig();    config.setMaxIdle(8);    config.setMinIdle(0);    return config;    }    @Scope(scopeName = "prototype")    public JedisConnectionFactory jedisConnectionFactory() {    JedisPoolConfig config = getRedisConfig();    JedisConnectionFactory factory = new JedisConnectionFactory(config);    factory.setUsePool(true);    factory.setHostName(host);    factory.setPort(port);    return factory;    }    @Bean(name = "login_mac")    public RedisTemplate<String, Map<String, String>> logmacRedisTemplate() {    final RedisTemplate<String, Map<String, String>> template = new RedisTemplate<>();    JedisConnectionFactory jedisConnectionFactory = jedisConnectionFactory();    jedisConnectionFactory.setDatabase(logmacDatabaseId);    template.setConnectionFactory(jedisConnectionFactory);    logger.info("host:{}, port:{}, database:{}", jedisConnectionFactory.getHostName(),jedisConnectionFactory.getPort(), jedisConnectionFactory.getDatabase());    StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();    template.setKeySerializer(stringRedisSerializer);    template.setHashKeySerializer(stringRedisSerializer);    template.setHashValueSerializer(stringRedisSerializer);    return template;    }    @Bean(name = "mobile_mask")    public RedisTemplate<String, Map<String, String>> mobileMaskRedisTemplate() {    final RedisTemplate<String, Map<String, String>> template = new RedisTemplate<>();    JedisConnectionFactory jedisConnectionFactory = jedisConnectionFactory();    jedisConnectionFactory.setDatabase(mobmaskDatabaseId);    template.setConnectionFactory(jedisConnectionFactory);    logger.info("host:{}, port:{}, database:{}", jedisConnectionFactory.getHostName(),jedisConnectionFactory.getPort(), jedisConnectionFactory.getDatabase());    StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();    template.setKeySerializer(stringRedisSerializer);    template.setHashKeySerializer(stringRedisSerializer);    template.setHashValueSerializer(stringRedisSerializer);    return template;    }}

最後,再寫一個Service類,就可以同時注入這兩個RedisTemplate,操作同一個Redis伺服器上的不同的dbindex了。

import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.data.redis.core.HashOperations;import org.springframework.data.redis.core.RedisTemplate;import org.springframework.stereotype.Service;import java.util.HashMap;import java.util.Map;/** * Created by Administrator on 2018/4/10. */@Servicepublic class RedisTestService {    @Autowired    @Qualifier("login_mac")    private RedisTemplate<String, Map<String, String>> template1;    @Autowired    @Qualifier("mobile_mask")    private RedisTemplate<String, Map<String, String>> template2;    public void write2Redis() {    HashOperations<String, String, String> hashOperations = template1.opsForHash();    Map<String, String> values = new HashMap<>();    values.put("dbindex", "1");    hashOperations.putAll("123", values);    template2.opsForHash().put("123", "dbindex", "3");    }}

Application.java 啟動類

@SpringBootApplicationpublic class Application implements CommandLineRunner{    @Autowired    private RedisTestService redisTestService;    public static void main(String[] args) {    SpringApplication.run(Application.class, args);    }    @Override    public void run(String... strings) throws Exception {    redisTestService.write2Redis();    }}

在redisTestService對象中:有兩個RedisTemplate執行個體:

兩個RedisTemplate執行個體分別封裝了兩個JedisConnectionFactory:

調試結果下:

2018-04-10 20:18:34.754  INFO 13512 --- [           main] c.y.t.c.redis.LoginMacRedisConfig        : host:192.168.107.253, port:6379, database:1
2018-04-10 20:19:06.972  INFO 13512 --- [           main] c.y.t.c.redis.LoginMacRedisConfig        : host:192.168.107.253, port:6379, database:3

最終查看寫入Redis結果,可以看出:dbindex 1 和 dbindex 3 都分別成功寫入了資料。

redis 192.168.107.253:6379> SELECT 1OKredis 192.168.107.253:6379[1]> KEYS *1) "123"redis 192.168.107.253:6379[1]> HGET 123 dbindex"1"redis 192.168.107.253:6379[1]> SELECT 3OKredis 192.168.107.253:6379[3]> KEYS *1) "123"redis 192.168.107.253:6379[3]> HGET 123 dbindex"3"
額外補充

其實要在同一個應用中訪問不同的dbindex,一種方式是使用JedisPool,JedisPool建立Jedis,然後調用select方法選擇dbindex。具體實現可參考這篇文章。但這樣的話,就不能使用RedisTemplate的各種方便的介面讀寫Redis了。

    @Bean    public JedisPool redisPoolFactory() {        JedisPool jedisPool = new JedisPool(jedisPoolConfig(), host, port);        Jedis jedis = jedisPool.getResource();        jedis.select(3);        return jedisPool;    }

其實是可以像說的:通過RedisConnectionCommand的 select 方法來選擇dbindex的,但是還是同樣的問題,用不了RedisTemplate。

RedisConnection redisConnection = redisTemplate.getConnectionFactory().getConnection();DefaultStringRedisConnection stringRedisConnection = new   DefaultStringRedisConnection(redisConnection);stringRedisConnection.select(2);stringRedisConnection.set("test", "test");

另外這裡也有一篇Spring Boot Redis多執行個體配置,也可以參考一下。Spring Boot 兼Redis新手,只能這樣了。

原文:http://www.cnblogs.com/hapjin/p/8783084.html

Spring boot 使用多個RedisTemplate

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.