Power Automate의 오류 처리와 재시도 설계 ── "동작하던 플로우가 멈춰 있었다"를 막는 법

· · Power Automate, 오류 처리, 클라우드 플로우, 재시도, 멱등성, 운영 모니터링, 업무 자동화, 기술 상담

“매일 아침 동작하던 집계 플로우가 실은 지난주부터 멈춰 있었다”, “주문 등록 플로우가 같은 데이터를 두 번 처리해서 대장에 중복이 생겼다”. Power Automate로 플로우를 만들어 운영하기 시작한 회사로부터 이런 상담을 자주 받습니다. 만들기는 쉬웠는데, 멈춘 것을 아무도 알아차리지 못했다는 패턴입니다.

Power Automate 플로우는 정상 경로만이라면 몇 시간 만에 동작합니다. 다만 연결 대상 서비스는 일시적으로 다운되고, 인증은 끊기며, 예상치 못한 데이터는 반드시 흘러들어 옵니다. “실패했을 때 무슨 일이 일어나는가”를 설계하지 않은 플로우는 실패를 조용히 쌓아가다가, 최악의 경우 14일 만에 자동으로 꺼집니다1. 이 글에서는 플로우 실패의 분류부터, 표준 재시도의 정확한 사양, 스코프를 이용한 Try-Catch-Finally 패턴, 실패를 알아차리는 구조, 재실행과 멱등성까지, 실제 운영을 견디는 오류 처리 설계 패턴을 정리합니다. Power Automate 전체의 구분 사용이나 UI 자동화 쪽(데스크톱 플로우)의 오류 처리는 「Power Automate로 업무 자동화하기 ── 클라우드 플로우・데스크톱 플로우 구분과 오류 처리 설계」에서 다루고 있으므로, 이 글은 클라우드 플로우에 대한 심화 내용으로 좁혀서 설명합니다.

1. 먼저 결론

  • 실패는 「일시적 장애」「데이터 기인」「권한・인증 만료」「사양 변경」의 4가지로 나누어 생각합니다. 표준 재시도로 해결되는 것은 첫 번째뿐이고, 나머지 3가지는 탐지와 수정을 위한 구조가 필요합니다2.
  • 표준 재시도 정책은 요청이 타임아웃되거나 408・429・5xx 응답으로 실패했을 때만 작동합니다. 기본값은 지수 백오프이며, 횟수는 라이선스 계층(성능 프로필)에 따라 최대 2회 또는 12회입니다31.
  • 오류 처리의 기본형은 스코프 + 「실행 조건 구성」에 의한 Try-Catch-Finally입니다. 실행 조건 구성에서는 「성공한 경우・실패한 경우・건너뛴 경우・타임아웃된 경우」의 4가지 상태 중에서 선택합니다34. 참고로 이 기능은 일본어 UI에서 표시 이름이 「実行条件の構成」이며, 영어 UI와 문서에서는 「run after」라고 부릅니다. 이 글에서는 이하 UI 표시 이름을 따서 실행 조건 구성으로 통일합니다.
  • Catch에서 실패를 처리했다면 마지막에 Terminate 액션으로 실행을 「실패」로 기록합니다. 이를 잊으면 실행 기록상으로는 성공한 것처럼 보여 실패가 묻혀 버립니다43.
  • 기본 실패 알림 메일은 「알려진 해결 방법이 있는 실패」 한정・28일 쿨다운 포함이라, 전적으로 의지하기에는 빈틈이 많은 구조입니다. Catch 블록에서의 자체 알림을 필수로 여겨야 합니다5.
  • 실행 기록은 기본값으로 28일밖에 보이지 않습니다. 계속 실패하는 플로우는 14일 만에 자동으로 꺼집니다. “멈춰 있었던 것을 한 달 뒤에 알아차렸다”는 사양상 충분히 있을 수 있는 일입니다61.
  • 재실행(재제출)과 이중 기동에 대비해, 두 번 실행되어도 안전한 멱등 설계(처리 완료 플래그, 생성이 아닌 upsert, 트리거 조건)를 처음부터 넣어 둡니다78.

2. 플로우는 어떻게 실패하는가 ── 실패의 4가지 분류

오류 처리 설계는 “어떻게 실패하는가”의 분류에서 시작하면 정리하기 쉬워집니다. Microsoft의 가이드에서도 자동화는 반드시 실패할 수 있는 것으로 보고, 연결 대상의 유지보수・API 변경・비밀번호 변경・순간적인 네트워크 장애 등을 상정하도록 요구하고 있습니다2. 실무에서는 다음 4가지 분류로 생각하면 대응 방향이 그대로 정해집니다.

분류 전형적인 예 재시도로 해결되는가 대응 방향
일시적 장애 연결 대상의 순간 단절・유지보수, 스로틀링(429), 서버 오류(5xx) 해결되는 경우가 많음 표준 재시도에 맡긴다(3장)
데이터 기인 예상 밖의 빈 값・형식, 참조 대상에 존재하지 않는 ID(400/404) 해결되지 않음 Try-Catch로 잡아서 알린다(4장), 입력 측의 검증
권한・인증 만료 연결(커넥션)의 만료, 비밀번호 변경, 담당자의 퇴사・계정 비활성화 해결되지 않음 재인증이 필요. 탐지와 알림(5장), 연결 유지 방식의 설계
사양 변경 SharePoint 열 이름 변경, 연결 대상 API의 버전 변경, 양식 항목 변경 해결되지 않음 플로우 수정이 필요. 변경 관리와 알림

이 중 실무에서 가장 골치 아픈 것이 권한・인증 만료입니다. 플로우의 액션뿐 아니라 트리거 자체가 실패하게 되기 때문입니다. 트리거가 4xx 계열 오류로 실패하는 전형적인 예로, 연결에 사용하던 비밀번호의 변경(만료)이 공식 문제 해결 가이드에도 나와 있습니다. 트리거가 실패하면 플로우 자체가 애초에 시작되지 않기 때문에 실행 기록에 「실패」 행조차 남지 않아, 알아차리는 것이 더욱 늦어집니다9. 연결은 그것을 만든 사용자 개인에게 연결되어 있기 때문에, 담당자의 퇴사・이동으로 한꺼번에 끊기는 사고도 일어납니다. 이러한 조직적 대책은 「Power Automate의 개인 의존 대책 ── 만든 사람이 퇴사해도 플로우가 멈추지 않으려면」에서 자세히 다루고 있습니다.

