2

我们的项目中有一个“小”问题:“无法建立到节点 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,然后将数据持久化到 DB 中。然后我们将使用 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 一起使用,这似乎不起作用。原则上不可能(或者是?),或者我的某些配置不正确(请帮助),或者它可能是一个错误?

4

1 回答 1

0

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

不幸的是,JUnitt5 没有等价物 - 但您仍然可以添加一个静态并在方法EmbeddedKafkaBroker中自己销毁它。@AfterAll

于 2019-10-01T14:51:54.733 回答