Retry Strategy
실제 서비스 운영시, DB 연결시 Timeout 등의 문제로 프로세스를 재시작해야 하는 경우가 발생할 수 있다. Argo Workflows에서도 Task에서 에러 발생시, task를 다시 생성하여 재시도하는 기능을 제공한다. 다음은 일부러 Python 스크립트 에러를 발생시켜 지정된 횟수만큼 retry를 하는 워크플로우 예시이다.
apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
generateName: wf-retrystrategy-
spec:
entrypoint: dag-template
arguments:
parameters:
- name: messageA
value: A
templates:
- name: dag-template
inputs:
parameters:
- name: messageA
dag:
tasks:
- name: Task1
arguments:
parameters: [{name: text, value: "{{inputs.parameters.messageA}}" }]
template: task-decision
- name: TaskA
template: task-A
depends: Task1.Succeeded
when: "{{tasks.Task1.outputs.result}} == A"
- name: task-decision
inputs:
parameters:
- name: text
script:
image: python:3.8-slim
command: [python]
source: |
p = "{{inputs.parameters.text}}"
print(p)
- name: task-A
retryStrategy:
limit: 5
retryPolicy: "Always"
backoff:
duration: "1"
factor: 2
maxDuration: 1m
script:
image: python:3.8-slim
command: [python]
source: |
print("Task A was executed.)
- task-A
- script.source 필드의 내용을 보면, 일부러 "를 제거하여 Syntax 에러가 발생하도록 설정하였다.
- retryStrategy
- limit: 재시도 최대 횟수(number)
- retryPolicy: 실패, 에러 또는 모든 경우에 대해 retry를 수행할지 선택하며, "Always"/"OnFailure"/"OnError"/"OnTrasientError" 옵션이 존재(string)
- backOff
- duration: 최초 retry 전까지 대기하는 시간, 기본은 초 단위이지만 2m, 4h 등으로 분, 시, 일 변경 가능(string)
- factor: Backoff 발생시, 증가하는 duration의 배수를 의미하며 duration=1,factor=2인 경우, 1->2->4->8->... 와 같이 늘어남(number)
- maxDuration: Backoff로 대기할 수 있는 최대 시간(string), limit이 아무리 커도 대기시간이 maxDuration을 초과하면 workflow는 종료됨
위 Workflow 실행시 아래와 같은 결과를 얻을 수 있다. TaskA의 재시도 5번이 모두 실패하였으며, 60초가 넘어가면서 Workflow도 종료되었다.
재귀 호출
프로그래밍을 하다보면, 재귀 함수를 통해 문제를 해결한 경험이 한번쯤 있을 것이다. Argo Workflows의 DAG나 Steps 등의 Template Invocator 역시 하나의 Template이기 때문에, 자기 자신을 호출하도록 구현할 수 있다. 우선 다음 예시를 보자.
apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
generateName: wf-recursion-
spec:
entrypoint: dag-template
templates:
- name: dag-template
dag:
tasks:
- name: roll-dice
template: task-roll-dice
- name: six
template: task-six
depends: roll-dice.Succeeded
when: "{{tasks.roll-dice.outputs.result}} == 6"
- name: not-six
template: dag-template
depends: roll-dice.Succeeded
when: "{{tasks.roll-dice.outputs.result}} != 6"
- name: task-roll-dice
script:
image: python:3.8-slim
command: [python]
source: |
import random
number = random.randint(1,6)
print(number)
- name: task-six
script:
image: python:3.8-slim
command: [python]
source: |
print("Hurray, it's 6!")
Python 코드가 약간 거슬리지만, 내용 자체는 어렵지 않다. 주사위를 굴려서 6이 나오면 메시지를 출력하고 그렇지 않으면 다시 주사위를 굴리는 동작을 워크플로우로 구현하였다. 내부적으로는 6이 나올 때까지 계속해서 'task-roll-dice' 템플릿이 호출될 것이다. 운이 좋으면 한번에 끝날 수도 있지만, 그렇지 않다면 아래 결과처럼 계속해서 Task가 생성될 수 있다.
'CI-CD' 카테고리의 다른 글
Argo CD - ApplicationSet (0) | 2022.07.02 |
---|---|
Argo Workflows - (4) Secret, 반복 및 조건부 실행 (0) | 2021.07.10 |
Argo Workflows - (3) Parameter, Artifact (0) | 2021.07.07 |
Argo Workflows - (2) Core Concepts (0) | 2021.07.04 |
Argo Workflows - (1) Introduction (0) | 2021.07.01 |