또 하나 알아 두어야 할 것은, 실패를 방치하면 플로우 자체가 정지된다는 점입니다. 트리거나 액션이 계속 실패하는 플로우는 14일 만에 자동으로 꺼지고, 계속 스로틀링되는 플로우도 14일 만에 꺼집니다. 90일간 트리거되지 않은 플로우도(프리미엄・용량 라이선스 소유자가 아니라면) 꺼질 수 있습니다1. 또한 DLP(Data Loss Prevention: 데이터 손실 방지. 관리자가 커넥터의 사용 가능 여부와 조합을 제한하여 조직의 데이터가 의도치 않게 외부로 유출되는 것을 막는 가드레일입니다. 현재 공식 명칭은 「데이터 정책」)10의 정책 위반이나 반복되는 실패로 인해, 플로우가 「중단(suspended)」 상태가 되어 있는 경우도 있습니다11. DLP 정책 변경은 즉시 적용되어 예고 없이 플로우를 정지시키므로, 여러 플로우가 동시에 망가졌을 때는 먼저 정책 변경을 의심하는 것이 정석입니다11. “동작하던 플로우가 멈춰 있었다”의 몇 할은, 장애가 아니라 이 사양에 의한 것입니다.

3. 표준 재시도를 이해한다

Power Automate(기반은 Azure Logic Apps)의 액션에는 처음부터 재시도 정책이 내장되어 있습니다. 먼저 이 사양을 정확히 알아 두면 “재시도 설정을 추가해야 하는가”, “재시도로는 해결되지 않는가”를 판단할 수 있습니다.

무엇이・언제 재시도되는가

재시도 정책이 작동하는 것은 액션(또는 트리거)의 요청이 타임아웃되거나, 408(요청 타임아웃)・429(요청 과다=스로틀링)・5xx(서버 오류) 응답으로 실패했을 때입니다3. 기본 정책은 지수 백오프(간격을 지수적으로 늘려가며 재시도)이며, Power Automate에서의 기본 횟수와 간격은 플로우의 성능 프로필(실질적으로는 라이선스 계층)에 따라 다릅니다1.

성능 프로필 주요 대응 라이선스 기본 재시도
Low Microsoft 365 플랜, 무료 플랜 등 최대 2회. 약 5분 단위로 간격이 늘어나며, 마지막 재시도는 약 10분 간격
Medium / High Power Automate Premium, Process 라이선스 등 최대 12회. 7초부터 지수적으로 늘어나며, 마지막 재시도는 약 1시간 간격

즉 같은 플로우 정의라도 소유자의 라이선스에 따라 “일시적 장애에 대한 끈기”가 달라집니다. 프로필은 재시도 횟수뿐 아니라 하루당 요청 수 상한에도 영향을 미치므로, 라이선스 계층에 대한 사고방식은 「Power Automate 라이선스와 표준/프리미엄 커넥터의 경계」도 참고하시기 바랍니다.

재시도 정책은 액션 설정에서 변경할 수 있습니다. 종류는 기본・없음・고정 간격・지수 간격의 4가지이며, 횟수와 간격을 명시적으로 지정할 수 있습니다. 설정 상한은 횟수 90회・최소 간격 5초・최대 지연 1일입니다31. Microsoft의 코딩 가이드라인에서는 일시적 장애로부터의 회복에는 고정 간격보다 지수 간격이 권장됩니다. 짧은 간격으로 계속 두드려 상대측의 회복을 방해하지 않기 위해서입니다4.

재시도로 해결되는 것・해결되지 않는 것

사상 재시도로 해결되는가
연결 대상의 순간 단절・타임아웃(408/5xx) 해결되는 경우가 많음. 기본값 그대로 두면 됨
스로틀링(429) 간격이 늘어나면 해결될 수 있음. 다만 상시적인 429는 설계 문제(요청 수 감소가 필요)
데이터 이상(400)・존재하지 않는 리소스(404) 해결되지 않음. 몇 번을 해도 같은 오류
인증 오류(401/403)・연결 끊김 해결되지 않음. 재인증이라는 플로우 밖의 조작이 필요
업무적인 실패(승인 반려, 재고 부족 등) 애초에 HTTP 오류가 아니므로 재시도 대상 밖. 플로우의 분기로 처리

주의할 점은, 재시도도 요청 수(Power Platform 요청)를 소비한다는 것입니다. 성공・실패에 관계없이 액션 실행은 요청 수에 카운트되며, 재시도나 페이지네이션의 요청도 마찬가지입니다1. 429에 대해 횟수를 늘리는 방향으로 조정하면 스로틀링이 더 악화될 수 있으므로, 재시도를 강화하기 전에 “호출 횟수 자체를 줄일 수 없는가”를 먼저 검토합니다.

4. Try-Catch-Finally 패턴 ── 스코프와 실행 조건 구성

재시도로 해결되지 않는 실패는 플로우 안에서 잡아서 처리합니다. Power Automate에는 try-catch 구문이 없지만, 스코프(Scope)실행 조건 구성(영어 UI에서는 run after)을 조합하면 같은 구조를 만들 수 있습니다. 이는 Microsoft의 코딩 가이드라인에서도 권장되는 정석입니다4.

이 구조의 토대가 되는 것이 실행 조건 구성입니다. 각 액션은 완료 시 성공(Succeeded)・실패(Failed)・건너뜀(Skipped)・타임아웃(TimedOut) 중 하나의 상태를 가지며, 후속 액션은 기본값으로 “직전 액션이 성공한 경우”에만 실행됩니다. 이 조건은 액션마다 변경할 수 있어, “실패한 경우”, “타임아웃된 경우”에 실행되는 분기를 만들 수 있습니다3.

설정 위치는 처음 보면 좀처럼 찾을 수 없습니다. 디자이너에서 대상 액션(또는 스코프)의 “…”(점 3개 메뉴)를 열고 “실행 조건 구성”을 선택하면, 직전 액션마다 4가지 상태의 체크박스가 나열된 패널이 나타납니다11. 여기서 필요한 상태에 체크를 넣습니다. 한 가지 주의할 점이 있다면, 반드시 하나는 선택되어 있어야 하므로, 기본값인 “성공한 경우”를 해제하는 것은 다른 상태에 체크를 넣은 후여야 한다는 순서입니다3. 참고로 실행 조건 구성은 “바로 앞의 액션”에 한정되지 않고, 여러 선행 액션을 지정해 각각에 상태를 할당할 수도 있습니다3.

