我正在使用spring-kafka 3.1.6和hazelcast 3.7.4。
关闭我的应用程序时,好像hazelcast在我的kafka使用者面前关闭了。
因此导致错误
nested exception is org.springframework.transaction.CannotCreateTransactionException: Could not open JPA EntityManager for transaction; nested exception is com.hazelcast.core.HazelcastInstanceNotActiveException: Hazelcast instance is not active!; nested exception is org.springframework.transaction.CannotCreateTransactionException: Could not open JPA EntityManager for transaction; nested exception is com.hazelcast.core.HazelcastInstanceNotActiveException: Hazelcast instance is not active!
和
org.apache.kafka.common.errors.WakeupException: null
at org.apache.kafka.clients.consumer.internals.ConsumerNetworkClient.maybeTriggerWakeup(ConsumerNetworkClient.java:422)
at org.apache.kafka.clients.consumer.internals.ConsumerNetworkClient.poll(ConsumerNetworkClient.java:245)
at org.apache.kafka.clients.consumer.internals.ConsumerNetworkClient.poll(ConsumerNetworkClient.java:208)
我的使用者配置了RetryTemplate。
org.springframework.context.support.DefaultLifecycleProcessor Failed to shut down 1 bean with phase value 2147483547 within timeout of 30000: [org.springframework.kafka.config.internalKafkaListenerEndpointRegistry]
有人可以通过让hazelcast等待kafka容器停止来帮助我正常关机吗?
谢谢
修改
KafkaContainer和HazelcastInstance都是由spring处理的bean。
HazelcastInstance是手动创建的(不使用默认的springboot自动配置):
@PreDestroy
public void destroy() {
LOGGER.info("Closing Hazelcast");
Hazelcast.shutdownAll();
}
@Bean
public HazelcastInstance hazelcastInstance() {
LOGGER.debug("Configuring Hazelcast");
Config config = new Config();
...
还有Kafka容器:
@Bean(name = "kafkaListenerContainerFactory")
public ConcurrentKafkaListenerContainerFactory<Key, Value> kafkaListenerContainerFactory() {
ConcurrentKafkaListenerContainerFactory<Key, Value> factory =
new ConcurrentKafkaListenerContainerFactory<>();
factory.setConsumerFactory(new DefaultKafkaConsumerFactory<>(consumerConfigs()));
factory.setRetryTemplate(retryTemplate());
factory.getContainerProperties().setAckOnError(false);
factory.getContainerProperties().setAckMode(AbstractMessageListenerContainer.AckMode.RECORD);
factory.getContainerProperties().setErrorHandler(new DefaultErrorHandler());
return factory;
}
编辑2:
我正在将应用程序复制3次。所有3个副本已同时关闭。
这是1个副本的关机日志历史记录:
1)18:14:54.427“ ContextClosedEvent”春季事件已被组件捕获并记录
2)18:14:54.441 org.apache.kafka.common.errors.WakeupException:null
3)18:14:55.951 com.hazelcast.core.HazelcastInstanceNotActiveException:Hazelcast实例未激活!
4)从18:14:55.951到18:15:23.103重复3)19次
5)18:15:24.441在30000的超时时间内无法关闭1个相位值为2147483547的bean:[org.springframework.kafka.config.internalKafkaListenerEndpointRegistry]
6)18:15:24.537关闭Hazelcast
答案 0 :(得分:1)
如果Kafka消费者bean不直接依赖于Hazelcast bean,则可以使用bean定义的depends-on
属性在bean之间定义一个顺序(在初始化和销毁期间)。喜欢;
<bean id="kafka-consumer" class="KafkaConsumerClassName" depends-on="hazelcast"/>
<bean id="hazelcast" class="HazelcastInstance" />
在这种情况下,将在 Kafka消费者Bean之前创建并初始化Hazelcast bean,并在 Kafka消费者Bean之后销毁它。
请参阅Spring参考手册中的Using depends-on部分。
答案 1 :(得分:0)
这对于基于客户端的安装程序可能是错误的线程,但对于基于嵌入的安装程序来说可能是错误的线程,在这里对我有用。
将此属性设置为false,
hazelcast.shutdownhook.enabled = false
hazelcast.shutdownhook.enabled = true
启用Hazelcast关机钩子线程。启用此功能后, 线程终止Hazelcast实例,而无需等待关机 优雅地。
默认情况下,此设置为true。更多info
帮助我不要强行杀死榛子广播,但我不得不打电话给hazelcastInstance.shutdown()
明确