春季集成:连接步骤中的容器应用程序悬挂几秒钟
简而言之,我有一个使用Spring实现的套接字应用程序,我共享以下代码:
@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);
}
};
}
}
当我本地运行此应用程序时,一切都很好:
我只使用Telnet(用于手动连接),然后在连接之后连接到该连接大约立即请参阅我的服务器问候,我可以通过命令与服务器进行通信 - &gt;回复。
当我在Docker容器中运行我的应用程序时,它会遇到一些麻烦。基本上,它立即将我连接到服务器,但我看到了延迟6秒的问候消息。它也没有回复我的命令,只是在此期间忽略它们。当它打印问候时 - 它也显示了我的请求的响应。之后,我能够与服务器合作而没有任何问题。
有人面对同样的问题吗?
upd:仅作为记录,该应用程序没有使用任何数据库,因此它非常轻巧的
upd1:也许,我的docker组成文件中的问题看起来很简单:
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:最长的延迟是在firt连接期间,通常是这样。需要6秒。下一个连接也将延迟,但最多将需要2秒钟。
upd3:此外,容器内部通信中存在此问题。我只使用此应用程序进行简单的Springboot Intergration测试 - 当我尝试从插座连接和阅读时 - 我正在收回ReadTimeOutConnection
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这解决了我的问题:
请参阅我禁用的选项:
最后使用此选项:
因此,显然,
inetAddress.gethostName()
确实需要一些时间来解决Docker DNS中的分辨率。This has fixed the problem for me:
See that option I disable:
This one in the end is used like this:
So, apparently that
inetAddress.getHostName()
really takes some time for resolution in the Docker DNS.