이를 스코프에 적용하면 Try-Catch-Finally가 됩니다. 스코프는 포함된 액션 전체의 결과를 하나로 모아 하나의 상태로 갖기 때문에, “Try 스코프 안 어딘가에서 실패하면 Catch 스코프를 실행한다”는 구성이, 액션 단위로 조건을 설정해 돌리는 것보다 압도적으로 유지보수하기 쉬워집니다34.

성공실패 / 타임아웃아니오트리거Try 스코프본처리를 여기에 모은다Finally 스코프실행 조건 구성 - 성공, 실패, 건너뜀, 타임아웃 모두Catch 스코프실행 조건 구성 - 실패, 타임아웃된 경우result 함수 + 배열 필터링으로실패한 액션과 이유를 추출Teams / 메일로 담당자에게 알림플로우 이름, 실패 단계, 오류 상세, 실행 URL뒷정리 - 대장 상태 열 갱신Catch를 거쳤는가Terminate상태 - Failed로 실행 종료정상 종료

구성의 요점은 4가지입니다.

  • Catch 스코프의 실행 조건 구성은 「실패한 경우」와 「타임아웃된 경우」 둘 다 선택합니다. 기본값인 「성공한 경우」는 해제합니다. 실패만 선택하면 승인 대기나 지연 액션의 타임아웃이 빠져나갑니다3.
  • Catch 안에서 실패의 내용을 꺼냅니다. result('Try 스코프 이름') 함수는 스코프 바로 아래 액션의 결과(상태・입출력・오류 본문)를 배열로 반환하므로, “배열 필터링”(Filter array)으로 상태가 Failed 또는 TimedOut인 것으로 좁히면, 실패한 액션 이름과 오류 메시지를 알림에 담을 수 있습니다34. Failed만으로 좁히면, 타임아웃을 거쳐 Catch에 들어왔을 때 추출 결과가 비어 버려 알림에서 정작 중요한 실패 단계가 빠지게 됩니다. 아울러 workflow() 함수에서 실행 ID를 꺼내 실행 기록으로 바로 가는 링크 URL을 만들어 두면 조사가 단숨에 쉬워집니다(식은 다음 절)4.
  • Finally 스코프의 실행 조건 구성은 4가지 상태를 모두 선택합니다. 성공이든 실패든 반드시 거쳐야 할 뒷정리(임시 파일 삭제, 대장 상태 열 갱신 등)를 여기에 둡니다.
  • 실패한 실행은 마지막에 Terminate 액션으로 “실패”로 끝냅니다. 여기가 가장 놓치기 쉬운 부분입니다. Catch가 정상적으로 완료되면 플로우 실행 전체로서는 마지막 액션이 성공으로 끝난 것이 되어, 실행 기록상 “성공”으로 기록됩니다. 즉 알림만 하고 끝내면 실행 기록에서는 실패가 보이지 않게 되어 모니터링과 이후 집계에서 누락됩니다. Terminate로 상태 Failed와 오류 메시지를 설정하고 종료하면 실행 기록에도 실패로 남습니다43. 다만 Terminate를 Catch 스코프의 맨 끝에 직접 두면 안 됩니다. Terminate는 그 시점에서 실행 전체를 즉시 종료시키기 때문에, 후속 Finally 스코프가 실행되지 않아 오류 시일수록 필요한 뒷정리가 생략됩니다. 그림처럼 Catch에서는 실패 플래그(변수)를 세워 알림까지만 하고, Finally의 뒷정리를 거친 후 플래그를 판정해 실패 시에만 Terminate로 종료하는 순서로 만듭니다.

참고로 실행 조건 구성은 승인 플로우의 타임아웃 분기(독촉・에스컬레이션)에서도 핵심이 되는 부품입니다. 구체적인 구성 방법은 「Power Automate로 승인 플로우 만들기 ── 종이와 메일의 품의・신청을 전자화하다」에서 다루고 있습니다.

Catch의 내용 ── 실패한 액션과 실행 URL을 식으로 꺼내기

여기가 구현의 핵심이므로 식까지 적어 둡니다. Try 스코프의 이름을 Try로 했을 경우, “배열 필터링”(Filter array)의 설정은 다음과 같습니다. 조건은 “고급 모드로 전환”으로 바꿔 식을 직접 작성합니다34.

시작(From):  @result('Try')
조건(고급 모드): @or(equals(item()['status'], 'Failed'), equals(item()['status'], 'TimedOut'))

result()가 반환하는 요소 하나하나에서 다음 값을 꺼낼 수 있습니다. 알림 본문에는 이 4가지를 나열해 두면 실행 기록을 열기 전에 대략적인 짐작이 됩니다3.

꺼내고 싶은 정보
실패한 액션 이름 item()['name']
상태(Failed / TimedOut) item()['status']
오류 코드 item()['code']
응답 본문(오류 메시지) item()['outputs']['body']

실행 기록으로의 바로 가기 링크는 workflow() 함수로 만듭니다. 이 함수는 플로우의 ID(name), 환경 이름(tags.environmentName), 플로우의 논리적 이름(tags.logicAppName), 실행의 ID(run.name) 등을 가진 객체를 반환하므로, URL은 다음과 같은 형태가 됩니다4.

concat('https://make.powerautomate.com/environments/', workflow()?['tags']?['environmentName'],
       '/flows/', workflow()?['tags']?['logicAppName'],
       '/runs/', workflow()?['run']?['name'])

공식 문서는 workflow()의 출력을 “JSON 구문 분석”(Parse JSON)으로 분석한 후 “작성”(Compose) 액션으로 URL을 조립하는 절차로 설명하고 있습니다4. 어느 쪽이든 결과는 같지만, 포털의 URL은 바뀔 수 있으므로 만든 직후에 생성된 링크를 한 번 클릭해, 원하는 실행 기록이 열리는지 확인하시기 바랍니다. 참고로 같은 문서는 자체 로그 출력을 지나치게 늘리면 액션 수와 실행 시간이 늘어나 역효과가 난다고도 주의를 주고 있습니다4. 담을 항목은 “플로우 이름・실패 액션・오류・실행 URL”의 4가지로 좁히는 것이 실무적입니다.

