我使用akka steams进行scala应用。所以我的应用程序的流程是这样的:
1. Check if file exists on FTP - I'm doing it with the org.apache.commons.net.ftp.FTPClient
2. If it exists stream it via alpakka library(and make some stream transformations)
我的应用程序在本地运行,它可以连接到服务器。
问题在于它被部署到dcos / mesos。我遇到了一个问题:
java.io.IOException: /path/file.txt: No such file or directory
我可以肯定地说文件仍然存在。此外,当我尝试通过ftp本地连接docker容器时,我得到了类似的东西:
ftp> open some.ftp.address.com
Connected to some.ftp.address.com.
220 Microsoft FTP Service
Name (some.ftp.address.com:root): USER
331 Password required
Password:
230 User logged in.
Remote system type is Windows_NT.
ftp> dir
501 Server cannot accept argument.
ftp: bind: Address already in use
ftp>
答案 0 :(得分:1)
所以我的问题真的很奇怪。但我已经设法解决了这个问题。 快速回答:我这样使用alpakka ftp lib:
Ftp
.fromPath(url, user, pass, Paths.get(s"/path/$fileName"))
但是使用这种方式可行:
val ftpSettings = FtpSettings(
host = InetAddress.getByName(url),
port = 21,
NonAnonFtpCredentials(user, pass),
binary = true,
passiveMode = true
)
Ftp
.fromPath(Paths.get(s"/path/$fileName"), ftpSettings)
更长的答案:我开始调查alpakka lib并且我发现它在检查文件是否存在时使用了同样适合我的lib!
https://github.com/akka/alpakka/blob/master/ftp/src/main/scala/akka/stream/alpakka/ftp/impl/FtpOperations.scala
所以我开始挖掘,似乎最有可能将被动模式设置为真的是解决方案。但这很奇怪,因为我读过Windows ftp服务器不支持被动模式...... 我希望有一天有人可以澄清我的怀疑,但此刻我很高兴,因为它有效:)
答案 1 :(得分:1)
不确定它是否仍然有用,但是在将数据连接更改为被动后,我也让ftp客户端从Docker容器内部传输数据。我认为活动模式要求客户端具有开放端口,服务器在返回文件列表结果时以及在数据传输期间会与服务器连接。但是,由于未路由请求(例如在NAT:et网络中),因此无法从docker容器外部访问客户端端口。
发现这篇文章介绍了主动/被动FTP连接