尝试在 Linux 上的 Docker 容器中列出 FTP 服务器目录时读取超时
Read time out when trying to list FTP server directory in Docker container on Linux
我有使用 LIST 命令轮询 FTP 服务器的服务。我使用本地被动模式,使用具有以下设置的 FTPSClient:
ftpClient.setTrustManager(TrustManagerUtils.getAcceptAllTrustManager());
ftpClient.setDataTimeout(1800000); //30 minutes
ftpClient.setBufferSize(1281000000);
ftpClient.setControlKeepAliveTimeout(120);
FTP 服务器目录中有大约 700,000 个文件,因此服务器响应需要时间。在我的本地机器上,通过启动原始 Java 应用程序,大约需要 5 分钟来检索文件列表,在 Windows 上的 Docker 容器中,它同时也可以正常工作,FileZilla - 没有问题,但更长。但是,当我 运行 Linux 机器(Ubuntu 18.04.4 LTS)上的容器时,尽管它可以连接到服务器,但它无法检索数据。在超时设置的指定时间后,我收到:
Caused by: java.net.SocketTimeoutException: Read timed out at
java.net.SocketInputStream.socketRead0(Native Method) ~[?:?] at
java.net.SocketInputStream.socketRead(SocketInputStream.java:115)
~[?:?] at java.net.SocketInputStream.read(SocketInputStream.java:168)
~[?:?] at java.net.SocketInputStream.read(SocketInputStream.java:140)
~[?:?] at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
~[?:?] at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
~[?:?] at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
~[?:?] at java.io.InputStreamReader.read(InputStreamReader.java:185)
~[?:?] at java.io.BufferedReader.fill(BufferedReader.java:161) ~[?:?]
at java.io.BufferedReader.readLine(BufferedReader.java:326) ~[?:?]
at java.io.BufferedReader.readLine(BufferedReader.java:392) ~[?:?]
at
org.apache.commons.net.ftp.FTPFileEntryParserImpl.readNextEntry(FTPFileEntryParserImpl.java:53)
~[app.jar:?] at
org.apache.commons.net.ftp.FTPListParseEngine.readStream(FTPListParseEngine.java:142)
~[app.jar:?] at
org.apache.commons.net.ftp.FTPListParseEngine.readServerList(FTPListParseEngine.java:118)
~[app.jar:?] at
org.apache.commons.net.ftp.FTPClient.initiateListParsing(FTPClient.java:3450)
~[app.jar:?] at
org.apache.commons.net.ftp.FTPClient.initiateListParsing(FTPClient.java:3371)
~[app.jar:?] at
org.apache.commons.net.ftp.FTPClient.initiateListParsing(FTPClient.java:3308)
~[app.jar:?] at
org.my.org.ftp.FtpOperator.listDirectory(FtpOperator.java:30)
~[app.jar:?]
我想这不是防火墙的问题,因为我有类似的服务可以轮询外部服务器并且它工作正常。两种服务都使用 Apache FTP 客户端库的本地被动模式。
Docker-编写文件:
version: '2'
services:
ingest:
image: pl/ingest
ports:
- "8038:8038"
volumes:
- ./logs:/logs
- ./processedFiles:/processedFiles
networks:
default:
driver: bridge
driver_opts:
com.docker.network.driver.mtu: 1500
在 docker 中将网络模式从网桥更改为主机-compose 使容器能够通过 FTPS/FTP:
列出文件
version: '2'
services:
ingest:
image: pl/ingest
ports:
- "8038:8038"
volumes:
- ./logs:/logs
- ./processedFiles:/processedFiles
network_mode: "host"
遇到了同样的问题 SuperUser answer:
... active mode ftp is not suited for containerized ftp clients, due
to the server actively trying to initiate a data connection to the ftp
client, which is not possible for a container.
有容器解决方法,但解决此问题的编程方法可能更简单:连接后更改为被动模式即可。
ftpClient.enterLocalPassiveMode()
现在对我有用了。
我有使用 LIST 命令轮询 FTP 服务器的服务。我使用本地被动模式,使用具有以下设置的 FTPSClient:
ftpClient.setTrustManager(TrustManagerUtils.getAcceptAllTrustManager());
ftpClient.setDataTimeout(1800000); //30 minutes
ftpClient.setBufferSize(1281000000);
ftpClient.setControlKeepAliveTimeout(120);
FTP 服务器目录中有大约 700,000 个文件,因此服务器响应需要时间。在我的本地机器上,通过启动原始 Java 应用程序,大约需要 5 分钟来检索文件列表,在 Windows 上的 Docker 容器中,它同时也可以正常工作,FileZilla - 没有问题,但更长。但是,当我 运行 Linux 机器(Ubuntu 18.04.4 LTS)上的容器时,尽管它可以连接到服务器,但它无法检索数据。在超时设置的指定时间后,我收到:
Caused by: java.net.SocketTimeoutException: Read timed out at java.net.SocketInputStream.socketRead0(Native Method) ~[?:?] at java.net.SocketInputStream.socketRead(SocketInputStream.java:115) ~[?:?] at java.net.SocketInputStream.read(SocketInputStream.java:168) ~[?:?] at java.net.SocketInputStream.read(SocketInputStream.java:140) ~[?:?] at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284) ~[?:?] at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326) ~[?:?] at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178) ~[?:?] at java.io.InputStreamReader.read(InputStreamReader.java:185) ~[?:?] at java.io.BufferedReader.fill(BufferedReader.java:161) ~[?:?] at java.io.BufferedReader.readLine(BufferedReader.java:326) ~[?:?] at java.io.BufferedReader.readLine(BufferedReader.java:392) ~[?:?] at org.apache.commons.net.ftp.FTPFileEntryParserImpl.readNextEntry(FTPFileEntryParserImpl.java:53) ~[app.jar:?] at org.apache.commons.net.ftp.FTPListParseEngine.readStream(FTPListParseEngine.java:142) ~[app.jar:?] at org.apache.commons.net.ftp.FTPListParseEngine.readServerList(FTPListParseEngine.java:118) ~[app.jar:?] at org.apache.commons.net.ftp.FTPClient.initiateListParsing(FTPClient.java:3450) ~[app.jar:?] at org.apache.commons.net.ftp.FTPClient.initiateListParsing(FTPClient.java:3371) ~[app.jar:?] at org.apache.commons.net.ftp.FTPClient.initiateListParsing(FTPClient.java:3308) ~[app.jar:?] at org.my.org.ftp.FtpOperator.listDirectory(FtpOperator.java:30) ~[app.jar:?]
我想这不是防火墙的问题,因为我有类似的服务可以轮询外部服务器并且它工作正常。两种服务都使用 Apache FTP 客户端库的本地被动模式。
Docker-编写文件:
version: '2'
services:
ingest:
image: pl/ingest
ports:
- "8038:8038"
volumes:
- ./logs:/logs
- ./processedFiles:/processedFiles
networks:
default:
driver: bridge
driver_opts:
com.docker.network.driver.mtu: 1500
在 docker 中将网络模式从网桥更改为主机-compose 使容器能够通过 FTPS/FTP:
列出文件version: '2'
services:
ingest:
image: pl/ingest
ports:
- "8038:8038"
volumes:
- ./logs:/logs
- ./processedFiles:/processedFiles
network_mode: "host"
遇到了同样的问题 SuperUser answer:
... active mode ftp is not suited for containerized ftp clients, due to the server actively trying to initiate a data connection to the ftp client, which is not possible for a container.
有容器解决方法,但解决此问题的编程方法可能更简单:连接后更改为被动模式即可。
ftpClient.enterLocalPassiveMode()
现在对我有用了。