5. 실패를 알아차리는 구조 ── 알림과 가시화

오류 처리를 만들어도 아무도 실패를 알아차리지 못하면 의미가 없습니다. “알아차리는 구조”는 기본 알림에 의지하지 않고 여러 층으로 설계합니다.

기본 실패 알림 메일을 정확히 이해한다

Power Automate는 실패 시 메일 알림을 보내는 구조를 갖고 있지만, 사양을 모른 채 의지하면 빈틈투성이입니다. 알림은 두 종류입니다5.

  • 실행 단위 실패 알림: 실행이 실패한 직후에 전송되지만, 전송되는 것은 연결 끊김・스로틀링・알려진 커넥터 오류 등 「알려진 해결 방법이 있는 실패」로 판정된 경우뿐입니다. 일반적인 액션 실패에서는 전송되지 않습니다. 수신 대상은 소유자와 공동 소유자(실행 전용 사용자는 포함되지 않음)이며 관리자에게는 전송되지 않습니다. 게다가 한 번 전송되면 같은 플로우에는 28일간의 쿨다운이 있어, 그동안의 실패에는 추가 알림이 오지 않습니다. 실행 단위 알림은 모든 플로우에서 기본값으로 활성화되어 있는 것도 아니라, 플로우 설정에서 확인이 필요합니다5.
  • 주간 실패 다이제스트: 환경을 넘나든 실패 요약이 주 1회 전송됩니다. 실행 단위 알림이 전송되지 않는 일반적인 실패도 여기에는 포함됩니다5.

이 외에, 특정 오류에 대해서는 복구 절차가 포함된 “복구 힌트” 메일이 소유자에게 전송됩니다(플로우별로 끄기도 설정 가능)7. 정리하면 기본 알림은 “처음의 연결 끊김은 알아차릴 수 있지만, 업무 데이터 기인의 실패나 두 번째 이후의 실패는 빠져나가기 쉬운” 구조입니다. 중요한 플로우에서는 4장의 Catch 블록에서 보내는 자체 알림을 필수로 여기시기 바랍니다.

Catch에서의 알림 설계 ── 알림 플로우 자체가 실패하는 경우

자체 알림에도 설계 포인트가 있습니다.

  • 수신 대상을 개인으로 하지 않습니다. 담당자 개인 앞으로 하면 부재・퇴사 시 아무에게도 전달되지 않습니다. 공유 메일함이나 Teams 채널로 보내는 것이 공식 문서에서도 권장됩니다11.
  • 알림 경로를 본처리와 분리합니다. 흔히 있는 사고가 “Outlook 연결이 끊겨서 플로우가 실패하고, 실패 알림도 같은 Outlook 연결이라 보낼 수 없다”는 동반 실패입니다. 인증 만료가 원인인 실패에서는 같은 연결을 사용하는 알림 액션도 동시에 실패합니다. 알림은 Teams 게시 등 본처리와 다른 커넥터・다른 연결로 하거나, 알림 전용의 작은 플로우로 분리해 호출하면 동반 실패의 위험을 낮출 수 있습니다. 그래도 “알림의 알림”을 무한히 만들 수는 없으므로, 마지막 보루로 다음의 정기 확인을 둡니다.
  • 알림에는 조사에 필요한 정보를 전부 담습니다. 플로우 이름, 실패한 액션 이름, 오류 메시지, 실행 기록으로의 바로 가기 링크. 이것이 없으면 알림이 와도 “무언가가 실패했다” 이상은 알 수 없어 방치되기 쉽습니다4.

가시화와 정기 확인

  • 플로우 검사기: 저장 전에 플로우 정의의 오류나 경고를 검출해 줍니다. 만들고 난 후 한 번 확인하는 습관을 들입니다12.
  • 실행 기록의 정기 확인: 플로우의 실행 기록은 기본값으로 28일밖에 표시되지 않습니다6. 솔루션에 포함시킨 플로우는 Dataverse에 실행 기록의 메타데이터를 남길 수 있지만, 이쪽도 기본 보존 기간은 28일이며 연장은 관리자 측의 설정입니다13. 운영 중인 플로우에 대해서는 실패뿐 아니라 “취소 상태의 실행”(동시 실행 제어가 원인인 경우가 있음)이나 “실행 수의 급감”(트리거가 작동하지 않는 징후)까지 포함해 주 1회 정도 확인하는 운영이 권장됩니다11.
  • 관리자의 일원화된 모니터링: 실행 단위 알림 메일이 전송되지 않는 실패까지 포함해 전체를 보려면, Power Platform 관리 센터의 Monitor(모니터링)가 가장 포괄적입니다. 플로우 단위・환경 단위로 실패 건수와 오류 상세를 확인할 수 있습니다5.

정기 실행 플로우의 경우에는 “애초에 시작되었는가”의 모니터링도 필요해집니다. 영업일 판정이나 월말 처리를 포함한 정기 실행 설계는 「Power Automate의 정기 실행 플로우와 영업일 설계」에서 다루고 있습니다.

6. 재실행과 멱등성 ── “두 번 실행되어도 깨지지 않는” 것을 만든다

실패에 대한 대응은 탐지로 끝나지 않습니다. “실패한 부분을 다시 하는” 조작과 “다시 해도 깨지지 않는” 설계가 세트로 필요합니다.

재제출(resubmit)의 사양

실패한 실행은 실행 기록에서 재제출(Resubmit)로 다시 할 수 있습니다. 같은 트리거 데이터로 다시 실행하는 조작으로, 일시적 장애(500/502 등)라면 그대로 재제출, 플로우 정의의 오류가 원인이라면 수정해 저장한 후 재제출하면 수정된 정의로 다시 실행됩니다7. 실행 기록 목록에서는 한 번에 최대 20건까지 한꺼번에 재제출할 수 있어, 대량 실패 시의 복구에 사용할 수 있습니다. 수동 기동(즉시 트리거) 플로우의 경우, 자신의 실행은 언제든 재제출할 수 있지만, 다른 사용자가 기동한 실행의 재제출은 테넌트 설정에서 관리자가 허용해야 합니다14.

