FailoverClientConnectionFactory:已与故障转移服务器连接,但仍尝试与主服务器连接

时间:2020-02-27 11:16:27

标签: spring-integration

如果主服务器和故障转移服务器之间的连接断开也无法建立,则出现问题。经过一段时间的故障转移服务器启动,并通过服务器故障转移成功建立连接。但是它仍然尝试与主服务器连接,这是否是所需的行为?

连接工厂的代码段:

列出processServers = mConfigurationService.getProcessServers(); 列出工厂=新的ArrayList <>();

        for (ServerInfo serverInfo : processServers) 
        {
            AbstractClientConnectionFactory clientFactory = new TcpNetClientConnectionFactory(
                    serverInfo.getServerAddress(), serverInfo.getServerPort());
            clientFactory.setApplicationEventPublisher(this.applicationEventPublisher);             
            clientFactory.setSingleUse(false);
            clientFactory.setDeserializer(mMessageSerializerDeserializer);
            clientFactory.setSerializer(mMessageSerializerDeserializer);
            factories.add(clientFactory);
        }

        failoverCF = new FailoverClientConnectionFactory(factories);
        failoverCF.setSingleUse(false);
        failoverCF.afterPropertiesSet();

以下是日志,我们可以在其中找到与10.90.x.F建立的连接,但仍尝试与10.90.x.P建立连接。

2020-02-27 16:33:53 [task-scheduler-10]调试 o.s.i.i.t.c.TcpNetClientConnectionFactory-打开新套接字 连接到10.90.x.P:42027 2020-02-27 16:33:53 [task-scheduler-2] 调试 o.s.i.i.t.c.FailoverClientConnectionFactory $ FailoverTcpConnection- org.springframework.integration.ip.tcp.connection.TcpNetClientConnectionFactory@4946485c, host = 10.90.x.P,port = 42027失败,并出现java.net.ConnectException: 连接超时:连接,尝试另一个2020-02-27 16:33:53 [task-scheduler-2]调试 o.s.i.i.t.c.FailoverClientConnectionFactory $ FailoverTcpConnection- 得到了 10.90.x.F:42027:65437:1f582e09-eb9a-4966-8fd2-60cb156ad015 从 org.springframework.integration.ip.tcp.connection.TcpNetClientConnectionFactory@1df06ecd, 主机= 10.90.x.F,端口= 42027 2020-02-27 16:33:53 [task-scheduler-2] 调试o.s.i.i.t.c.ClientModeConnectionManager-连接 bae635ce-c643-4650-ba15-5fb2fe8af053:1建立了2020-02-27 16:34:14 [task-scheduler-10]调试 o.s.i.i.t.c.FailoverClientConnectionFactory $ FailoverTcpConnection- org.springframework.integration.ip.tcp.connection.TcpNetClientConnectionFactory@4946485c, host = 10.90.x.P,port = 42027失败,并出现java.net.ConnectException: 连接超时:连接,尝试另一个2020-02-27 16:34:14 [task-scheduler-7]调试o.s.i.i.t.c.TcpNetClientConnectionFactory- 打开与10.90.x.P:42027 2020-02-27 16:34:14的新套接字连接 [task-scheduler-10]调试 o.s.i.i.t.c.FailoverClientConnectionFactory $ FailoverTcpConnection- 得到了 10.90.x.F:42027:65437:1f582e09-eb9a-4966-8fd2-60cb156ad015 从 org.springframework.integration.ip.tcp.connection.TcpNetClientConnectionFactory@1df06ecd, 主机= 10.90.x.F,端口= 42027 2020-02-27 16:34:14 [task-scheduler-10] 调试o.s.i.i.tcp.TcpSendingMessageHandler-获得连接 7a451368-13b2-4abf-908e-3cfe0fca2148:1

2020-02-27 16:34:35 [task-scheduler-7]调试 o.s.i.i.t.c.FailoverClientConnectionFactory $ FailoverTcpConnection- org.springframework.integration.ip.tcp.connection.TcpNetClientConnectionFactory@4946485c, host = 10.90.x.P,port = 42027失败,并出现java.net.ConnectException: 连接超时:连接,尝试另一个2020-02-27 16:34:35 [task-scheduler-7]调试 o.s.i.i.t.c.FailoverClientConnectionFactory $ FailoverTcpConnection- 得到了 10.90.x.F:42027:65437:1f582e09-eb9a-4966-8fd2-60cb156ad015 从 org.springframework.integration.ip.tcp.connection.TcpNetClientConnectionFactory@1df06ecd, 主机= 10.90.x.F,端口= 42027

带有示例项目的新日志:

2020-03-04 21:57:39.027  INFO 76636 --- [           main] .s.i.i.t.c.TcpNetServerConnectionFactory : started server2, port=1235
Hit enter to start server1
2020-03-04 21:57:39.029  INFO 76636 --- [pool-1-thread-1] .s.i.i.t.c.TcpNetServerConnectionFactory : server2, port=1235 Listening
2020-03-04 21:57:39.081 DEBUG 76636 --- [ask-scheduler-1] .s.i.i.t.c.TcpNetClientConnectionFactory : client2: Added new connection: localhost:1235:52400:26295f67-0ebf-45bd-b7f9-ad7d6a08ffbf
2020-03-04 21:57:39.084 DEBUG 76636 --- [ask-scheduler-1] tConnectionFactory$FailoverTcpConnection : Got localhost:1235:52400:26295f67-0ebf-45bd-b7f9-ad7d6a08ffbf from client2, host=localhost, port=1235
ee1cbb1c-0ae0-49b3-969a-38cf28ed6aea:1
2:[B@53ec43e4
ee1cbb1c-0ae0-49b3-969a-38cf28ed6aea:2
2:[B@1da20d77
ee1cbb1c-0ae0-49b3-969a-38cf28ed6aea:3
2:[B@6acde81
2020-03-04 21:57:54.096 DEBUG 76636 --- [ask-scheduler-3] .s.i.i.t.c.TcpNetClientConnectionFactory : Opening new socket connection to localhost:1234
2020-03-04 21:57:56.102 DEBUG 76636 --- [ask-scheduler-3] tConnectionFactory$FailoverTcpConnection : client1, host=localhost, port=1234 failed with java.net.ConnectException: Connection refused: connect, trying another
2020-03-04 21:57:56.103 DEBUG 76636 --- [ask-scheduler-3] tConnectionFactory$FailoverTcpConnection : Got localhost:1235:52400:26295f67-0ebf-45bd-b7f9-ad7d6a08ffbf from client2, host=localhost, port=1235
8bfe4fab-1931-4565-af56-f162252f972b:1
2:[B@46fd87cc
8bfe4fab-1931-4565-af56-f162252f972b:2
2:[B@77bf1f94

1 个答案:

答案 0 :(得分:0)

感谢您的耐心;我转载了它。

这是一个错误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

除了unit tests之外,我还使用编写用于重现您问题的应用测试了此修复程序:

@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

这是pom

<?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>
相关问题