我一直试图找到在AWS Elastic beanstalk上使用PHP运行后台作业的最佳方法,经过几个小时在Google和SO上搜索,我相信一个好的解决方案是使用SWF和活动工作者.
我发现这个例子埋没在aws-sdk-for-php中:https://github.com/amazonwebservices/aws-sdk-for-php/tree/master/_samples/AmazonSimpleWorkflow/cron
自述文件说:
要运行此示例,您需要在单独的终端/控制台窗口中从命令行执行三个脚本
和
请注意,start_cron_example_workflow.php脚本将在决策程序和活动工作程序脚本继续运行时快速退出,直到您手动终止它们为止.
决策者和活动工作者将"永远"循环,并试图在EB中运行这些是我在做的事情.
在我的.ebextensions目录中,我有一个执行这些文件的文件:
container_commands:
01background_task:
command: "php -f start_cron_example_activity_workers.php"
02background_task:
command: "php -f start_cron_example_workflow_workers.php"
Run Code Online (Sandbox Code Playgroud)
但是我收到以下错误消息:
错误
无法部署应用程序版本.
错误某些实例未响应命令.没有收到[i-a5417ed4]的答复.
我可以用配置文件做任何方式吗?如何在不引入单点故障的情况下在AWS EB中完成此工作?
谢谢.
cron backgroundworker amazon-web-services amazon-swf amazon-elastic-beanstalk
序言:我正在尝试为我认为是一个非常常见的用例提出一个提案,我想使用亚马逊的SWF和SQS来实现我的目标.可能还有其他服务可以更好地匹配我正在尝试的内容,因此如果您有任何建议,请随时将它们删除.
问题:最基本的需求是客户端(移动设备,Web服务器等)发布将异步处理而不响应客户端的消息 - 非常基本.
预期的实现是客户端将消息发布到预定的SQS队列.此时,客户端已完成.我们还有一个定义的SWF工作流程负责从队列中拾取消息,并且(在一些操作之后)将它放在Dynamo DB中 - 再次,所有这些都非常简单.
我似乎无法弄清楚的是,如何触发工作流程的启动.从我一直在阅读的工作流程来看,并不是一个无限期的过程.它有一个开始,一个中间和一个结尾.根据SWF文档,工作流程可以运行不超过一年(在SWF中设置超时值).
所以,我的问题是:如果我假设工作流代表一个消息处理流程,那么每当消息发布到SQS时,如何启动工作流程?
警告:我也研究过使用SNS而不是SQS.这将允许我运行可以订阅SNS的服务器,然后在发布通知时启动工作流.这当然是一种解决方案,但我想避免为单个Web服务设置服务器,然后我必须根据正在处理的消息数量来管理/扩展.我首先考虑使用SQS/SWF的原因是有一个我不必担心的自动缩放系统.
先感谢您.
Step Functions 现在支持回调功能以支持手动批准。我想知道任务令牌是如何生成的,以及我们是否可以传递自己的任务令牌字符串,以便我们不需要存储它来标记任务通过/失败。
此外,对于需要多个客户端交互才能进入下一个状态的工作流程,建议使用 Step Functions 或 SWF(及其信号)。
用例:我在工作流程中有多个步骤,如果计时器达到 6 个月,或者如果在这 6 个月内用户实际批准,则我们需要执行失败场景,那么工作流程需要执行到通过的场景。
我有一个工作流程,它接收S3存储桶中的文件,并根据文件内容进行大量处理和进一步请求.目前,客户端必须在上传文件后手动触发工作流程.这对我来说似乎是一个非常常见的用例,所以有没有办法在文件上传后立即触发工作流程?
我想在它们之间应该有一个SNS通知,但有没有办法将通知直接发送到SWF,而没有服务消耗它们并启动工作流程?
SWF文档建议"工作人员应将其客户端套接字超时设置为至少70秒(比服务保留轮询请求的最长时间高10秒)."
目前我的作品收到了阅读时间,例如:
botocore.vendored.requests.packages.urllib3.exceptions.ReadTimeoutError: HTTPSConnectionPool(host='swf.eu-west-1.amazonaws.com', port=443): Read timed out. (read timeout=60)
Run Code Online (Sandbox Code Playgroud)
我已经准备好了
socket.setdefaulttimeout(70)
Run Code Online (Sandbox Code Playgroud)
,但它似乎没有产生任何影响.我看到在botocore enrpoint.py上将DEFAULT_TIMEOUT设置为60,但是找不到在boto3中自定义它的方法.如何将其移至70以避免长轮询中的读取超时?
我有一个父工作流(ParentWorkflow)调用子工作流(ChildWorkflow),我正在尝试测试该调用.
父代码看起来像这样:
public class ParentWorkflow {
private final ChildWorkflowClientFactory childWorkflowClientFactory =
new ChildWorkflowClientFactoryImpl();
public void runWorkflow() {
new TryCatch() {
@Override
protected void doTry() throws Throwable {
Promise<Void> workflowFinished = childWorkflowClient.childWorkflow(x);
...
}
...
}
}
Run Code Online (Sandbox Code Playgroud)
我想模拟
childWorkflowClient.childWorkflow(x)
调用,但是当我连接单元测试时,我似乎没有注入客户端工厂的选项,单元测试代码如下所示:
@Rule
public WorkflowTest workflowTest = new WorkflowTest();
@Mock
private Activities mockActivities;
private ParentWorkflowClientFactory workflowFactory
= new ParentWorkflowClientFactoryImpl();
@Before
public void setUp() throws Exception {
// set up mocks
initMocks(this);
workflowTest.addActivitiesImplementation(mockActivities);
workflowTest.addWorkflowImplementationType(ParentWorkflowImpl.class);
workflowTest.addWorkflowImplementationType(ChildWorkflowImpl.class);
Run Code Online (Sandbox Code Playgroud)
我似乎无法将任何内容传递到工作流实现类中,还有另一种方法可以模拟子工作流吗?
我正在创建一个应用程序,其中有多个阶段 - 在第一阶段,有多个任务要并行执行...一旦该阶段的所有任务完成,只有处理才能进入下一阶段.
从我读到的关于决策者的内容来看,决策者可以从下一阶段的众多可能选项中选择一种.
但是,只有当前阶段的所有并行流程都完成时,我才想进入下一阶段.
这是否意味着我应该设置每个并行进程来调用下一个阶段,并且当下一个阶段初始化时,它应该检查前一阶段的所有并行进程是否完成,然后才真正开始处理?这意味着第一阶段的所有并行进程都将调用对应.第二阶段的并行过程,其中只有一个实际上会进行处理(因为这将是发现前一阶段的所有过程都已完成的过程).
有没有更好的方法来实现这个?那么下一阶段的过程只被召唤一次?
所以我试图了解队列解决了哪些实际问题。通过阅读谷歌上的所有信息,我得到了高水平的信息。
因此,我正在研究 A 公司的架构,他们对于作业队列有不同的用例,例如
为什么要稍后处理呢?
这是我最好的猜测...
假设这是一个有效的用例,那么添加更多服务器来处理更多“事物”难道没有意义吗?是因为添加更多服务器比使用队列成本更高并且稍微牺牲响应时间吗?
根据我的用例示例,队列还能为它们解决哪些其他问题?
amazon-swf ×8
amazon-sqs ×2
java ×2
amazon-s3 ×1
boto3 ×1
cron ×1
python ×1
rabbitmq ×1
redis ×1
unit-testing ×1
workflow ×1