여기서 중요한 것은, 재제출은 플로우를 처음부터 다시 실행한다는 점입니다. 10단계 중 8단계에서 실패한 실행을 재제출하면, 성공했던 1~7단계도 다시 실행됩니다. “메일 발송은 이미 끝났는데 한 번 더 보내졌다”, “대장에 같은 행이 두 줄 생겼다”는 사고는 여기서 일어납니다.

멱등성 ── 두 번 실행되어도 안전한 설계

그래서 같은 입력으로 몇 번을 실행해도 결과가 같아지는(멱등한) 설계를 처음부터 넣어 둡니다. 재제출뿐 아니라 트리거의 중복 기동이나 병렬 실행에도 효과가 있는, 오류 설계의 핵심입니다.

  • 처리 완료 플래그를 둡니다. SharePoint 목록 등의 대장에 “상태” 열(미처리/처리 중/처리 완료)을 두고, 플로우 시작 부분에서 상태를 확인해 처리 완료라면 그 자리에서 종료하고, 처리를 마치면 상태를 갱신합니다. 이렇게 해 두면 재제출해도 이중 처리가 되지 않습니다. 다만 플래그는 갱신 순서까지 정해야 비로소 기능합니다. 메일 발송이나 기간 시스템 등록처럼 외부에 미치는 부작용은, 실행 직전에 “처리 중”으로 갱신한 후 실행하고, 완료 후에 “처리 완료”로 합니다. 부작용 이후・플래그 갱신 이전에 실패한 실행은 “처리 중” 상태로 남아, 부작용이 이루어졌는지 알 수 없는 상태가 됩니다. 이 행을 기계적으로 재제출하면 이중 발송이 될 수 있으므로, “처리 중” 행은 자동 재실행 대상에서 제외하고, 실제 발송 결과・등록 결과와 대조한 후 사람이 “처리 완료”나 “미처리”로 되돌리는 운영으로 합니다. 안심하고 재실행해도 되는 것은 “미처리”로 멈춰 있는 행뿐입니다.
  • “생성”이 아니라 “있으면 갱신, 없으면 생성”(upsert)으로 합니다. 고유한 키(주문 번호, 신청 ID 등)로 기존 행을 검색해, 있으면 갱신, 없으면 생성하는 분기로 만듭니다. 무조건적인 “항목 만들기”는 재실행할 때마다 중복 행을 쌓아 올립니다. 반대로 말하면 고유 키가 없는 데이터는 멱등하게 만들 수 없으므로, 대장 설계 단계에서 키 열을 정해 두는 것이 전제가 됩니다.
  • 트리거 조건으로 불필요한 기동을 막습니다. “항목이 생성 또는 변경되었을 때” 트리거의 플로우가 자기 자신의 다시 쓰기로 재기동되는 것 같은 중복 기동은, 후단의 조건 분기가 아니라 트리거 조건(trigger conditions)으로 막습니다. 트리거 조건을 만족하지 않는 이벤트에서는 실행 자체가 발생하지 않으므로, 실행 횟수도 요청 수도 소비하지 않습니다8.

한 가지 주의할 점이 있습니다. 처리 완료 플래그나 upsert 같은 “확인하고 나서 쓰는” 방식은, 재제출 같은 순차적인 재시도에는 효과가 있지만, 단독으로는 원자적인 보호가 아닙니다. 중복된 트리거 이벤트가 거의 동시에 2개 발생하면, 양쪽 실행이 “미처리”를 읽은 후 양쪽이 처리를 진행하는 경합이 일어날 수 있습니다. 병렬 기동이 있을 수 있는 플로우에서 확실히 중복을 막으려면, 다음 절의 동시 실행 제어로 병렬도를 1로 만들어 직렬화하는 방법이나, 저장 대상 쪽에서 고유 키 제약을 강제할 수 있는 구조(데이터베이스의 고유 제약 등)를 사용해 쓰기 시점에 중복 생성을 실패시키는 설계를 함께 사용하시기 바랍니다.

동시 실행 제어(concurrency control)와 순서의 트레이드오프

이중 실행과 함께 문제가 되는 것이 “동시 실행”과 “순서”입니다. 기본값에서는 트리거 조건을 만족하는 이벤트가 동시에 다수 발생하면 플로우는 몇 개든 병렬로 실행됩니다1. 대장의 같은 행을 여러 실행이 동시에 읽고 쓰면, 오래된 값을 읽어 덮어쓰는(더티 리드) 불일치가 일어날 수 있습니다15.

트리거 설정의 동시 실행 제어(Concurrency Control)를 켜면 병렬 실행 수(병렬도)를 1~100으로 지정할 수 있습니다. 병렬도를 1로 하면 실행이 한 번에 하나가 되어 순서대로 처리하는 것에 가까워집니다115. 다만 이 스위치에는 무거운 주의점이 있습니다.

  • 한 번 켜면 되돌릴 수 없습니다. 끄려면 트리거를 삭제하고 다시 만드는 수밖에 없습니다1. 동시 실행 제어는 되돌릴 수 없으므로, 적용한다면 액션 수가 적은 플로우(필요하다면 하위 플로우로 분리해서)로 한정하는 것이 권장됩니다15.
  • 놓치는 위험이 생깁니다. 동시 실행 제어가 켜져 있을 때, 대기할 수 있는 실행 수는 “10+병렬도”까지이며, 이 상한에 도달한 동안 도착한 트리거는 커넥터 측에서 재시도되지만, 상한 초과가 오래 지속되면 실행에 이르지 못할 가능성이 있습니다. 모든 트리거를 확실히 실행으로 연결하고 싶은 플로우에서는 동시 실행 제어를 끈 상태로 두도록 공식 문서가 명시하고 있습니다1. 실행 기록이 취소 상태투성이라면 이 설정이 원인인 경우가 있습니다11.

즉 “순서를 지킨다”와 “놓치지 않는다”는 트레이드오프입니다. 병렬도 1의 직렬화는 유량이 적고 순서가 중요한 처리(대장의 연번 채번 등)에는 유효하지만, 피크 시에 대량의 이벤트가 오는 처리에 안이하게 사용해서는 안 됩니다. 순서와 완전성이 둘 다 엄격하게 필요하다면, 8장에서 말하듯 Power Automate 밖에서 설계해야 할 영역으로 들어가게 됩니다.

