SpringBoot支持Kafka多源配置的同时还要支持启停配置化,是真的会玩
开心一刻
今早,女朋友给我发微信
她:宝贝,你要记住
她:我可是你女朋友,你相亲就亲,想抱就抱
她:不要老是问我,男生要主动一些
我:可是你上次报警可不是这么说的

基础回顾
Spring Boot 集成 Kafka 非常简单,我相信你们都会,但我还是想带你们回顾下;只需要进行以下几步即可完成 Spring Boot 与 Kafka 的集成
引入依赖
如果只是单纯的集成,不考虑其他功能,那么添加如下依赖即可
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.18</version>
</parent> <dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka</artifactId>
</dependency>
</dependencies>
Spring Boot 并没有提供
starter的方式来集成 Kafka,不要一根筋的去找 starter如果还需要
web功能,则可以像如下一样添加依赖<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.18</version>
</parent> <dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka</artifactId>
</dependency>
</dependencies>
依赖就是如此简单;扯个题外问题
spring-kafka的版本在哪指定的?添加配置
如果 Kafka 未开启认证,那配置可以非常简单
spring:
kafka:
bootstrap-servers: 192.168.0.87:9092,192.168.0.88:9092,192.168.0.89:9092
但实际使用中,往往会开启认证,并对
consumer做定制化配置,配置往往类似如下spring:
kafka:
bootstrap-servers: 192.168.0.87:9092,192.168.0.88:9092,192.168.0.89:9092
consumer:
# 自动提交消费位移
enable-auto-commit: false
# 偏移量初始位置
auto-offset-reset: latest
# 一次拉取记录最大数
max-poll-records: 5
properties:
security.protocol: SASL_PLAINTEXT
sasl.mechanism: PLAIN
#sasl.mechanism: SCRAM-SHA-256
#username、password需要调整成实际值
sasl.jaas.config: org.apache.kafka.common.security.plain.PlainLoginModule required username="username" password="password";
#sasl.jaas.config: org.apache.kafka.common.security.scram.ScramLoginModule required username="username" password="password";
listener:
ack-mode: manual
producer:
properties:
security.protocol: SASL_PLAINTEXT
sasl.mechanism: PLAIN
#sasl.mechanism: SCRAM-SHA-256
#username、password需要调整成实际值
sasl.jaas.config: org.apache.kafka.common.security.plain.PlainLoginModule required username="username" password="password";
#sasl.jaas.config: org.apache.kafka.common.security.scram.ScramLoginModule required username="username" password="password";
也不复杂,相信你们都能看懂
进行使用
分两点:
消费消息和发送消息消费消息实现很简单/**
* @author: 青石路
*/
@Component
public class KafkaConsumer { private static final Logger log = LoggerFactory.getLogger(KafkaConsumer.class); @KafkaListener(topics = "tp_qsl_order_cancel", groupId = "gid_qsl_order_cancel")
public void listenOrder(String message, Acknowledgment acknowledgment) {
try {
log.info("收到kafka message: {}", message);
// TODO 业务处理
} finally {
acknowledgment.acknowledge();
}
}
}
监听的
topic是tp_qsl_order_cancel,消费者组指定为gid_qsl_order_cancel;这样,消费监听就算完成了发送消息实现同样简单,注入KafkaTemplate,然后调用其send方法即可/**
* @author: 青石路
*/
@Component
public class KafkaSender { private static final Logger log = LoggerFactory.getLogger(KafkaSender.class); @Resource
private KafkaTemplate<String, String> kafkaTemplate; public void send(String topic, String msg) {
kafkaTemplate.send(topic, msg).addCallback(
success -> {
if (success != null) {
log.info("消息发送成功: Topic={}, Partition={}, Offset={}",
success.getRecordMetadata().topic(), success.getRecordMetadata().partition(), success.getRecordMetadata().offset());
}
},
failure -> {
log.error("消息发送失败:", failure.getCause());
}
);
}
}
KafkaTemplate 提供了多个 send 方法

