Спасибо за ваше терпение; Я воспроизвел его.
Это ошибка https://github.com/spring-projects/spring-integration/issues/3199
РЕДАКТИРОВАТЬ
Новые свойства для управления этим поведением:
/**
* When using a shared connection {@link #setSingleUse(boolean) singleUse} is false,
* specify how long to wait before trying to fail back to start from the beginning of
* the factory list. Default is 0 for backwards compatibility to always try to get a
* connection to the primary server. If you don't want to fail back until the current
* connection is closed, set this to {@link Long#MAX_VALUE}.
* Cannot be changed when using {@link CachingClientConnectionFactory} delegates.
* @param refreshSharedInterval the interval in milliseconds.
* @since 4.3.22
* @see #setSingleUse(boolean)
* @see #setCloseOnRefresh(boolean)
*/
public void setRefreshSharedInterval(long refreshSharedInterval) {
Assert.isTrue(!this.cachingDelegates,
"'refreshSharedInterval' cannot be changed when using 'CachingClientConnectionFactory` delegates");
this.refreshSharedInterval = refreshSharedInterval;
}
/**
* When using a shared connection {@link #setSingleUse(boolean) singleUse} is false,
* set this to true to close the old shared connection after a refresh. If this is
* false, the connection will remain open, but unused until its connection factory is
* again used to get a connection. Default is false for backwards compatibility.
* Cannot be changed when using {@link CachingClientConnectionFactory} delegates.
* @param closeOnRefresh true to close.
* @since 4.3.22
* @see #setSingleUse(boolean)
* @see #setRefreshSharedInterval(long)
*/
public void setCloseOnRefresh(boolean closeOnRefresh) {
Assert.isTrue(!this.cachingDelegates,
"'closeOnRefresh' cannot be changed when using 'CachingClientConnectionFactory` delegates");
this.closeOnRefresh = closeOnRefresh;
}
EDIT2
Помимо модульных тестов , я протестировал исправление с приложением, которое написал, чтобы воспроизвести вашу проблему:
@SpringBootApplication
@EnableScheduling
public class So60432039Application {
public static void main(String[] args) {
SpringApplication.run(So60432039Application.class, args);
}
@Bean
public AbstractServerConnectionFactory server1() {
TcpNetServerConnectionFactory factory = new TcpNetServerConnectionFactory(1234);
factory.registerListener(m -> {
System.out.println("1:" + m.getPayload());
return false;
});
return factory;
}
@Bean
public AbstractServerConnectionFactory server2() {
TcpNetServerConnectionFactory factory = new TcpNetServerConnectionFactory(1235);
factory.registerListener(m -> {
System.out.println("2:" + m.getPayload());
return false;
});
return factory;
}
@Bean
public AbstractClientConnectionFactory client1() {
return new TcpNetClientConnectionFactory("localhost", 1234);
}
@Bean
public AbstractClientConnectionFactory client2() {
return new TcpNetClientConnectionFactory("localhost", 1235);
}
@Bean
public FailoverClientConnectionFactory failover() {
FailoverClientConnectionFactory factory =
new FailoverClientConnectionFactory(Arrays.asList(client1(), client2()));
factory.registerListener(m -> false);
factory.setRefreshSharedInterval(15_000);
factory.setCloseOnRefresh(true);
return factory;
}
@Scheduled(fixedDelay = 5_000, initialDelay = 5_000)
public void getConnection() throws Exception {
try {
TcpConnectionSupport connection = failover().getConnection();
connection.send(new GenericMessage<>("foo"));
System.out.println(connection.getConnectionId());
}
catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
catch (RuntimeException e) {
System.out.println(e.getMessage());
}
}
@Bean
public ApplicationRunner runner() {
return args -> {
client1().start();
client2().start();
failover().start();
System.out.println("Hit enter to start server2");
System.in.read();
server2().start();
System.out.println("Hit enter to start server1");
System.in.read();
server1().start();
System.out.println("Hit enter to stop server1");
System.in.read();
server1().stop();
};
}
}
logging.level.org.springframework.integration.ip.tcp.connection.TcpNetClientConnectionFactory=debug
logging.level.org.springframework.integration.ip.tcp.connection.FailoverClientConnectionFactory$FailoverTcpConnection=debug
С factory.setRefreshSharedInterval(15_000);
на месте; Я получаю:
Hit enter to start server2
<enter>
2020-03-03 09:23:36.065 INFO 78635 --- [ main] .s.i.i.t.c.TcpNetServerConnectionFactory : started server2, port=1235
Hit enter to start server1
2020-03-03 09:23:36.066 INFO 78635 --- [pool-1-thread-1] .s.i.i.t.c.TcpNetServerConnectionFactory : server2, port=1235 Listening
2020-03-03 09:23:38.690 DEBUG 78635 --- [ask-scheduler-2] .s.i.i.t.c.TcpNetClientConnectionFactory : Opening new socket connection to localhost:1234
2020-03-03 09:23:38.695 DEBUG 78635 --- [ask-scheduler-2] tConnectionFactory$FailoverTcpConnection : client1, host=localhost, port=1234 failed with java.net.ConnectException: Connection refused (Connection refused), trying another
2020-03-03 09:23:38.695 DEBUG 78635 --- [ask-scheduler-2] .s.i.i.t.c.TcpNetClientConnectionFactory : Opening new socket connection to localhost:1235
2020-03-03 09:23:38.697 DEBUG 78635 --- [ask-scheduler-2] .s.i.i.t.c.TcpNetClientConnectionFactory : client2: Added new connection: localhost:1235:52647:f370c7e4-2455-4114-9c7a-55bd38f728cf
2020-03-03 09:23:38.698 DEBUG 78635 --- [ask-scheduler-2] tConnectionFactory$FailoverTcpConnection : Got localhost:1235:52647:f370c7e4-2455-4114-9c7a-55bd38f728cf from client2, host=localhost, port=1235
2053c07b-3d7c-4ac0-8b46-1e2f703fa6a9:1
2:[B@7d7d9ef3
2053c07b-3d7c-4ac0-8b46-1e2f703fa6a9:2
2:[B@3316e0a4
2053c07b-3d7c-4ac0-8b46-1e2f703fa6a9:3
2:[B@2dae23bc
Закомментировав это, я получаю старое поведение:
Hit enter to start server2
<enter>
2020-03-03 09:25:45.143 INFO 79176 --- [ main] .s.i.i.t.c.TcpNetServerConnectionFactory : started server2, port=1235
Hit enter to start server1
2020-03-03 09:25:45.144 INFO 79176 --- [pool-1-thread-1] .s.i.i.t.c.TcpNetServerConnectionFactory : server2, port=1235 Listening
2020-03-03 09:25:47.363 DEBUG 79176 --- [ask-scheduler-2] .s.i.i.t.c.TcpNetClientConnectionFactory : Opening new socket connection to localhost:1234
2020-03-03 09:25:47.368 DEBUG 79176 --- [ask-scheduler-2] tConnectionFactory$FailoverTcpConnection : client1, host=localhost, port=1234 failed with java.net.ConnectException: Connection refused (Connection refused), trying another
2020-03-03 09:25:47.368 DEBUG 79176 --- [ask-scheduler-2] .s.i.i.t.c.TcpNetClientConnectionFactory : Opening new socket connection to localhost:1235
2020-03-03 09:25:47.369 DEBUG 79176 --- [ask-scheduler-2] .s.i.i.t.c.TcpNetClientConnectionFactory : client2: Added new connection: localhost:1235:52775:31caf4d1-0fd1-49bf-8be6-f9fa935bd8a0
2020-03-03 09:25:47.371 DEBUG 79176 --- [ask-scheduler-2] tConnectionFactory$FailoverTcpConnection : Got localhost:1235:52775:31caf4d1-0fd1-49bf-8be6-f9fa935bd8a0 from client2, host=localhost, port=1235
618d04e0-aa3a-4bac-966c-982d93528dd9:1
2:[B@47858489
2020-03-03 09:25:52.373 DEBUG 79176 --- [ask-scheduler-1] .s.i.i.t.c.TcpNetClientConnectionFactory : Opening new socket connection to localhost:1234
2020-03-03 09:25:52.374 DEBUG 79176 --- [ask-scheduler-1] tConnectionFactory$FailoverTcpConnection : client1, host=localhost, port=1234 failed with java.net.ConnectException: Connection refused (Connection refused), trying another
2020-03-03 09:25:52.374 DEBUG 79176 --- [ask-scheduler-1] tConnectionFactory$FailoverTcpConnection : Got localhost:1235:52775:31caf4d1-0fd1-49bf-8be6-f9fa935bd8a0 from client2, host=localhost, port=1235
51b1c8ab-15c6-4108-acb7-b34584bf8506:1
2:[B@79bc08ef
2020-03-03 09:25:57.378 DEBUG 79176 --- [ask-scheduler-2] .s.i.i.t.c.TcpNetClientConnectionFactory : Opening new socket connection to localhost:1234
2020-03-03 09:25:57.378 DEBUG 79176 --- [ask-scheduler-2] tConnectionFactory$FailoverTcpConnection : client1, host=localhost, port=1234 failed with java.net.ConnectException: Connection refused (Connection refused), trying another
2020-03-03 09:25:57.379 DEBUG 79176 --- [ask-scheduler-2] tConnectionFactory$FailoverTcpConnection : Got localhost:1235:52775:31caf4d1-0fd1-49bf-8be6-f9fa935bd8a0 from client2, host=localhost, port=1235
3c49c6f7-fe6a-410b-acff-cfa20aba42b1:1
2:[B@774d8ab2
EDIT3
Вот пом
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.22.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>so60432039</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>so60432039</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-integration</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-ip</artifactId>
<version>4.3.22.BUILD-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>