使用 @EmbeddedKafka 时执行 @DirtiesConfig 的正确方法是什么

2024-04-20

我们的项目中有一个“小”问题:“无法建立与节点 0 的连接。代理可能不可用。”测试运行非常非常长的时间,并且该消息每秒至少记录一次。但我发现,如何摆脱它。请继续阅读。如果配置/注释有不正确的地方,请告诉我。

版本优先:

<springframework.boot.version>2.1.8.RELEASE</springframework.boot.version>

这会自动带来

<spring-kafka.version>2.2.8.RELEASE</spring-kafka.version>

现在我们将考虑这个集成测试,注释为:

@RunWith(SpringRunner.class)
@Import(/*some our configuration, irrelevant*/ )
@ActiveProfiles(/*some our profiles, irrelevant*/)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@EmbeddedKafka(controlledShutdown = true)
@Transactional

然后我们进行一些测试,例如:

@Test
@DirtiesContext

public void testPostWhatever() throws JSONException, IOException {

该测试只是创建一些请求数据,调用 post,然后将数据保存到数据库中。然后我们将使用 GET 来查找是否可以找到这些数据。琐碎的。对我来说有点奇怪的是这里的事务处理。测试类使用 @Transactional 进行注释,但根据日志,事务仅在 Controller 方法上打开,在本示例中(当然应该在服务上)具有相同的 @Transactional 注释。两者都具有 TxType.REQUIRED 传播。这将导致测试发起的回滚实际上不会回滚任何内容,因为事务已经提交。如果您知道为什么会这样,请指教。但这不是这个问题的关键。到目前为止,我们只是将 @DirtiesContext 放在这个方法上,它应该只是重新初始化上下文。它解决了数据未回滚的问题,但上下文重新初始化的成本很高。但以下消息开始出现在日志中:

2019-10-01 13:49:07.336 org.apache.kafka.clients.NetworkClient   : [Producer clientId=producer-2] Connection to node 0 could not be established. Broker may not be available.
2019-10-01 13:49:07.699 org.apache.kafka.clients.NetworkClient   : [Producer clientId=producer-1] Connection to node 0 could not be established. Broker may not be available.
2019-10-01 13:49:08.191 org.apache.kafka.clients.NetworkClient   : [Producer clientId=producer-2] Connection to node 0 could not be established. Broker may not be available.
2019-10-01 13:49:08.603 org.apache.kafka.clients.NetworkClient   : [Producer clientId=producer-1] Connection to node 0 could not be established. Broker may not be available.
2019-10-01 13:49:08.927 o.a.c.loader.WebappClassLoaderBase       : The web application [ofs] appears to have started a thread named [kafka-producer-network-thread | producer-2] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
 sun.nio.ch.EPollArrayWrapper.epollWait(Native Method)
 sun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.java:269)
 sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:93)
 sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:86)
 sun.nio.ch.SelectorImpl.select(SelectorImpl.java:97)
 org.apache.kafka.common.network.Selector.select(Selector.java:691)
 org.apache.kafka.common.network.Selector.poll(Selector.java:411)
 org.apache.kafka.clients.NetworkClient.poll(NetworkClient.java:510)
 org.apache.kafka.clients.producer.internals.Sender.run(Sender.java:239)
 org.apache.kafka.clients.producer.internals.Sender.run(Sender.java:163)
 java.lang.Thread.run(Thread.java:748)

删除这个@DirtiesContext并将其放在班级级别,例如

@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)

具有相同的行为(除了荒谬的额外开销)。但是,如果我删除所有@DirtiesContext,并手动清除数据库并提交更改,以便在每次测试后恢复更改,一切都会正常工作,没有警告或错误。

所以我认为有两件事。我的问题是由不正确的 tx 处理引起的(请帮助),但是 @DirtiesContext 也应该可以与 spring-kafka 一起使用,并且seems不工作。要么原则上不可能(或者确实如此?),要么我配置不正确(请帮助),或者它可能是一个错误?


如果您使用的是 JUnit4,则可以使用EmbeddedKafkaRule as a @ClassRule而不是使用@EmbeddedKafka然后代理就不会添加到上下文中。

不幸的是,JUnit 5 没有等效的东西 - 但您仍然可以添加静态EmbeddedKafkaBroker并亲自摧毁它@AfterAll method.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 @EmbeddedKafka 时执行 @DirtiesConfig 的正确方法是什么 的相关文章

随机推荐