我们可以按需选择
上面 3 步都完成后,即可启动应用进行测试了
消费消息
这个测试很简单,直接往
tp_qsl_order_canceltopic 中发送一条消息即可
点击
发送消息后,控制台输出
消息正常消费,没有任何毛病
发送消息
我加了一个
OrderController/**
* @author: 青石路
*/
@RestController
@RequestMapping("order")
public class OrderController { @Resource
private KafkaSender kafkaSender; @GetMapping("add")
public String add(String orderInfo) {
// TODO 订单业务处理
// 下发消息到库存
kafkaSender.send("tp_qsl_inventory_order_add", orderInfo);
return "下单成功";
}
}
便于测试消息发送;直接发起
http请求http://localhost:8080/order/add?orderInfo=订单完整信息
然后就可以去
tp_qsl_inventory_order_addtopic 中看消息是否发送成功
消息正常发送,也没有任何毛病
至此,Spring Boot 集成 Kafka 就算大功告成了;如此简单,相信你们都能轻松拿捏

Kafka 多源
上述只讲了单 Kafka 源的情况,也就是 消费消息 与 发送消息 针对的是同个 Kafka 源;但实际工作中,同个项目连接多个 Kafka 源的情况是非常常见的,我们就以 2 个 Kafka 源为例,从其中一个源消费消息、向另一个源发送消息,该如何实现?其实也不难,按以下几步调整即可
配置文件调整
既然有 2 个 Kafka 源,那么我们的配置文件就需要配置 2 个,类似如下
spring:
kafka:
first:
bootstrap-servers: 192.168.0.87:9092,192.168.0.88:9092,192.168.0.89:9092
consumer:
# 自动提交消费位移
enable-auto-commit: false
# 偏移量初始位置
auto-offset-reset: latest
# 一次拉取记录最大数
max-poll-records: 5
# properties:
# security.protocol: SASL_PLAINTEXT
# sasl.mechanism: PLAIN
#sasl.mechanism: SCRAM-SHA-256
#username、password需要调整成实际值
# sasl.jaas.config: org.apache.kafka.common.security.plain.PlainLoginModule required username="username" password="password";
#sasl.jaas.config: org.apache.kafka.common.security.scram.ScramLoginModule required username="username" password="password";
listener:
ack-mode: manual
second:
bootstrap-servers: 192.168.0.90:9092
#producer:
#properties:
#security.protocol: SASL_PLAINTEXT
#sasl.mechanism: PLAIN
#sasl.mechanism: SCRAM-SHA-256
#username、password需要调整成实际值
#sasl.jaas.config: org.apache.kafka.common.security.plain.PlainLoginModule required username="username" password="password";
#sasl.jaas.config: org.apache.kafka.common.security.scram.ScramLoginModule required username="username" password="password";
这里的
first和second不是固定的,你们想怎么命名就怎么命名;既然这么灵活,那 Spring Boot 肯定是不支持的,那么如上配置,Spring Boot 是识别不了的,相当于没配,此时去启动应用,Spring Boot 会启用默认配置去连接localhost:9092
所以我们需要自定义配置 Kafka,而一旦我们进行了自定义,那么 Spring Boot 则不会启用默认配置
自定义配置 Kafka
针对每个 Kafka 源单独配置,配置内容比较固定
FirstKafkaConfig
/**
* 第一个Kafka配置
* @author: 青石路
*/
@Configuration
public class FirstKafkaConfig { @ConfigurationProperties(prefix = "spring.kafka.first")
@Bean("firstKafkaProperties")
public KafkaProperties firstKafkaProperties() {
return new KafkaProperties();
} @Bean("firstKafkaTemplate")
public KafkaTemplate<String, String> firstKafkaTemplate() {
return new KafkaTemplate<>(firstProducerFactory());
} @Bean("firstKafkaListenerContainerFactory")
public KafkaListenerContainerFactory<ConcurrentMessageListenerContainer<String, String>> fisrtKafkaListenerContainerFactory() {
ConcurrentKafkaListenerContainerFactory<String, String> factory = new ConcurrentKafkaListenerContainerFactory<>();
factory.setConsumerFactory(firstConsumerFactory());
factory.getContainerProperties().setAckMode(firstKafkaProperties().getListener().getAckMode());
return factory;
} @Bean("firstConsumerFactory")
public ConsumerFactory<String, String> firstConsumerFactory() {
return new DefaultKafkaConsumerFactory<>(firstKafkaProperties().buildConsumerProperties());
} @Bean("firstProducerFactory")
public DefaultKafkaProducerFactory<String, String> firstProducerFactory() {
return new DefaultKafkaProducerFactory<>(firstKafkaProperties().buildProducerProperties());
}
}
SecondKafkaConfig
/**
* 第二个Kafka配置
* @author: 青石路
*/
@Configuration
public class SecondKafkaConfig { @ConfigurationProperties(prefix = "spring.kafka.second")
@Bean("secondKafkaProperties")
public KafkaProperties secondKafkaProperties() {
return new KafkaProperties();
} @Bean("secondKafkaTemplate")
public KafkaTemplate<String, String> secondKafkaTemplate() {
return new KafkaTemplate<>(secondProducerFactory());
} @Bean("secondKafkaListenerContainerFactory")
public KafkaListenerContainerFactory<ConcurrentMessageListenerContainer<String, String>> fisrtKafkaListenerContainerFactory() {
ConcurrentKafkaListenerContainerFactory<String, String> factory = new ConcurrentKafkaListenerContainerFactory<>();
factory.setConsumerFactory(secondConsumerFactory());
return factory;
} @Bean("secondConsumerFactory")
public ConsumerFactory<String, String> secondConsumerFactory() {
return new DefaultKafkaConsumerFactory<>(secondKafkaProperties().buildConsumerProperties());
} @Bean("secondProducerFactory")
public DefaultKafkaProducerFactory<String, String> secondProducerFactory() {
return new DefaultKafkaProducerFactory<>(secondKafkaProperties().buildProducerProperties());
}
}
重点在
@ConfigurationProperties(prefix = "spring.kafka.first")
@ConfigurationProperties(prefix = "spring.kafka.second")
多源之间不要配重、不要配混
调整消息监听与消息发送
因为配置了多源,那么
KafkaListenerContainerFactory也对应配置了多个,所以我们要指定用哪个 KafkaListenerContainerFactory 来创建消息监听器@KafkaListener(topics = "tp_qsl_order_cancel", groupId = "gid_qsl_order_cancel") // 调整成 @KafkaListener(topics = "tp_qsl_order_cancel", groupId = "gid_qsl_order_cancel", containerFactory = "firstKafkaListenerContainerFactory")
消费消息端就算调整完成;同理,KafkaTemplate也配置了多个,那么发送消息的时候也需要指定用哪个 KafkaTemplate 来发送@Resource
private KafkaTemplate<String, String> kafkaTemplate; // 调整成 private KafkaTemplate<String, String> kafkaTemplate;
@Autowired
@Qualifier("secondKafkaTemplate")
public void setKafkaTemplate(KafkaTemplate<String, String> kafkaTemplate) {
this.kafkaTemplate = kafkaTemplate;
}
发送消息端也就调整完成
都调整完成后,我们启动应用,会发现启动失败,并提示如下信息

