我有一个基于媒体的Web应用程序在AWS(EC2 Windows)上运行。而且,我正在尝试通过在自动扩展组上添加应用程序和Web服务器来实现可扩展性。
我的问题是我需要将媒体存储与S3分开,以便我可以与不同的应用服务器簇共享。但是我必须将这些媒体文件从S3移至不同的FTP服务器。为此,我必须将文件从S3下载到App Server,然后进行FTP上传,这需要太多的时间过程。请注意,我将ColdFusion用作应用程序服务器。
现在,我有2个解决此问题的选项
- 将S3实例安装到EC2实例(我知道这是不建议的,也不确定这是否有助于提高FTP上传的速度)。
- 使用LAMDA服务将文件直接从S3上传到FTP服务器
我不能对每个EC2实例使用单独的EBS卷,因为
- 存储量很大,它将导致高成本
- 我需要在EC2实例附加的不同EBS卷上同步媒体存储
efs不是一个选项,因为我正在使用Windows Storage。
任何人都可以建议更好的解决方案吗?
python
很容易from ftplib import FTP
from socket import _GLOBAL_DEFAULT_TIMEOUT
import urllib.request
class FtpCopier(FTP):
source_address = None
timeout = _GLOBAL_DEFAULT_TIMEOUT
# host → ftp host name / ip
# user → ftp login user
# password → ftp password
# port → ftp port
# encoding → ftp servver encoding
def __init__(self, host, user, password, port = 21, encoding = 'utf-8'):
self.host = host
self.user = user
self.password = password
self.port = port
self.connect(self.host, self.port)
self.login(self.user, self.password, '')
self.encoding = encoding
# url → any web URL (for example S3)
# to_path → ftp server full path (check if ftp destination folders exists)
# chunk_size_mb → data read chunck size
def transfer(self, url, to_path, chunk_size_mb = 10):
chunk_size_mb = chunk_size_mb * 1048576 # 1024*1024
file_handle = urllib.request.urlopen(url)
self.storbinary("STOR %s" % to_path, file_handle, chunk_size_mb)
使用示例:
ftp = FtpCopier("some_host.com", "user", "p@ssw0rd")
ftp.transfer("https://bucket.s3.ap-northeast-2.amazonaws.com/path/file.jpg", "/path/new_file.jpg")
,但请记住,Lambda过程时间限制为15分钟。因此,在文件传输完成之前,可能会出现超时。我建议使用ECS Fargate代替Lambda。只要您需要,就可以保持运行过程。
如果S3文件不公开,请使用预先符号URL通过Urllib访问。
aws s3 presign s3://bucket/path/file.jpg --expires-in 604800