Home > Net >  Spring integration: Container application hangs for a few seconds during connection step
Spring integration: Container application hangs for a few seconds during connection step

Time:06-22

In brief, I have a socket app, implemented with spring, I share the code below:

@SpringBootApplication
public class ExampleApp {

    public static void main(String[] args) {
        SpringApplication.run(ExampleApp.class, args);
    }

    @Bean
    public AbstractServerConnectionFactory serverConnectionFactory() {
        TcpNetServerConnectionFactory tcpNetServerConnectionFactory = new TcpNetServerConnectionFactory(1234);
        return tcpNetServerConnectionFactory;
    }

    @Bean
    public MessageChannel requestChannel() {
        return new DirectChannel();
    }

    @Bean
    public MessageChannel replyChannel() {
        return new DirectChannel();
    }

    @Bean
    public TcpReceivingChannelAdapter receivingChannelAdapter(AbstractServerConnectionFactory serverConnectionFactory, MessageChannel requestChannel) {
        TcpReceivingChannelAdapter tcpReceivingChannelAdapter = new TcpReceivingChannelAdapter();
        tcpReceivingChannelAdapter.setConnectionFactory(serverConnectionFactory);
        tcpReceivingChannelAdapter.setOutputChannel(requestChannel);
        return tcpReceivingChannelAdapter;
    }

    @Bean
    @ServiceActivator(inputChannel = "replyChannel")
    public TcpSendingMessageHandler tcpSendingMessageHandler(AbstractServerConnectionFactory serverConnectionFactory) {
        TcpSendingMessageHandler tcpSendingMessageHandler = new TcpSendingMessageHandler();
        tcpSendingMessageHandler.setConnectionFactory(serverConnectionFactory);
        return tcpSendingMessageHandler;
    }

    @ServiceActivator(inputChannel = "requestChannel", outputChannel = "replyChannel")
    public Message<String> processMessage(Message<String> message) {
        Message<String> reply = MessageBuilder
                .withPayload("OK")
                .setHeader(IpHeaders.CONNECTION_ID, message.getHeaders().get(IpHeaders.CONNECTION_ID, String.class))
                .build();
        return reply;
    }

    @Bean
    public ApplicationListener<TcpConnectionEvent> listener(MessageChannel replyChannel) {
        return tcpConnectionEvent -> {
            if (tcpConnectionEvent instanceof TcpConnectionOpenEvent) {
                Message<String> message = MessageBuilder
                        .withPayload("Hello client")
                        .setHeader(IpHeaders.CONNECTION_ID, tcpConnectionEvent.getConnectionId())
                        .build();
                replyChannel.send(message);
            }
        };
    }
}

When I am running this application locally, everything is fine:

I just use telnet (for the manual connect) and connect there, after connection approximately instantly I see my Server greeting and I am able to communicate with the Server by command -> response.

When I am running my app in docker container - it has some troubles. Basically, it instantly connects me to the Server but I see the greeting message with 6 seconds of delay. It does not reply to my commands as well, just ignores them during that period. When it prints greeting - it shows the responses for my requests as well. After that I am able to cooperate with the Server without any problems.

Have anybody faced the same problem?

UPD: just for the record, the app is not using any database, so it is very lightweight

UPD1: maybe, problem is in my docker compose file, it looks quite simple:

  app:
    image: me/app:v1
    container_name: app
    build:
      context: *ToAppRootDir*
      dockerfile: *pathToDockerFile*
    restart: always
    environment:
      - SERVER_PORT: 8080
      - SOCKET_PORT: 8081
    ports:
      - "8080:8080"
      - "8081:8081"

UPD2: The longest delay is during the firt connection, usually it takes 6seconds. The next connection will have delay as well, but it will takes up to 2 seconds.

UPD3: Moreover, this problem exists in the container internal communication. I have simple springBoot intergration test with only this app - and when i am trying to connect and read from the socket - i am recieving ReadTimeoutConnection

CodePudding user response:

This has fixed the problem for me:

@Bean
public AbstractServerConnectionFactory serverConnectionFactory() {
    TcpNetServerConnectionFactory tcpNetServerConnectionFactory = new TcpNetServerConnectionFactory(port);
    tcpNetServerConnectionFactory.setLookupHost(false);
    return tcpNetServerConnectionFactory;
}

See that option I disable:

/**
 * If true, DNS reverse lookup is done on the remote ip address.
 * Default true.
 * @param lookupHost the lookupHost to set
 */
public void setLookupHost(boolean lookupHost) {

This one in the end is used like this:

    InetAddress inetAddress = socket.getInetAddress();
    if (inetAddress != null) {
        this.hostAddress = inetAddress.getHostAddress();
        if (lookupHost) {
            this.hostName = inetAddress.getHostName();
        }
        else {
            this.hostName = this.hostAddress;
        }
    }

So, apparently that inetAddress.getHostName() really takes some time for resolution in the Docker DNS.

  • Related