7. 운영 투입 전 설계 체크리스트

새 플로우를 운영에 올리기 전에 최소한 여기까지는 확인합니다. 전부를 첫날에 갖추는 것이 이상적이지만, 도입 장벽을 낮추기 위해 “최소한”(이것이 없으면 사고가 보이지 않음)“여유가 있으면”(운영에 올린 후 한 달 이내에 채움)의 2단계로 나누었습니다.

# 구분 확인 항목 관련 장
1 최소한 실패의 4가지 분류(일시 장애/데이터 기인/인증 만료/사양 변경)별로 이 플로우에서 무엇이 일어나는지 상정했는가 2장
2 여유가 있으면 재시도 정책은 기본값 그대로여도 되는가. 429가 발생할 것으로 예상되는 연결 대상이라면 요청 수 자체를 줄일 수 없는가 3장
3 최소한 본처리는 Try 스코프에 모여 있는가. Catch의 실행 조건 구성에 「실패」와 「타임아웃」 둘 다 선택했는가 4장
4 최소한 Finally의 뒷정리를 마친 후, 실패 플래그에 따라 Terminate(상태: Failed)로 종료하는 순서로 되어 있는가. 실패를 묻어 버리지 않는가 4장
5 최소한 실패 알림은 자체적으로 만들었는가. 수신 대상은 공유 메일함/Teams 채널인가. 본처리와 다른 경로인가 5장
6 여유가 있으면 알림에 플로우 이름・실패 액션・오류 상세・실행 URL이 들어 있는가 5장
7 여유가 있으면 실행 기록의 주간 확인(실패・취소・실행 수 급감)을 누가 할지 정했는가 5장
8 최소한 재제출되어도 안전한가. 처리 완료 플래그나 upsert로 멱등하게 되어 있는가. 고유 키는 있는가 6장
9 최소한 자기 트리거나 중복 기동을 트리거 조건으로 막고 있는가 6장
10 여유가 있으면 동시 실행 제어를 사용한다면 되돌릴 수 없다는 점과 놓칠 위험을 이해한 상태인가 6장
11 여유가 있으면 연결은 누구의 것인가. 공동 소유자를 설정해 담당자 부재 시에도 재인증・수정할 수 있는가 2장
12 여유가 있으면 플로우가 자동으로 꺼졌을 때(연속 실패 14일 등) 알아차릴 수단은 있는가 2・5장

12개 항목이나 되냐고 생각할 수 있지만, 운영 첫날에 필요한 것은 “최소한”의 6개 항목뿐이며, 게다가 절반 이상은 처음 한 번만 생각하면 되는 항목입니다. “여유가 있으면”의 6개 항목도 방치해도 된다는 뜻이 아니라, 움직이기 시작한 후 차분히 채울 수 있다는 구분입니다. 반대로 이것을 건너뛰고 운영에 올린 플로우의 “후속 보완”은, 동작 중인 것을 건드리는 두려움도 겹쳐 대체로 실시되지 못한 채 사고를 맞이합니다.

8. 어디까지 Power Automate로 할 것인가

오류 처리를 파고들다 보면 Power Automate의 담당 범위를 넘어서는 요건이 보이기 시작합니다. 선긋기의 기준을 몇 가지 들어 보겠습니다.

상황 판단
실패하면 알리고, 사람이 확인해 재제출하면 되는 업무 Power Automate로 충분. 이 글의 패턴으로 족함
여러 시스템을 순서대로 갱신하고, 도중에 실패하면 갱신된 부분을 되돌려야 함(보상 트랜잭션) 플로우로 만들면 복잡해지기 쉬움. 처리를 한꺼번에 받는 API 측의 정비나 수탁 개발 영역
순서 보장・배타 제어・놓침 제로가 동시에 요구됨(채번, 재고 배정, 회계 연계 등) 동시 실행 제어의 트레이드오프(6장)를 고려하면, 큐나 데이터베이스의 트랜잭션을 사용할 수 있는 개발 영역이 안전
실패 시 동작을 포함한 자동 테스트・변경 이력・리뷰가 필수 플로우 정의의 단위 테스트는 어려움. Git으로 관리할 수 있는 PowerShell이나 .NET으로
수만 건 규모의 데이터를 매번 처리하고, 실패한 행만 재처리하고 싶음 플로우의 반복 처리는 대량 데이터에 적합하지 않음. 배치 처리 설계가 필요

판단의 감각으로는 “실패했을 때의 복구 절차를 말로 설명할 수 있는 동안은 Power Automate, 그림을 그리지 않으면 설명할 수 없게 되면 개발 영역” 정도로 보고 있습니다. 특히 보상 트랜잭션(A사 시스템에는 등록 완료, B사 시스템은 실패, 그럼 A를 취소할 것인가?)이 필요한 업무는 플로우의 겉모습 이상으로 복잡해, Terminate와 알림만으로는 수습되지 않습니다. 작업 스케줄러나 PowerShell과의 구분 사용까지 포함한 판단은 「Power Automate와 PowerShell・작업 스케줄러의 구분 사용」에서 정리하고 있습니다.

9. 정리

“동작하던 플로우가 멈춰 있었다”는 불운이 아니라 거의 설계의 문제입니다. 플로우는 반드시 실패합니다. 실패의 4가지 분류 중 재시도가 돌봐주는 것은 일시적 장애뿐이며, 데이터 기인・인증 만료・사양 변경은 Try-Catch에 의한 포착, Terminate에 의한 기록, 자체 알림, 그리고 주간 실행 기록 확인이라는 다층 구조로 잡아낼 수밖에 없습니다. 기본 실패 알림 메일은 조건부・28일 쿨다운 포함의 제한적인 구조이며, 이에 의지한 운영은 반드시 빠져나감을 일으킵니다.

그리고 실패에 대한 대비의 핵심은 알림보다 멱등성입니다. 처리 완료 플래그와 upsert로 “두 번 실행되어도 깨지지 않는” 형태로 만들어 두면 재제출도 트리거의 중복도 두렵지 않게 되어, 복구는 “실패한 부분을 골라 재제출”로 끝나게 됩니다. 반대로 보상 트랜잭션이나 엄격한 순서 보장이 필요한 업무는 Power Automate로 무리하게 만들어 넣지 말고 개발 영역으로 빼내는 판단이 장기적으로는 저렴하게 먹힙니다. 움직이기 시작한 날이야말로 이 체크리스트를 한 바퀴 돌아보시기 바랍니다.

