配置多個數據源,數據源爲redis集羣
spring: application: name: XXX redis: cluster: nodes: Ip:Port,Ip:Port,Ip:Port password: test-on-borrow: true timeout: 10000 #按照各自業務需求配置超時時間 lettuce: pool: max-active: 200 max-idle: 200 max-wait: 5000 min-idle: 10 secondaryRedis: cluster: nodes: Ip:Port,Ip:Port,Ip:Port password:
/** * Redis配置聲明 * */ @Configuration public class RedisConfig { //如果單個數據源,直接使用lettuceConnectionFactory,不要單獨配置 //@Autowired //public LettuceConnectionFactory lettuceConnectionFactory; //監聽執行方法 @Autowired IndexListener indexListener; //監聽執行方法 @Autowired SendIndexPriceListener sendIndexPriceListener; //聲明temp @Resource(name = "secondaryRedisTemplate") private RedisTemplate secondaryRedisTemplate; //聲明temp @Resource(name = "stringRedisTemplate") private RedisTemplate stringRedisTemplate; /** * 監聽 * @return */ @Bean RedisMessageListenerContainer indexMessageListenerContainer(){ RedisMessageListenerContainer redisMessageListenerContainer = new RedisMessageListenerContainer(); redisMessageListenerContainer.setConnectionFactory(stringRedisTemplate.getConnectionFactory()); redisMessageListenerContainer.setTaskExecutor(threadPool()); redisMessageListenerContainer.addMessageListener(indexListener, new ChannelTopic("管道名稱")); redisMessageListenerContainer.afterPropertiesSet(); return redisMessageListenerContainer; } /** * 監聽 指數推送 * @return */ @Bean RedisMessageListenerContainer sendIndexPriceListenerContainer(){ RedisMessageListenerContainer redisMessageListenerContainer = new RedisMessageListenerContainer(); redisMessageListenerContainer.setConnectionFactory(secondaryRedisTemplate.getConnectionFactory()); redisMessageListenerContainer.setTaskExecutor(threadPool()); //監聽器,管道名稱 redisMessageListenerContainer.addMessageListener(sendIndexPriceListener, new ChannelTopic("管道名稱")); redisMessageListenerContainer.afterPropertiesSet(); return redisMessageListenerContainer; } public ExecutorService threadPool(){ return Executors.newFixedThreadPool(30); } }
配置多個數據源
@Configuration public class GenerateNewTemplateRedisConfig { @Autowired private Environment environment; /** * 配置lettuce連接池 * * @return */ @Bean @Primary @ConfigurationProperties(prefix = "spring.redis.lettuce.pool") public GenericObjectPoolConfig redisPool() { return new GenericObjectPoolConfig(); } /** * 配置第一個數據源的 * * @return */ @Bean("redisClusterConfig") @Primary public RedisClusterConfiguration redisClusterConfig() { Map<String, Object> source = new HashMap<>(8); source.put("spring.redis.cluster.nodes", environment.getProperty("spring.redis.cluster.nodes")); RedisClusterConfiguration redisClusterConfiguration; redisClusterConfiguration = new RedisClusterConfiguration(new MapPropertySource("RedisClusterConfiguration", source)); redisClusterConfiguration.setPassword(RedisPassword.of(environment.getProperty("spring.redis.password"))); return redisClusterConfiguration; } /** * 配置第一個數據源的連接工廠 * 這裏注意:需要添加@Primary 指定bean的名稱,目的是爲了創建兩個不同名稱的LettuceConnectionFactory * * @param redisPool * @param redisClusterConfig * @return */ @Bean("lettuceConnectionFactory") @Primary public LettuceConnectionFactory lettuceConnectionFactory(GenericObjectPoolConfig redisPool, @Qualifier("redisClusterConfig") RedisClusterConfiguration redisClusterConfig) { LettuceClientConfiguration clientConfiguration = LettucePoolingClientConfiguration.builder().poolConfig(redisPool).build(); return new LettuceConnectionFactory(redisClusterConfig, clientConfiguration); } /** * 配置第一個數據源的stringRedisTemplate * 注意:這裏指定使用名稱=factory 的 RedisConnectionFactory * 並且標識第一個數據源是默認數據源 @Primary * * @param redisConnectionFactory * @return */ @Bean("stringRedisTemplate") @Primary public StringRedisTemplate stringRedisTemplate(@Qualifier("lettuceConnectionFactory") RedisConnectionFactory redisConnectionFactory) { return getRedisTemplate(redisConnectionFactory); } /** * 配置第二個數據源 * * @return */ @Bean("secondaryRedisClusterConfig") public RedisClusterConfiguration secondaryRedisConfig() { Map<String, Object> source = new HashMap<>(8); source.put("spring.redis.cluster.nodes", environment.getProperty("spring.secondaryRedis.cluster.nodes")); RedisClusterConfiguration redisClusterConfiguration; redisClusterConfiguration = new RedisClusterConfiguration(new MapPropertySource("RedisClusterConfiguration", source)); redisClusterConfiguration.setPassword(RedisPassword.of(environment.getProperty("spring.secondaryRedis.password"))); return redisClusterConfiguration; } @Bean("secondaryLettuceConnectionFactory") public LettuceConnectionFactory secondaryLettuceConnectionFactory(GenericObjectPoolConfig redisPool, @Qualifier("secondaryRedisClusterConfig")RedisClusterConfiguration secondaryRedisClusterConfig) { LettuceClientConfiguration clientConfiguration = LettucePoolingClientConfiguration.builder().poolConfig(redisPool).build(); return new LettuceConnectionFactory(secondaryRedisClusterConfig, clientConfiguration); } /** * 配置第二個數據源的RedisTemplate * 注意:這裏指定使用名稱=factory2 的 RedisConnectionFactory * * @param redisConnectionFactory * @return */ @Bean("secondaryRedisTemplate") public StringRedisTemplate secondaryRedisTemplate(@Qualifier("secondaryLettuceConnectionFactory") RedisConnectionFactory redisConnectionFactory) { return getRedisTemplate(redisConnectionFactory); } //返回Template並綁定RedisConnectionFactory private StringRedisTemplate getRedisTemplate(RedisConnectionFactory factory) { StringRedisTemplate template = new StringRedisTemplate(); template.setConnectionFactory(factory); return template; } }
/** * 監聽執行方法 * */ @Slf4j @Component public class SendIndexPriceListener extends MessageListenerAdapter { @Autowired LocalCache localCache; @Autowired IndexPriceService indexPriceService; @Autowired private SingleContractStopCache singleContractStopCache; public SendIndexPriceListener() { super(); super.afterPropertiesSet(); } public void handleMessage(String message, String channel) { try { String currencyId = ""; String contractIdStr = ""; if (org.apache.commons.lang3.StringUtils.isEmpty(message)) { log.error("message error, message :: {} ", message); } SendIndexPriceDto sendIndexPriceDto = JSON.parseObject(message, SendIndexPriceDto.class); boolean isLostParam = (org.apache.commons.lang3.StringUtils.isEmpty(sendIndexPriceDto.getTradePair()));//判斷幣種名稱 boolean isLostIndexPrice = StringUtils.isEmpty(sendIndexPriceDto.getIndexPrice());//判斷指數價格 if (isLostParam || isLostIndexPrice) { log.error("isLostParam or isLostIndexPrice error, isLostParam or isLostIndexPrice :: {} ", "is null"); } //獲取全部數據 List<Contract> contractList = 查詢數據庫或Redis數據; //業務邏輯 String[] tradePairArray = sendIndexPriceDto.getTradePair().toUpperCase().split("_"); if (tradePairArray.length > 0) { Map<String, String> tradePairMap = contractList.stream().collect(Collectors.toMap(a -> a.getCurrencyName().toUpperCase(), a -> a.getCurrencyId() + "_" + a.getSeq())); if (tradePairMap.containsKey(tradePairArray[0].toUpperCase())) { String[] currencySeq = tradePairMap.get(tradePairArray[0].toUpperCase()).split("_"); currencyId = currencySeq[0]; contractIdStr = currencySeq[1]; } } else { log.error("currencyName error, currencyName :: {}", "is null"); } Long id = Long.valueOf(currencyId); BigDecimal price = new BigDecimal(sendIndexPriceDto.getIndexPrice()); if (price.compareTo(BigDecimal.ZERO) <= 0) { log.error("price error, price :: {} < 0", price); } price = price.setScale(8, RoundingMode.DOWN); IndexPrice indexPriceBean = IndexPrice.builder() .currencyId(id) .price(price) .createdDate(new Date()) .build(); if (!CollectionUtils.isEmpty(contractList)) { Map<Long, Long> currencyContractMap = contractList.stream().collect(Collectors.toMap(a -> a.getCurrencyId(), a -> a.getSeq())); if (currencyContractMap.containsKey(id)) { Long contractId = currencyContractMap.get(id); if (singleContractStopCache.singleContractFlagStatus(contractId)) { log.warn("contract is stop trade, indexPrice stop !!! contract ::: {}", currencyContractMap.get(id)); } indexPriceBean.setContractId(currencyContractMap.get(id)); } } indexPriceService.updIndexPrice(indexPriceBean); log.debug("update success,contract :: {}, index price :: {}, time :: {}", contractIdStr, sendIndexPriceDto.getIndexPrice(), sendIndexPriceDto.getCreateTime()); } catch (Exception e) { log.error("deal channel :: 【{}】 message :: {} fail!", channel, message, e); } } }