2013-02-20 61 views
5

我剛開始使用AWS Ruby SDK來管理簡單的工作流程。我立即注意到的一種行爲是,在提交新的工作流程執行之前,至少有一名相關工作人員和一名相關決策人員正在運行。亞馬遜SWF:至少有一名員工需要跑步,爲什麼?

如果我在啓動我的工作人員和決策者之前提交新的工作流程執行,那麼即使我仍處於超時限制內,任務也不會被提取。爲什麼是這樣?根據HTTP長輪詢如何工作的描述,我希望任何應用程序在調用poll()時都能接收相關任務。

作業失敗後(例如,由於工作人員或決定器錯誤,或由於終止),我遇到其他死鎖情況。有時候,重新運行甚至只是開始一個全新的工作流程執行,都會導致工作流執行死鎖。 AWS控制檯的工作流程執行歷史記錄中顯示了初始決策任務,但決策者從未收到它們。無可否認,我在確認/減少這個問題時遇到了麻煩,但我懷疑它與上述問題有關。這大概發生在10%到20%的時間;剩下的時間,一切正常。

一些其他的事情要提到的是:我使用單個任務列表來執行按順序運行的兩個單獨的活動任務。工作人員和決策者都在輪詢相同的任務列表。

這裏是我的工人:

 

require 'yaml' 
require 'aws' 

config_file_path = File.join(File.dirname(File.expand_path(__FILE__)), 'config.yaml') 
config = YAML::load_file(config_file_path) 

swf = AWS::SimpleWorkflow.new(config) 

domain = swf.domains['test-domain'] 

puts("waiting for an activity") 
domain.activity_tasks.poll('hello-tasklist') do |activity_task| 

    puts activity_task.activity_type.name 
    activity_task.complete! :result => name 

    puts("waiting for an activity") 
end 
 

編輯

在AWS論壇另一位用戶評論說:

我認爲原因是SWF不能立即識別長輪詢連接關閉。當你殺死一名工人時,它的連接一段時間可以被服務認爲是開放的。所以它仍然可以派遣一個任務給它。對你來說,看起來新員工從來沒有得到它。驗證它的方法是檢查工作流歷史記錄。您將看到活動任務啓動事件,其中包含死亡工作人員的主機和PID。最終這樣的任務將會超時並且可以由決策者重新嘗試。

請注意,在頻繁終止連接的單元測試期間,這種情況很常見,對於任何生產應用程序來說都不是問題。常見的解決方法是對每個單元測試使用不同的任務列表。

這似乎是一個相當合理的解釋。我會試着證實這一點。

回答

9

你提出了兩個問題:一個關於執行開始,沒有活動決策者,另一個關於演員在任務中間崩潰。讓我按順序解決它們。

我根據您的觀察結果進行了實驗,事實上,當新的工作流程執行開始並且沒有決策者進行輪詢時,SWF仍然認爲新的決策任務已經開始。以下是來自AWS控制檯的我的事件日誌。注意發生了什麼:

Fri Feb 22 22:15:38 GMT+000 2013 1 WorkflowExecutionStarted 
Fri Feb 22 22:15:38 GMT+000 2013 2 DecisionTaskScheduled 
Fri Feb 22 22:15:38 GMT+000 2013 3 DecisionTaskStarted 
Fri Feb 22 22:20:39 GMT+000 2013 4 DecisionTaskTimedOut 
Fri Feb 22 22:20:39 GMT+000 2013 5 DecisionTaskScheduled 
Fri Feb 22 22:22:26 GMT+000 2013 6 DecisionTaskStarted 
Fri Feb 22 22:22:27 GMT+000 2013 7 DecisionTaskCompleted 
Fri Feb 22 22:22:27 GMT+000 2013 8 ActivityTaskScheduled 
Fri Feb 22 22:22:29 GMT+000 2013 9 ActivityTaskStarted 
Fri Feb 22 22:22:30 GMT+000 2013 10 ActivityTaskCompleted 
... 

的第一個決定任務立即安排(預計),並馬上開始(即涉嫌派遣到決勝局,即使沒有被判定運行)。在此期間我開始了一個決策者,但是直到5分鐘後的原始決策任務超時,工作流程纔開始移動。我無法想象這會成爲所需的行爲。兩種可能的防禦措施:在開始新的執行之前運行決策者,或者在決策任務中設置可接受的低超時時間(這些任務應該立即生效)。

崩潰的演員(無論是決定者還是工人)的問題是我熟悉的。一個簡短的背景說明第一:

活性和決策任務由服務分3個階段條記錄

  • 計劃=準備由演員被拾起。
  • Started =已被演員選中。
  • 已完成/失敗或超時=在最後期限內,演員已完成或未完成任務。

一旦演員拿起一個任務墜毀,它顯然不會報告任何回服務(除非它能夠恢復,還記得任務令牌派遣任務 - 但大多數崩潰的演員不會那麼聰明)。下次決定任務將被安排時,將在最近分派的任務超時後,這就是爲什麼所有演員似乎都在任務超時期間被阻塞的原因。這實際上是期望的行爲:只要工作人員仍在最後期限內工作,服務人員無法知道該任務是否正在工作。有一個簡單的方法可以解決這個問題:使用try-catch模塊讓你的演員合適,並在意外崩潰發生時使任務失敗。我不鼓勵爲每個集成測試使用單獨的任務列表。相反,我建議在teardown()區塊中拒絕任務。 SWF允許指定reason使任務失敗,這是記錄失敗並稍後通過AWS控制檯查看失敗的一種方式。

+1

感謝您的詳細解釋。我認爲我一直在做錯事,但看起來像所有事情都按預期工作或多或少。我沒有得到自己寫測試。 – Tom 2013-02-24 18:59:56

+0

快樂是我的,我做了一個爆炸,最終學到了一些東西。 – oozie 2013-02-26 20:35:07

+1

這有助於。謝謝 – Tzu 2015-07-29 18:27:31