这特喵的,跟预想的不一样吖

遇到问题先不要慌,我们仔细看下提示信息,我给你们翻译一下
KafkaAnnotationDrivenConfiguration 构造方法需要一个 KafkaProperties 实例,但在 Spring 容器中找到了 3 个,它懵圈了,不知道该使用哪一个
可以通过 @Primary 提高实例的优先级,或者使用 @Qualifier 明确指定使用哪个实例
所以处理方式就来了,使用 @Primary 来提高某个 KafkaProperties 实例的优先级,KafkaAnnotationDrivenConfiguration 就不会懵圈了,会使用优先级高的 KafkaProperties 实例
因为 KafkaAnnotationDrivenConfiguration 不是我们写的,没法通过 @Qualifier 明确指定
我们直接提高 firstKafkaProperties 的优先级
@ConfigurationProperties(prefix = "spring.kafka.first")
@Bean("firstKafkaProperties")
@Primary
public KafkaProperties firstKafkaProperties() {
return new KafkaProperties();
}
再启动应用,发现正常启动了;你们就可以进行 消费消息 和 发送消息 测试了,我就不演示了,反正我测试都是通过的,不信?不信就不信,你能把我怎么样嘛

启停配置化
Kafka 不管是单源还是多源,应用进行集成,都是非常合理的需求,我们开发做对应的实现也是应该的;但如下这个需求我多少是有点抵触的
客户方的环境有诸多约束、限制,权限管控非常严,还有各种防火墙,需要各种申请流程,非常耗时;项目分多个应用,应用之间存在交互(Kafka 是方式之一),每个应用的交付时间不一样,自然在客户环境的演示时间也不一样,所以为了演示不受 Kafka 的限制,需要给每个 Kafka 源增加一个开关配置,通过开关来分别控制每个 Kafka 源的启停
这里的启停指的是 启用 与 停用;演示的时候,哪些 Kafka 源能正常使用就启用这些,哪些还不能使用就停用哪些,同时业务代码中也需要做适配调整。面对这个需求,你们说是不是不合理?所以你们能理解我的抵触了吧。但为了更好的演示,给甲方爸爸留下专业的印象,增加开关貌似是当下最合适的无奈之选,极不情愿的开启改造之旅

