【问题标题】:Activity Management in distributed architecture using AWS SWF使用 AWS SWF 在分布式架构中进行活动管理
【发布时间】:2014-11-18 09:51:55
【问题描述】:

我有两台服务器(EC2 实例)。在一台服务器(服务器 1)上,我有 3 个批次,而在另一台服务器(服务器 2)上,我有 4 个批次。现在,服务器 2 中的一个批处理只需要在服务器 1 中的批处理成功执行后执行。

更新

    Promise<Void> r12 = null
    new TryCatchFinally(){

    // First server job sequencing
    Promise<Void> r11 = client1.b1();
    r12 = client1.b2(r11);
    Promise<Void> r13 = client1.b3(r12);
    Promise<Void> r14 = client1.b4(r13);
    }
    @Override
    protected void doCatch(Throwable e) throws Throwable {
    System.out.println("Failed to execute commands in server 1");
    }
    @Override
    protected void doFinally() throws Throwable {
    // cleanup
    }       
    }
    new TryCatchFinally(){

    // Second server job sequencing
    Promise<Void> r21 = client2.b1();
    // Will execute only when both parameters are ready
    Promise<Void> r22 = client2.b2(r21, r12);
    Promise<Void> r23 = client2.b3(r22);
    Promise<Void> r24 = client2.b4(r23);
    }
    @Override
    protected void doCatch(Throwable e) throws Throwable {
    System.out.println("Failed to execute commands in server 2");
    }
    @Override
    protected void doFinally() throws Throwable {
    // cleanup
    }       
    }

任何服务器中的任何活动都可以抛出任何自定义异常。但是服务器中任何活动的执行不应该因为另一个服务器中的活动抛出异常而被取消。仅当它自己的服务器中的某个活动抛出任何异常时,才应取消服务器中的活动。 (如果依赖的活动失败或抛出任何异常,则无论服务器如何,依赖的活动也应该被取消)。为此,我所做的是将它包装到两个单独的 try catch 块中。

如果服务器 1 和服务器 2 的活动都抛出任何异常或失败,如何终止工作流执行?

【问题讨论】:

    标签: amazon-web-services amazon-ec2 amazon-swf


    【解决方案1】:

    您可以将每个 Spring Batch 执行包装到一个 SWF 活动中,然后使用 SWF 决策程序对这些活动进行排序。请参阅AWS Flow Framework 文档和recipes 了解更多信息。

    阅读更新后的问题描述后补充:

    您可以使用 Promises 以任何方式对活动进行排序。所以在你的情况下,我会做类似的事情:

    // First server job sequencing
    Promise<Void> r11 = client1.b1();
    Promise<Void> r12 = client1.b2(r11);
    Promise<Void> r13 = client1.b3(r12);
    Promise<Void> r14 = client1.b4(r13);
    
    // Second server job sequencing
    Promise<Void> r21 = client2.b1();
    // Will execute only when both parameters are ready
    Promise<Void> r22 = client2.b2(r21, r12);
    Promise<Void> r23 = client2.b3(r22);
    Promise<Void> r24 = client2.b4(r23);
    

    如果任何活动引发异常,它将取消所有未完成的活动并使工作流失败,除非使用TryCatchFinally 明确捕获和处理异常。未启动的活动(例如,因为它正在等待其 Promise 类型的参数准备好)立即取消。正在执行的活动应显式处理取消。有关详细信息,请参阅 AWS Flow Framework GuideError Handling 页面中的“活动检测信号”部分。

    添加了错误处理部分:

    您将不应影响工作流其他部分的部分包装在 TryCatch 中。因此,在此示例中,任何引发异常的 client2 活动都会取消所有未来的 client2 活动,但不会取消在 client1 上调用的活动,因为异常不会被抛出到其范围内。

    // First server job sequencing
    Promise<Void> r11 = client1.b1();
    final Promise<Void> r12 = client1.b2(r11);
    Promise<Void> r13 = client1.b3(r12);
    Promise<Void> r14 = client1.b4(r13);
    
    new TryCatch(){
    
      @Override
      protected void doTry() throws Throwable {
        // Second server job sequencing
        Promise<Void> r21 = client2.b1();
        // Will execute only when both parameters are ready
        Promise<Void> r22 = client2.b2(r21, r12);
        Promise<Void> r23 = client2.b3(r22);
        Promise<Void> r24 = client2.b4(r23);
      }
    
      @Override
      protected void doCatch(Throwable e) throws Throwable {
        // Handle exception without rethrowing it.
      }
    }
    

    【讨论】:

    • 你能更清楚地解释你的问题吗? SWF 允许以任何顺序执行活动。因此,您只需安排活动 1,并在完成后安排活动 2。由于 SWF 负责所有必要的低级管道,因此无需发送任何“通知”。活动由工作人员使用“任务列表”安排和轮询。因此,要将 activity1 和 activity2 路由到不同的 EC2 实例,它们必须使用不同的任务列表。
    • 谢谢.. 有什么办法可以确保不依赖于其他服务器的作业不会因为其他服务器的作业抛出任何异常而被取消?
    • 是的,将应该取消的活动一起包装在 TryCatch 中并处理异常而不重新抛出它。有关异常处理的更多信息,请参阅 TryCatchFinally 的 JavaDoc。
    • 谢谢.. 如何终止工作流执行?另外,如果有任何自定义异常,我如何删除堆栈跟踪并显示自定义消息。
    • Maxim... 我遇到了 SWF cron 问题。我在这里发布了一个问题stackoverflow.com/questions/28019926/…。如果您能提供解决方案,我将非常感谢您。
    猜你喜欢
    • 2019-01-12
    • 2014-09-04
    • 1970-01-01
    • 2017-05-18
    • 2018-10-20
    • 2014-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多