需求
为了高可用,防止一些突发场景(比如说XX光纤被挖事件)。现在很多公司都会做异地灾备。
对于异地服务,鉴于通信耗时问题,一般深圳地区的服务,都连着深圳地区的数据库或其他中间件。
实现
加载配置类(RabbitProperties是spring自带的,基于它搞事)
@Configuration
@ConfigurationProperties(prefix = "spring.rabbitmq.xx")
@ConditionalOnProperty(name = "test.cache.enabled", havingValue = "true", matchIfMissing = true)
public class XxRabbitProperties extends HashMap<String, RabbitProperties> {
@Bean("xxRabbitProperties")
@ConditionalOnProperty(name = "test.cache.rabbitmq.enabled", havingValue = "true", matchIfMissing = true)
public Map<String, RabbitProperties> rabbitProperties() {
return this;
}
}
@Configuration
@ConditionalOnProperty(name = "test.cache.enabled", havingValue = "true", matchIfMissing = true)
public class RabbitMqConfig {
@Value("${instance-area:SZ}")
String instanceArea;
@ConditionalOnProperty(name = "test.cache.rabbitmq.enabled", havingValue = "true", matchIfMissing = true)
public class RabbitAutoConfiguration {
@Bean
public CachingConnectionFactory rabbitConnectionFactory(
@Qualifier("xxRabbitProperties") Map<String, RabbitProperties> ftcRabbitProperties,
ObjectProvider<ConnectionNameStrategy> connectionNameStrategy) throws Exception {
String key = ftcRabbitProperties.keySet().stream()
.filter(a -> a.toUpperCase().startsWith(instanceArea.toUpperCase()))
.findFirst().orElseThrow(() -> new UnsupportedOperationException("RabbitMq配置异常:获取部署地配置失败"));
RabbitProperties properties = ftcRabbitProperties.get(key);
PropertyMapper map = PropertyMapper.get();
CachingConnectionFactory factory = new CachingConnectionFactory(
Objects.requireNonNull(getRabbitConnectionFactoryBean(properties).getObject()));
map.from(properties::determineAddresses).to(factory::setAddresses);
map.from(properties::isPublisherReturns).to(factory::setPublisherReturns);
map.from(properties::getPublisherConfirmType).whenNonNull().to(factory::setPublisherConfirmType);
RabbitProperties.Cache.Channel channel = properties.getCache().getChannel();
map.from(channel::getSize).whenNonNull().to(factory::setChannelCacheSize);
map.from(channel::getCheckoutTimeout).whenNonNull().as(Duration::toMillis)
.to(factory::setChannelCheckoutTimeout);
RabbitProperties.Cache.Connection connection = properties.getCache().getConnection();
map.from(connection::getMode).whenNonNull().to(factory::setCacheMode);
map.from(connection::getSize).whenNonNull().to(factory::setConnectionCacheSize);
map.from(connectionNameStrategy::getIfUnique).whenNonNull().to(factory::setConnectionNameStrategy);
return factory;
}
private RabbitConnectionFactoryBean getRabbitConnectionFactoryBean(RabbitProperties properties) {
PropertyMapper map = PropertyMapper.get();
RabbitConnectionFactoryBean factory = new RabbitConnectionFactoryBean();
map.from(properties::determineHost).whenNonNull().to(factory::setHost);
map.from(properties::determinePort).to(factory::setPort);
map.from(properties::determineUsername).whenNonNull().to(factory::setUsername);
map.from(properties::determinePassword).whenNonNull().to(factory::setPassword);
map.from(properties::determineVirtualHost).whenNonNull().to(factory::setVirtualHost);
map.from(properties::getRequestedHeartbeat).whenNonNull().asInt(Duration::getSeconds)
.to(factory::setRequestedHeartbeat);
RabbitProperties.Ssl ssl = properties.getSsl();
if (ssl.determineEnabled()) {
factory.setUseSSL(true);
map.from(ssl::getAlgorithm).whenNonNull().to(factory::setSslAlgorithm);
map.from(ssl::getKeyStoreType).to(factory::setKeyStoreType);
map.from(ssl::getKeyStore).to(factory::setKeyStore);
map.from(ssl::getKeyStorePassword).to(factory::setKeyStorePassphrase);
map.from(ssl::getTrustStoreType).to(factory::setTrustStoreType);
map.from(ssl::getTrustStore).to(factory::setTrustStore);
map.from(ssl::getTrustStorePassword).to(factory::setTrustStorePassphrase);
map.from(ssl::isValidateServerCertificate)
.to((validate) -> factory.setSkipServerCertificateValidation(!validate));
map.from(ssl::getVerifyHostname).to(factory::setEnableHostnameVerification);
}
map.from(properties::getConnectionTimeout).whenNonNull().asInt(Duration::toMillis)
.to(factory::setConnectionTimeout);
factory.afterPropertiesSet();
return factory;
}
}
}
注意:resources下的spring.factories配置文件记得增加配置路径。
基于spring自带的处理做的拓展开发。rabbitMq重试配置,此处没重写。