增加开关配置
在配置文件中增加开关配置,每个 Kafka 源有其独立的配置,有几个源就配置几个开关
spring:
kafka:
first:
enabled: true
...
second:
enabled: true
...
enabled配置成true表示启用,false表示停用自定义配置适配开关
需要根据开关值来决定是否启用
FirstKafkaConfig和SecondKafkaConfig,Spring Boot 正好提供了一个具有该功能的注解:ConditionalOnProperty,直接安排上/**
* 第一个Kafka配置
* @author: 青石路
*/
@Configuration
@ConditionalOnProperty(name = "spring.kafka.first.enabled", havingValue = "true")
public class FirstKafkaConfig {
... /**
* 第二个Kafka配置
* @author: 青石路
*/
@Configuration
@ConditionalOnProperty(name = "spring.kafka.second.enabled", havingValue = "true")
public class SecondKafkaConfig {
...
这样就实现了通过开关来
启停Kafka 源消费消息与发送消息适配开关
消费端适配很简单
/**
* @author: 青石路
*/
@Component
@ConditionalOnProperty(name = "spring.kafka.first.enabled", havingValue = "true")
public class KafkaConsumer {
...
发送端适配则有点不一样,方式有多种,我提供一种;修改 KafkaSender,改 2 处即可
KafkaTemplate 调整成非强制依赖,将
@Autowired的required设置成 false@Autowired
@Qualifier("secondKafkaTemplate")
public void setKafkaTemplate(KafkaTemplate<String, String> kafkaTemplate) {
this.kafkaTemplate = kafkaTemplate;
} // 调整成 @Autowired(required = false)
@Qualifier("secondKafkaTemplate")
public void setKafkaTemplate(KafkaTemplate<String, String> kafkaTemplate) {
this.kafkaTemplate = kafkaTemplate;
}
使用 KafkaTemplate 时做 null 判断
public void send(String topic, String msg) {
kafkaTemplate.send(topic, msg).addCallback(
success -> {
if (success != null) {
log.info("消息发送成功: Topic={}, Partition={}, Offset={}",
success.getRecordMetadata().topic(), success.getRecordMetadata().partition(), success.getRecordMetadata().offset());
}
},
failure -> {
log.error("消息发送失败:", failure.getCause());
}
);
} // 调整成 public void send(String topic, String msg) {
if (kafkaTemplate == null) {
log.warn("未启用secondKafka,不发送消息");
return;
}
kafkaTemplate.send(topic, msg).addCallback(
success -> {
if (success != null) {
log.info("消息发送成功: Topic={}, Partition={}, Offset={}",
success.getRecordMetadata().topic(), success.getRecordMetadata().partition(), success.getRecordMetadata().offset());
}
},
failure -> {
log.error("消息发送失败:", failure.getCause());
}
);
}
至此改造就算完成;开关都为 true 的情况下,效果与未加开关前的多源是一致的,也就是正常的,我已经测过了,你们不放心的话自己再去测试一下;开关都为 false 时,相当于没注册消费监听器,也就相当于没有消费者,那么往 tp_qsl_order_cancel topic 中发消息,是没有消费者消费消息的,那么控制台就不会有任何输出,同理,此时的 KafkaTemplate 是没有注册成功的(也就是 null),发起 http 请求
http://localhost:8080/order/add?orderInfo=大订单
控制台输出如下

正是我们想要的效果,说明都为 false 的情况也是正确的;接下来我们看下 false、true 的情况

好家伙,直接启动失败!但这个问题我们前面碰到过,那么如何处理呢?用 @Primary 标记 secondKafkaProperties ?假设我们这么做了,那开关都为 true 的情况下,KafkaProperties 实例岂不是有多个 Primary,Spring Boot 又会懵圈,不知道该使用哪个 KafkaProperties 实例,显然这种方式行不通;我们把问题拓展下,多个 KafkaProperties 实例存在的情况下,需要动态指定一个 Primary,但不能是 Spring Boot 自动配置的那个,即
spring.kafka-org.springframework.boot.autoconfigure.kafka.KafkaProperties
除了这个,随便给哪个 KafkaProperties 实例指定成 Primary 都是没问题的,因为我们的业务代码中都明确指定了使用的是我们自定义的 kafka,所以我们需要在 Bean 实例化之前修改某个 KafkaProperties 的 BeanDefinition,设置其 Primary 为 true;实现方式有很多,我这里提供一种:BeanFactoryPostProcessor
/**
* @author: 青石路
*/
@Component
public class KafkaPrimaryProcessor implements BeanFactoryPostProcessor {
private static final Logger log = LoggerFactory.getLogger(KafkaPrimaryProcessor.class);
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
String[] beanNames = beanFactory.getBeanNamesForType(KafkaProperties.class);
if (beanNames.length <= 1) {
return;
}
for (String beanName : beanNames) {
BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName);
// springboot的自动配置
if (beanName.contains(KafkaProperties.class.getName())) {
continue;
}
log.info("多KafkaProperties,指定primary[{}]", beanName);
beanDefinition.setPrimary(true);
return;
}
}
}
这个代码相信你们都能看懂,会从多个 KafkaProperties BeanDefinition 中取第一个(除了自动配置的),设置其 Primary 为 true,所以我们还需要调整下 firstKafkaProperties,拿掉其 @Primary
@ConfigurationProperties(prefix = "spring.kafka.first")
@Bean("firstKafkaProperties")
@Primary
public KafkaProperties firstKafkaProperties() {
return new KafkaProperties();
}
// 调整成
@ConfigurationProperties(prefix = "spring.kafka.first")
@Bean("firstKafkaProperties")
public KafkaProperties firstKafkaProperties() {
return new KafkaProperties();
}
这么调整之后,无论是有几个 Kafka 源,以及如何启停这些源,都能正常运转,是不是很优秀,值得鼓掌!

