【问题标题】:How to retry socket server creation with spring-integration?如何使用弹簧集成重试创建套接字服务器?
【发布时间】:2018-10-15 08:56:42
【问题描述】:

以下是我的套接字服务器配置。我想定义一个回退/故障转移端口。

如果当前端口已在使用中,我如何重试创建套接字 bean(例如使用后备端口)?

如果故障转移端口也已在使用中:如何重试套接字创建直到成功(例如 5 分钟)?

    @Bean
    public TcpConnectionFactoryFactoryBean factory() {
        TcpConnectionFactoryFactoryBean f = new TcpConnectionFactoryFactoryBean();
        f.setType("server");
        f.setPort(port); //I want to retry and switch that port
        f.setUsingNio(true);
        f.setSingleUse(false);
        f.setDeserializer(deserializer);
        f.setSerializer(serializer);
        return f;
    }

    @Bean
    public TcpInboundGateway server(
            TcpConnectionFactoryFactoryBean factory,
            MessageChannel serverChannel) throws Exception {
        TcpInboundGateway g = new TcpInboundGateway();
        g.setConnectionFactory(factory.getObject());
        g.setRequestChannel(serverChannel);
        return g;
    }

【问题讨论】:

  • 那么随机分配端口对你有用吗?
  • 不,我想要一个主端口和一个故障转移端口。只有这两个是有效的。我想重试这两个,直到一个成功。

标签: java spring sockets spring-boot spring-integration


【解决方案1】:

Spring 提供了一个名为 SocketUtils 的实用程序类,它公开了一些使用套接字的方法。

对您有用的是SocketUtils.html#findAvailableTcpPort,它接受输入参数minPortmaxPort,并会返回a 范围内的可用tcp 端口[minPort, maxPort]。您可以为您的端口调用此方法,如果它们是连续的,您可以使用该方法返回的那个。如果端口不连续,您需要将返回的端口与您的端口进行匹配。

@Bean
public TcpConnectionFactoryFactoryBean factory(LengthHeaderDeserializer deserializer) throws Exception {
    CompletableFuture.runAsync(() -> waitForSocket(port)).get(5, TimeUnit.MINUTES);

    TcpConnectionFactoryFactoryBean fact = new TcpConnectionFactoryFactoryBean();
    ....
}

private void waitForSocket(int port) {
    do {
        try {
            SocketUtils.findAvailableTcpPort(port, port);
            return;
        } catch (Exception e) {
            try {
                TimeUnit.SECONDS.sleep(5);
            } catch (InterruptedException e1) {
                return;
            }
        }
    } while (true);
}

【讨论】:

  • 好的,所以 spring 尝试在该端口上打开一个套接字,然后直接关闭它。测试可用性。在创建TcpConnectionFactoryFactoryBean 之前,我可能会使用它在空闲端口上等待。
  • 我刚刚添加了一个示例,我是如何使用SocketUtils 解决它的,只是为了完整性。
  • @membersound 很棒。
【解决方案2】:

在端口0上监听更可靠,以便操作系统选择一个可用的端口。

【讨论】:

  • 虽然这通常是正确的,但我必须使用我无法控制的固定端口号。所以我没有机会使用不同的/系统选择的。
猜你喜欢
  • 2018-11-22
  • 2017-10-15
  • 1970-01-01
  • 2013-11-10
  • 1970-01-01
  • 1970-01-01
  • 2021-12-18
  • 2021-10-26
  • 1970-01-01
相关资源
最近更新 更多