我在 PHP on cluster server 有申请 . 它从服务器上的aws桶复制文件处理文件(解压缩文件 . 使用itext java将PDF转换为XML,读取XML并将数据保存到数据库),并将上载处理的文件返回到存储桶 .
它适用于单个实例,但在多个实例的负载 balancer 中,服务器上的进程下的文件消失 . 我无法直接从存储桶处理文件,因为我无法在存储桶上解压缩也无法在存储桶上运行jar文件 . 所以我必须临时存储文件以进行处理 . 有没有办法处理这种情况
一些可能的解决方案:
使用中央单键值存储(数据库)存储已存在的文件's that you are currently processing, when downloading a new file, check if this file isn'的路径 . 你可以使用Redis
将一个新的空文件上传到S3,但文件名中包含一些内容,以便您知道如果该文件存在,则附带的文件已被处理(虽然我不确定S3是否缓存目录列表)解决方案您还应该考虑将文件写入S3的成本,这也取决于您的规模
在处理S3时重命名或删除S3中的文件
可以有多种解决方案:
一种解决方案是检查并应用标签,如果在上传时处理文件应用某些标签,如 processed=true ,当您下载文件时检查标签 .
processed=true
更好的解决方案是使用lambda来完成这项任务 .
你可以使用模式
S3到lambda
Lambda在SQS中删除了一条消息
应用程序监视SQS
应用程序处理文件
删除邮件 .
或者让lambda完成S3上传的所有工作 . 取决于进程运行的时间 . 执行时间为5分钟 . http://docs.aws.amazon.com/lambda/latest/dg/limits.html
例如:
设置lambda函数以在上传新对象事件时监视s3 . 然后让lambda函数在SQS中删除一条消息(从它接收的事件数据中,Lambda函数知道源存储桶名称和对象键名称) . 服务器可以监视队列,处理消息,提取文件并将其上载到新存储桶,从旧的s3存储桶中删除该文件,然后从队列中删除该消息 . 如果服务器在处理期间死亡,则消息将返回到队列(可见性超时) . 确保在旧存储桶上处理和删除它的方法是启用版本控制和生命周期策略 . 处理消息时,如果旧存储桶上不存在文件,则发送警报和/或检查先前版本 . 您还可以在旧存储桶上设置生命周期策略,以便在超过X天时永久删除版本 .
使用Lambda监控S3
http://docs.aws.amazon.com/lambda/latest/dg/with-s3.html
http://docs.aws.amazon.com/lambda/latest/dg/with-s3-example.html
版本控制
http://docs.aws.amazon.com/AmazonS3/latest/dev/Versioning.html
选择永久删除以前的版本,然后输入对象成为先前版本后永久删除对象的天数(例如,455天) . http://docs.aws.amazon.com/AmazonS3/latest/user-guide/create-lifecycle.html
您需要的是一个可以无损地存储文件的系统 . 有很多替代品 .
a)另一台服务器
b)SQS队列 . 上面的@strongiz答案解释得非常好 .
c)甚至是另一个数据库 .
在每种情况下,您都需要一个标志来定义文件是否被处理 . 文件处理完成后
a)删除文件或,
b)改变旗帜
由于PHP是面向会话的,因此您无法在其中存储数据,因此,您需要连接到另一个接口 . 对于数据库,您实际上可以存储文件路径条目和标志以确定是否处理了文件 . 所以,即使是3的组合也可能有效 .
4 回答
一些可能的解决方案:
使用中央单键值存储(数据库)存储已存在的文件's that you are currently processing, when downloading a new file, check if this file isn'的路径 . 你可以使用Redis
将一个新的空文件上传到S3,但文件名中包含一些内容,以便您知道如果该文件存在,则附带的文件已被处理(虽然我不确定S3是否缓存目录列表)解决方案您还应该考虑将文件写入S3的成本,这也取决于您的规模
在处理S3时重命名或删除S3中的文件
可以有多种解决方案:
一种解决方案是检查并应用标签,如果在上传时处理文件应用某些标签,如
processed=true
,当您下载文件时检查标签 .更好的解决方案是使用lambda来完成这项任务 .
你可以使用模式
S3到lambda
Lambda在SQS中删除了一条消息
应用程序监视SQS
应用程序处理文件
删除邮件 .
或者让lambda完成S3上传的所有工作 . 取决于进程运行的时间 . 执行时间为5分钟 . http://docs.aws.amazon.com/lambda/latest/dg/limits.html
例如:
设置lambda函数以在上传新对象事件时监视s3 . 然后让lambda函数在SQS中删除一条消息(从它接收的事件数据中,Lambda函数知道源存储桶名称和对象键名称) . 服务器可以监视队列,处理消息,提取文件并将其上载到新存储桶,从旧的s3存储桶中删除该文件,然后从队列中删除该消息 . 如果服务器在处理期间死亡,则消息将返回到队列(可见性超时) . 确保在旧存储桶上处理和删除它的方法是启用版本控制和生命周期策略 . 处理消息时,如果旧存储桶上不存在文件,则发送警报和/或检查先前版本 . 您还可以在旧存储桶上设置生命周期策略,以便在超过X天时永久删除版本 .
使用Lambda监控S3
http://docs.aws.amazon.com/lambda/latest/dg/with-s3.html
http://docs.aws.amazon.com/lambda/latest/dg/with-s3-example.html
版本控制
http://docs.aws.amazon.com/AmazonS3/latest/dev/Versioning.html
您需要的是一个可以无损地存储文件的系统 . 有很多替代品 .
a)另一台服务器
b)SQS队列 . 上面的@strongiz答案解释得非常好 .
c)甚至是另一个数据库 .
在每种情况下,您都需要一个标志来定义文件是否被处理 . 文件处理完成后
a)删除文件或,
b)改变旗帜
由于PHP是面向会话的,因此您无法在其中存储数据,因此,您需要连接到另一个接口 . 对于数据库,您实际上可以存储文件路径条目和标志以确定是否处理了文件 . 所以,即使是3的组合也可能有效 .