话说,需求至此已经算完美实现了,可以完结了,但作为一个开发,尤其是一个有追求的开发,还有一个疑点未得到解决,心里始终不舒坦,是什么疑点呢,我们继续往下看
排除自动配置
既然是我们自定义配置 Kafka,不再依赖 Spring Boot 的自动配置,我们是不是可以排除掉 Spring Boot 的 Kafka 自动配置?理论上来说是可行的,那就干呗;直接排除掉 KafkaAutoConfiguration.class
/**
* @author: 青石路
*/
@SpringBootApplication(exclude = {KafkaAutoConfiguration.class})
public class KafkaApplication {
public static void main(String[] args) {
SpringApplication.run(KafkaApplication.class, args);
}
}
既然排除了自动配置,那么也就不需要指定 KafkaProperties 的 Primary 了,KafkaPrimaryProcessor 直接删掉,其他不用调整;将开关都设置成 true,我们启动应用后测试下
发送消息
直接 http 请求
http://localhost:8080/order/add?orderInfo=排除自动配置
日志显示发送成功

我们在看下 Topic
tp_qsl_inventory_order_add中消息
发送消息是没问题的
消费消息
往 Topic
tp_qsl_order_cancel中发送消息
点击
发送消息后,发现控制台并没有任何输出!!!
先别慌,我们冷静分析下,控制台没有任何输出说明消费者没注册成功,也就是
@KafkaListener没生效,为什么没生效,肯定是没有被解析,谁解析它呢,KafkaListener 中应该有说明
已经描述的很清楚
通过注册 KafkaListenerAnnotationBeanPostProcessor 来处理 KafkaListener 注解
可以手动注册 KafkaListenerAnnotationBeanPostProcessor,也可以通过 EnableKafka 注解来注册
EnableKafka方便点,我们使用它/**
* @author: 青石路
*/
@SpringBootApplication(exclude = {KafkaAutoConfiguration.class})
@EnableKafka
public class KafkaApplication { public static void main(String[] args) {
SpringApplication.run(KafkaApplication.class, args);
}
}
重新启动应用,会发现控制台有如下输出

