【轉】[Java]引入Redisson可能會出現項目啓動失敗問題解決

轉自:https://blog.csdn.net/bengbuguang4321/article/details/121951650

在啓動項目時,Redisson 自己會啓動一個Redisson連接池,嘗試連接redis,這時候如果遇到網絡不通就會出現問題,因爲redis連接不上,導致項目啓動不了

解決方法是:

1、重新空實現了一個RedissonClient

/**
 * @ClassName RedissonClientTemporary
 * @Decription 只是在初始化時候使用一下,之後就會被替換
 */
public class RedissonClientTemporary implements RedissonClient{
 
}

2、然後將這個空實現注入到spring容器

@Configuration
public class RedissonConfig {
    /**
     * 配置一個臨時的對象到spring容器中,不使用
     * @return 一個RedissonClient的實現
     */
    @Bean
    public RedissonClient redissonClient() {
        RedissonClient redissonClient = new RedissonClientTemporary();
        return redissonClient;
    }
}

3、在項目啓動後使用監聽事件,放入Redisson替換RedissonClient的實現,然後初始化一下

注:這裏可能還是會連接報錯,但是項目已經啓動,這裏再連接報錯的話可以考慮重試機制等補償方案

/**
 * @ClassName ApplicationLoadRedissonListener
 * @Decription 項目啓動完成,增加一個監聽器,替換spring容器裏面的redissonClient的對象,進行切換成redisson
 */
@Component
public class ApplicationLoadRedissonListener implements ApplicationListener<ApplicationReadyEvent> {
 
    private static final Logger log = LoggerFactory.getLogger(ApplicationLoadRedissonListener.class);
 
    @Autowired
    ConfigurableApplicationContext configurableApplicationContext;
    @Autowired
    private RedisProperties redisProperties;
    @Value("${spring.redis.redisson.singleServerConfig.subscriptionsPerConnection}")
    private Integer subscriptionsPerConnection;
    @Value("${spring.redis.redisson.singleServerConfig.connectionPoolSize}")
    private Integer connectionPoolSize;
    @Value("${spring.redis.redisson.singleServerConfig.connectionMinimumIdleSize}")
    private Integer connectionMinimumIdleSize;
    @Value("${spring.redis.redisson.singleServerConfig.subscriptionConnectionPoolSize}")
    private Integer subscriptionConnectionPoolSize;
    @Value("${spring.redis.redisson.singleServerConfig.subscriptionConnectionMinimumIdleSize}")
    private Integer subscriptionConnectionMinimumIdleSize;
  
    @Override
    public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) {
        try{
            //加載一些基本的redis基礎配置
            Config config = new Config();
            String address = "redis://" + redisProperties.getHost() + ":" + redisProperties.getPort();
            SingleServerConfig serverConfig = config.useSingleServer();
            serverConfig.setAddress(address);
            serverConfig.setDatabase(redisProperties.getDatabase());
            if (!StringUtils.isEmpty(redisProperties.getPassword())) {
                serverConfig.setPassword(redisProperties.getPassword());
            }
            serverConfig.setTimeout((int)redisProperties.getTimeout().toMillis());
 
            //加載redisson一些特殊配置
            serverConfig.setConnectionPoolSize(connectionPoolSize);
            serverConfig.setConnectionMinimumIdleSize(connectionMinimumIdleSize);
            serverConfig.setSubscriptionConnectionMinimumIdleSize(subscriptionConnectionMinimumIdleSize);
            serverConfig.setSubscriptionConnectionPoolSize(subscriptionConnectionPoolSize);
            serverConfig.setSubscriptionsPerConnection(subscriptionsPerConnection);
 
            log.info("加載 redisson配置信息 {}", JsonUtil.of(serverConfig));
            BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.rootBeanDefinition(Redisson.class);
            beanDefinitionBuilder.addConstructorArgValue(config);
 
            String redissonClientName = RedissonClient.class.getSimpleName().substring(0,1).toLowerCase() + RedissonClient.class.getSimpleName().substring(1);
            Object redissonClient = configurableApplicationContext.getBean(redissonClientName);
            log.info("初次放入的redissonClient實現對象:{}", redissonClient.getClass().getName());;
 
            //創建一個Redisson對象
            BeanDefinitionRegistry beanDefinitionRegistry = (BeanDefinitionRegistry) configurableApplicationContext;
            beanDefinitionRegistry.registerBeanDefinition(redissonClientName, beanDefinitionBuilder.getBeanDefinition());
 
            //這裏相當於初始化加載使用
            redissonClient = configurableApplicationContext.getBean(redissonClientName);
            log.info("最終放入的redissonClient實現對象:{}", redissonClient.getClass().getName());
        }catch (Exception e){
            log.info("ApplicationLoadRedissonListener/onApplicationEvent/RedissonClient/Exception:[{}]", e.getMessage());
        }
    } 
}
寫在最後: redisson 連接配置
# redisson 連接配置
# 單個連接最大訂閱數量
spring.redis.redisson.singleServerConfig.subscriptionsPerConnection=5
# 連接池大小
spring.redis.redisson.singleServerConfig.connectionPoolSize=8
# 最小空閒連接數
spring.redis.redisson.singleServerConfig.connectionMinimumIdleSize=4
# 發佈和訂閱連接池大小
spring.redis.redisson.singleServerConfig.subscriptionConnectionPoolSize=8
# 發佈和訂閱連接的最小空閒連接數
spring.redis.redisson.singleServerConfig.subscriptionConnectionMinimumIdleSize=1

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章