관련 글

관련 상담 영역

합동회사 코무라소프트는 Power Automate 플로우의 오류 처리・운영 설계 리뷰부터, 플로우로는 수습되지 않는 순서 보장・트랜잭션 요건의 시스템화까지 다루고 있습니다.

참고 링크

  1. Microsoft Learn, Limits of automated, scheduled, and instant flows. 기본 재시도 정책이 성능 프로필별(Low는 최대 2회・약 5분 단위, Medium/High는 최대 12회・7초부터 약 1시간까지)로 다르다는 점, 재시도 설정 상한(90회・최소 간격 5초・최대 지연 1일), 실행 기간 30일, 계속 실패하는 플로우/계속 스로틀링되는 플로우가 14일 만에 꺼진다는 점, 90일간 트리거되지 않은 플로우가 꺼질 수 있다는 점, 동시 실행 제어가 기본값으로 꺼져 있고 병렬도 1~100(켤 때의 기본값 25)이며 트리거를 삭제하고 다시 만들지 않는 한 되돌릴 수 없다는 점, 대기 실행 수가 “10+병렬도”이며 초과 트리거가 실행에 이르지 못할 가능성이 있다는 점, 재시도나 페이지네이션을 포함한 성공・실패 모든 액션이 요청 수에 카운트된다는 점에 대해.  2 3 4 5 6 7 8 9 10 11

  2. Microsoft Learn, Reducing risk and planning for error handling. 자동화는 반드시 실패할 수 있다는 전제, 커넥터 이용 시 실패 요인(유지보수에 의한 중단, 소프트웨어 결함, API 버전 변경), 모든 자동화에 공통되는 실패 요인(비밀번호 변경, 순간적인 네트워크 장애), 재시도 정책의 존재에 대해.  2

  3. Microsoft Learn, Handle workflow errors and exceptions in Azure Logic Apps. 재시도 정책이 408・429・5xx 응답과 타임아웃을 대상으로 한다는 점, 기본값이 지수 간격 정책이라는 점, 재시도 종류(기본/없음/고정/지수), 실행 조건 구성(run after)의 4가지 상태(Succeeded/Failed/Skipped/TimedOut), 기본값을 해제하기 전에 다른 상태를 선택해야 한다는 점(항상 하나 이상의 상태가 선택되어 있어야 한다는 점), 여러 선행 액션에 각각 상태를 지정할 수 있다는 점, 스코프의 상태 평가와 run after에 의한 예외 포착, result() 함수와 배열 필터링에 의한 실패 액션 추출(@result('스코프 이름')@equals(item()['status'], 'Failed')), result()의 요소 하나가 갖는 속성(name・status・code・outputs・clientTrackingId 등), 분기가 실패로 끝나지 않으면 실행 전체가 실패가 되지 않는 상태 평가에 대해.  2 3 4 5 6 7 8 9 10 11 12 13 14

  4. Microsoft Learn, Employ robust error handling. 스코프에 의한 Try-Catch 패턴, 실행 조건 구성에서의 실패 분기, Catch 스코프에서 Filter array에 의한 result() 좁히기, 지수 재시도의 권장, Terminate 액션으로 상태 Failed를 설정해 실행을 실패로 종료시키는 것, workflow() 함수가 반환하는 JSON 스키마(name・tags.environmentName・tags.logicAppName・run 등)와 Parse JSON+Compose 액션에 의한 실행 기록 URL 조립, 자체 로그를 지나치게 늘리면 액션 수와 성능에 영향을 준다는 주의점, 오류의 로그 기록과 알림 권장에 대해.  2 3 4 5 6 7 8 9 10 11 12 13

  5. Microsoft Learn, Understand flow failure notifications. 실행 단위 실패 알림이 「알려진 해결 방법이 있는 실패」(연결 끊김・스로틀링 등)로 한정된다는 점, 수신 대상이 소유자・공동 소유자이며 실행 전용 사용자와 관리자에게는 전송되지 않는다는 점, 동일 플로우에 대한 28일 쿨다운, 실행 단위 알림이 모든 플로우에서 기본값으로 활성화되어 있지 않다는 점, 주간 실패 다이제스트, Power Platform 관리 센터의 Monitor에서 전체 실패를 확인할 수 있다는 점에 대해.  2 3 4 5

  6. Microsoft Learn, Missing runs or triggers history for a flow. 플로우의 실행 기록 데이터가 기본값으로 28일간만 보존되어 실행 기록 페이지에 표시되지 않게 된다는 점에 대해.  2

  7. Microsoft Learn, Troubleshoot a cloud flow. 복구 힌트(repair tips) 메일이 소유자에게 전송되며 플로우별로 끌 수 있다는 점, 28일간의 실행 기록에서 실패 단계를 특정하는 절차, 500/502 같은 일시적 오류에서의 재제출, 플로우 수정・저장 후 재제출하면 수정된 구성으로 다시 실행된다는 점에 대해.  2 3

  8. Microsoft Learn, Customize your triggers with conditions. 트리거 조건에 의해 조건을 만족하지 않는 이벤트에서는 실행 자체가 발생하지 않는다는 점, 후단의 조건 분기로 버리는 방식은 실행과 API 요청을 소비해 버린다는 점에 대해.  2

  9. Microsoft Learn, “There is a problem with the flow’s trigger” error shown in a flow’s run history. 트리거 자체가 실패하면 플로우가 실행되지 않는다는 점, 4xx 계열의 트리거 실패는 연결 변경(비밀번호 만료 등) 등 사용자가 수정해야 할 문제이며 5xx 계열은 일시적인 시스템 문제라는 점에 대해. 

  10. Microsoft Learn, Data policies. 데이터 정책(DLP 정책)이 관리자가 커넥터로의 접근을 제어해 조직 데이터가 의도치 않게 노출될 위험을 낮추는 가드레일이라는 점, 정책을 위반한 앱・플로우가 중단(suspended)이나 검역 상태에 놓여 동작하지 않게 된다는 점에 대해. 

  11. Microsoft Learn, Fix connection failures in cloud flows. 플로우의 중단(suspended) 상태, 실행 조건 구성을 이용한 실패 알림의 병렬 분기와 조작 절차(액션의 “…”에서 “실행 조건 구성”을 열어 “실패한 경우”만 선택), 중요 플로우의 알림을 공유 메일함이나 Teams 채널로 보내는 권장, 주간 실행 기록 확인(실패・취소・실행 수 급감), 취소 상태의 실행이 동시 실행 설정에 기인할 수 있다는 점, DLP 정책 변경이 예고 없이 즉시 적용되어 여러 플로우가 동시에 망가지는 원인이 될 수 있다는 점, 서비스 주체 연결이 비밀번호 변경이나 퇴사의 영향을 받지 않는다는 점에 대해.  2 3 4 5 6

  12. Microsoft Learn, Tools to test your automation. 플로우 검사기에 의한 작성 시 오류 검출, 복구 힌트, 실행 조건 구성을 이용한 자체 오류 알림 설정에 대해. 

  13. Microsoft Learn, Manage cloud flow run history in Dataverse. 솔루션 대응 플로우의 실행 기록이 Dataverse의 FlowRun 테이블에 저장된다는 점, 기본 보존 기간이 28일이며 관리자가 보존 기간을 변경할 수 있다는 점에 대해. 

  14. Microsoft Learn, Cancel or resubmit flow runs in bulk. 실행 기록에서 한 번에 최대 20건까지 재제출・취소할 수 있다는 점, 즉시 트리거에서 다른 사용자가 기동한 실행의 재제출에는 테넌트 설정(Power Automate flow run resubmission)의 활성화가 필요하다는 점에 대해. 

  15. Microsoft Learn, Optimize Power Automate triggers. 트리거가 기본값으로 조건을 만족하는 실행을 동시에 진행시킨다는 점, 더티 리드에 의한 불일치, 동시 실행 제어가 기본값으로 꺼져 있다는 점, 병렬도 1로 한 번에 1개 실행이 되어 순서가 필요한 처리에 유효하다는 점, 동시 실행 제어가 되돌릴 수 없으며 액션 수가 적은 플로우(하위 플로우)에 대한 적용이 권장된다는 점에 대해.  2 3