消费消息也正常了;因为重启应用了,保险起见,发送消息最好再测一次,记得测!!!
至此,心中疑点得以解决,如此才算完美解决!

Tips:
跟进 KafkaAutoConfiguration,它有如下代码
@Import({ KafkaAnnotationDrivenConfiguration.class, KafkaStreamsAnnotationDrivenConfiguration.class })
跟进 KafkaAnnotationDrivenConfiguration,其最下面有如下代码
@Configuration(proxyBeanMethods = false)
@EnableKafka
@ConditionalOnMissingBean(name = KafkaListenerConfigUtils.KAFKA_LISTENER_ANNOTATION_PROCESSOR_BEAN_NAME)
static class EnableKafkaConfiguration { }
这里使用了
@EnableKafka,这也是为什么自动配置(KafkaAutoConfiguration)能解析@KafkaListener的答案!
总结
Kafka 多源实现,大家需要掌握,至于启停配置化,大家就当看个热闹
但是启停配置化的实现(
@ConditionalOnProperty),还是值得大家掌握的Spring Boot 的条件注解非常多,在 Spring Boot 内部被广泛使用,感兴趣的可以查看:spring-boot-2.0.3源码篇 - @Configuration、Condition与@Conditional
如果不使用Spring Boot的自动配置,建议把对应的自动配置类排除掉
自动配置与手动配置同时存在的话可能会产生冲突,就像文中的KafkaProperties多实例;直接排除可能会导致缺少某些功能,肯定是没有启用这些功能的依赖,细心去寻找依赖并启用即可完整代码:spring-boot-kafka
SpringBoot支持Kafka多源配置的同时还要支持启停配置化,是真的会玩的更多相关文章
- SpringBoot原理深入及源码剖析(一) 依赖管理及自动配置
前言 传统的Spring框架实现一个Web服务需要导入各种依赖jar包,然后编写对应的XML配置文件等,相较而言,SpringBoot显得更加方便.快捷和高效.那么,SpringBoot究竟是如何做到 ...
- 从SpringBoot启动,阅读源码设计
目录 一.背景说明 二.SpringBoot工程 三.应用上下文 四.资源加载 五.应用环境 六.Bean对象 七.Tomcat服务 八.事件模型 九.配置加载 十.数据库集成 十一.参考源码 服务启 ...
- SpringBoot系列八:SpringBoot整合消息服务(SpringBoot 整合 ActiveMQ、SpringBoot 整合 RabbitMQ、SpringBoot 整合 Kafka)
声明:本文来源于MLDN培训视频的课堂笔记,写在这里只是为了方便查阅. 1.概念:SpringBoot 整合消息服务 2.具体内容 对于异步消息组件在实际的应用之中会有两类: · JMS:代表作就是 ...
- SpringBoot集成Kafka的实战用法大全
本文是SpringBoot+Kafka的实战讲解,如果对kafka的架构原理还不了解的读者,建议先看一下<大白话kafka架构原理>.<秒懂kafka HA(高可用)>两篇文章 ...
- Kafka Eagle 源码解读
1.概述 在<Kafka 消息监控 - Kafka Eagle>一文中,简单的介绍了 Kafka Eagle这款监控工具的作用,截图预览,以及使用详情.今天笔者通过其源码来解读实现细节.目 ...
- SpringBoot整合Kafka和Storm
前言 本篇文章主要介绍的是SpringBoot整合kafka和storm以及在这过程遇到的一些问题和解决方案. kafka和storm的相关知识 如果你对kafka和storm熟悉的话,这一段可以直接 ...
- SpringBoot入门教程(三)通过properties实现多个数据库环境自动切换配置
前面的文章已经介绍了CentOS部署SpringBoot项目从0到1的详细过程,包括Linux安装ftp.Tomcat以及Java jdk的全部过程.这篇文章主要介绍关于springboot如何通过多 ...
- Springboot学习07-数据源Druid
Springboot学习07-数据源Druid 关键字 Druid 前言 学习笔记 正文 1-Druid是什么 Druid是阿里巴巴开源平台上的一个项目,整个项目由数据库连接池.插件框架和SQL解析器 ...
- SpringBoot系列四:SpringBoot开发(改变环境属性、读取资源文件、Bean 配置、模版渲染、profile 配置)
声明:本文来源于MLDN培训视频的课堂笔记,写在这里只是为了方便查阅. 1.概念 SpringBoot 开发深入 2.具体内容 在之前已经基本上了解了整个 SpringBoot 运行机制,但是也需要清 ...
- 配置阿里云ECS支持IPv6,解决苹果app审核失败问题
前几天iOS的App提交给苹果审核没通过,给出的原因是:该应用在 IPv6 的环境下无法使用.检查发现:阿里云优化过的系统没有启用IPv6协议,需要配置启用一下,但是只单独启用IPv6也是无法直接提供 ...
随机推荐
- 2022年第十八届 GOPS 全球运维大会资料分享
全球运维大会是国内第一个运维行业大会,面向互联网.金融.通信及传统行业广大运维技术人员,旨在传播先进技术思想和理念,分享业内最佳实践. 2022年第十八届 GOPS 全球运维大会(深圳站)共分为18个 ...
- ⼯作中有做过数据处理吗? tree 组件 根据 pid 寻找父节点
主要是在组件和后端返回的数据之间,或者组件产⽣的数据和需要提交给后端的数据之间,有可能会出 现结构对不上,这个时候可能会处理⼀下,举个例⼦,⽐如说我们常⽤的tree型组件要求必须是嵌套的 tree型数 ...
- KubeSphere 社区双周报 | KubeKey 新增网络插件 Hybridnet | 2023.08.18-08.31
KubeSphere 社区双周报主要整理展示新增的贡献者名单和证书.新增的讲师证书以及两周内提交过 commit 的贡献者,并对近期重要的 PR 进行解析,同时还包含了线上/线下活动和布道推广等一系列 ...
- 云原生爱好者周刊:VMware Tanzu 社区办发布,无任何限制!
云原生一周动态要闻: VMware Tanzu 推出社区版 Kubernetes Cluster API 1.0 版已生产就绪 Linkerd 2.11 发布 Cartografos 工作组推出云原生 ...
- 新东方在有状态服务 In K8s 的实践
作者|周培,新东方架构部容器组专家 有状态服务建设一直以来都是 K8s 中非常具有挑战性的工作,新东方在有状态服务云化过程中,采用定制化 Operator 与自研本地存储服务结合的模式,增强了 K8s ...
- 带你一起看看nginx如何部署安装
nginx部署安装 Linux安装 源码构建Nginx 管理器安装 windows安装 首先需要下载Nginx软件包 nginx软件官方下载地址: nginx官方下载连接 建议选择稳定的软件版本,如果 ...
- 如何优雅地将AI人工智能在线客服嵌入企业网站
随着人工智能(AI)技术的飞速发展,越来越多的企业意识到,将AI客服嵌入企业网站是提升客户体验.提高工作效率的重要手段.相比于传统的人工客服,AI客服可以24/7全天候服务,不仅能有效处理大部分用户问 ...
- 正态分布——“牛而B之”
1 问题: 什么是正态分布,为什么这么出名和重要? 1.1 名气大 为什么叫"正态分布",也有地方叫"常态分布",这两个名字都不太直观,但如果我们各取一字变为& ...
- docker的使用-01配置国内镜像仓库提高加快拉取镜像的速度
docker的使用-01配置国内镜像仓库提高加快拉取镜像的速度 我的docker版本:(win10专业版,安装的当前最新版docker desktop) docker --version Docker ...
- centos7系统安装部署zabbix5.0
一.简介 zabbix是一个基于[WEB]界面的提供分布式[系统监视]以及网络监视功能的企业级的开源解决方案.zabbix能监视各种网络参数,保证[服务器系统]的安全运营:并提供灵活的通知机制以让[系 ...