같은 태그를 공유하는 최신 기사입니다. 더 가까운 주제로 지식을 넓힐 수 있습니다.

이 기사와 가까운 토픽 페이지입니다. 기사를 출발점 삼아 관련 서비스와 다른 기사로 이어집니다.

이 기사는 다음 서비스 페이지로 이어집니다. 가까운 입구부터 확인해 주세요.

자주 묻는 질문

이 기사 주제에 대해 상담 시 자주 나오는 질문을 모았습니다.

Power Automate 플로우가 실패하면 자동으로 알림 메일이 오나요?
제한적으로만 옵니다. 실행 단위 실패 알림 메일은 연결 끊김이나 스로틀링 등 「알려진 해결 방법이 있는 실패」로 판정된 경우에만 소유자・공동 소유자에게 전송되는 구조이며, 일반적인 액션 실패에서는 전송되지 않습니다. 게다가 한 번 전송되면 같은 플로우에 대해 28일간의 쿨다운이 있어, 그동안은 추가 알림이 오지 않습니다. 실행 단위 실패 알림은 모든 플로우에서 기본값으로 활성화되어 있는 것도 아닙니다. 확실히 알아차리려면 Catch 블록에서 자체적으로 Teams나 메일로 알리는 설계를 넣어 두는 것을 권장합니다.
Power Automate의 표준 재시도는 몇 번, 어떤 간격으로 이루어지나요?
액션의 요청이 타임아웃되거나 408・429・5xx 계열 응답으로 실패한 경우, 기본값으로는 지수적으로 간격을 늘려가며 자동으로 재시도됩니다. 횟수는 플로우의 성능 프로필(실질적으로는 라이선스 계층)에 따라 다르며, Microsoft 365 라이선스 등의 낮은 프로필에서는 최대 2회, Power Automate Premium이나 Process 라이선스 등의 중・고 프로필에서는 최대 12회입니다. 액션 설정에서 재시도 정책을 「없음・고정 간격・지수 간격」으로 변경할 수 있으며, 횟수는 최대 90회까지 설정할 수 있습니다. 400이나 404 같은 데이터・설정에 기인한 오류는 재시도 대상이 아닙니다.
실패한 플로우 실행을 다시 하려면(재제출하려면) 어떻게 해야 하나요?
실행 기록에서 실패한 실행을 열고 「재제출」을 선택하면 같은 트리거 데이터로 실행을 다시 할 수 있습니다. 플로우 정의의 오류가 원인인 경우에는 플로우를 수정해 저장한 후 재제출하면 수정된 내용으로 다시 실행됩니다. 실행 기록 목록에서는 한 번에 최대 20건까지 한꺼번에 재제출할 수 있습니다. 주의할 점은 재제출은 플로우를 처음부터 다시 실행하기 때문에, 도중까지 성공했던 실행에서는 이미 성공한 처리가 다시 한번 실행된다는 것입니다. 두 번 실행되어도 결과가 깨지지 않는 멱등한 설계(처리 완료 플래그, 생성이 아닌 갱신 우선 쓰기)로 만들어 두어야 합니다.
플로우가 모르는 사이에 비활성화되는 일이 있나요?
있습니다. 트리거나 액션이 계속 실패하는 플로우는 14일 만에 자동으로 꺼집니다. 스로틀링(제한 초과)이 계속되는 플로우도 마찬가지로 14일 만에 꺼집니다. 또한 90일간 한 번도 트리거되지 않은 플로우도 프리미엄 라이선스나 용량 라이선스를 보유하고 있지 않으면 꺼질 수 있습니다. 실패 방치는 곧바로 플로우 정지로 이어지기 때문에, 실패를 알아차리는 구조와 실행 기록(기본값 28일)의 정기 확인을 운영에 포함시켜 두는 것이 중요합니다.

저자 프로필

기사 저자의 프로필 페이지입니다.

Go Komura

합동회사 코무라소프트 대표

Windows 소프트웨어 개발, 기술 상담, 장애 조사를 중심으로 재현이 어려운 장애 조사와 기존 자산이 남아 있는 프로젝트에 강점이 있습니다.

블로그 목록으로 돌아가기