인프런 커뮤니티 질문&답변

김영빈님의 프로필 이미지

작성한 질문수

백엔드 애플리케이션 성능 개선하기 - 기초편

응답과 생성을 분리하기

비동기 분리에 대해서 질문드립니다.

24.09.21 22:26 작성

·

93

·

수정됨

1

안녕하세요? 강의쭉 잘 듣고 있습니다.

강의에서 말씀해주시고자 하는 부분은 [IO대기시간이 있는 작업을 비동기로 돌려서 클라이언트쪽에 우선응답을 빠르게 주고, 나머지는 따로 알아서 처리하는 것]으로 이해했습니다. 말씀해주신 방법은 충분히 사용할 수 있는 방법이라고 생각합니다.

 

그런데 조금 논외로, 이렇게 분리하는 방식이 좋은 방향성인가?에 대해서 궁금증이 생기고 사실 이 부분에 대해 최근 현업에서도 꽤 고민하고 있어서 질문을 드립니다. 아무래도 쪼렙 주니어개발자다보니.. 이런 부분에서 부족함과 의문이 많이 있네요 ㅠㅠ

 

제 생각에, 단축 url을 만드는 api가 200을 내려준다고하면 저장까지 올바르게 완료됨을 전제해야한다고 생각합니다. 이렇게 생각하는 이유는, 단축 url을 저장하는 것까지가 일종의 핵심적인 로직에 포함되지 않나? 하는 생각입니다.

 

예를 들어 로그를 찍거나, 혹은 비즈니스로직이여도 그렇게 중요하지 않은 부분이라면 마음편하게 완료를 보장하지 않는 async로 돌려도 될것 같습니다.

하지만 url저장처럼 핵심적인 로직에 관한 부분에 대해서는 200을 내려줄 거면 저장도 올바르게 보장되어야 하지 않나? 하는 생각이 듭니다. 다르게 말하면, 내려준 단축 url이 정상적으로 동작하지 않는데 200을 내려줘도 되나? 에 대한 궁금증입니다.(물론 핵심적인 로직에 대한 판단은 개개인마다 또 상황마다 다를 수 있지만요)

 

결론적으로 여쭤보고 싶은 부분은 아래와 같습니다

1) 비동기로 나누는 부분의 기준이 강사님에게 있으실 것 같은데, 보통 어떤 기준으로 나누시나요?

2) 추가로, 핸들링을 어떤식으로 하시는지도 궁금합니다. 예를 들면 위와 같이 저장하는 로직을 비동기로 뺏을 때, 실패한다면 보통 어떤식으로 핸들링을 하시나요?



답변 2

0

이준형(Foo)님의 프로필 이미지
이준형(Foo)
지식공유자

2024. 09. 24. 23:16

김영빈님 안녕하세요~

이번에도 좋은 질문 감사합니다.

하나씩 답변 드려볼게요.

 

 

먼저 1번에 대해 비동기로 처리할 작업을 결정할 때 저는 다음과 같은 기준을 사용합니다.

  • 응답 시간과 사용자 경험: 사용자가 즉시 결과를 필요로 하지 않는 작업이나, 응답 시간을 단축시키기 위해 백그라운드로 처리해도 되는 작업은 비동기로 처리합니다.

  • 업무 로직의 핵심 여부: 해당 작업이 비즈니스 로직의 핵심 부분인지 판단합니다. 핵심 로직은 동기적으로 처리하여 정확성과 신뢰성을 보장합니다. (이 부분이 말씀하신 것처럼 'url저장처럼 핵심적인 로직에 관한 부분에 대해서는 200을 내려줄 거면 저장도 올바르게 보장되어야 하지 않나? 하는 생각'이 들게하는 부분인데요, 말씀하신 내용이 맞습니다. 핵심적인 로직은 비동기적으로 처리할 때 신중하게 고려해야합니다. 다만 강의에서는 이렇게 분리하여 성능을 개선할 수 있다는걸 보여주면서도, 예제를 지나치게 복잡하지 않게 만들기 위해 활용했습니다)

  • 데이터 일관성 요구사항: 즉각적인 데이터 일관성이 필요하지 않고, 일정 시간의 지연이 허용되는 경우 비동기로 처리합니다.

  • 에러 처리가 중요한 경우: 작업 실패 시 시스템이나 사용자에게 미치는 영향이 크지 않다면 비동기로 처리하고, 실패를 로그에 기록하거나 재시도 메커니즘을 적용합니다.

     

     

    그리고 2번에 대한 내용도 이야기 해보자면,

  • 재시도 로직 구현: 작업이 실패하면 일정 횟수나 조건에 따라 자동으로 재시도하도록 설계합니다. 이때 지수적으로 백오프가 되도록 만듭니다.

  • 메시지 큐 사용: 작업을 메시지 큐에 넣어 안정적인 전달과 처리를 보장하며, 큐 시스템 자체의 재시도 및 장애 처리 기능을 활용합니다.

  • 오류 로그 및 모니터링: 실패한 작업에 대한 상세한 로그를 남기고, 모니터링 시스템을 통해 즉각적인 알림을 받습니다. 비동기적인 처리의 경우 사용자가 즉각적으로 에러를 받지 못하게됩니다. 따라서 로그를 통해 실패를 탐지해야합니다.

  • 트랜잭션 관리: 데이터베이스 트랜잭션을 사용하여 작업의 원자성을 보장하거나, 보상 트랜잭션을 통해 일관성을 유지합니다. 이와 관련해서는 Eventual Consistency에 대한 개념을 찾아보시면 좋을 것 같습니다.

  • 사용자 알림: 필요에 따라 사용자에게 작업 지연이나 실패에 대한 정보를 전달합니다. 설령 실패하더라도 사용자가 인지하는게 중요한 경우도 있습니다. 예를들어 대용량 파일을 전송하는 작업을 했을 때 전송되는동안 사용자를 대기중인 상태로 만들기 vs 비동기적으로 처리하되 실패와 성공 여부를 알려주기 중 선택하라면 일반적으론 후자가 더 좋은 UX를 가질겁니다.

     

     

    우선 생각나는건 이정도인데, 답변이 됐을까요? 지난번에도 그렇고 이번에도 좋은 질문 남겨주시고, 강의 잘 들어주셔서 감사합니다. (_ _)
    또 궁금한 내용 있으면 질문 남겨주세요~

     

0

인프런 AI 인턴님의 프로필 이미지

2024. 09. 21. 22:31

안녕하세요, 인프런 AI 인턴입니다. 김영빈님.

비동기 작업 분리에 대한 고민이시군요. 이와 관련된 유사한 질문 및 답변들을 참고하시면 아래 링크에서 확인할 수 있습니다:

postman에서 API 테스트했을 때 응답 레이턴시 차이가 있는 이유

  • 이 게시물에서는 API 요청 시 첫 번째 요청과 이후 요청의 레이턴시 차이 원인과 관련된 내용이 다루어집니다. 이는 비동기 처리 시에도 중요한 개념입니다.

로그인 한 유저만 접근 가능한 API도 부하테스트가 필요할까요?

  • 부하 테스트와 관련된 내용이지만, 비동기 처리 시 부하 테스트를 어떻게 접근해야 하는지에 관한 간접적인 힌트를 얻을 수 있습니다.

요약

김영빈님이 언급하신 것처럼, 핵심적인 로직의 비동기처리는 신중해야 합니다. 비동기 처리를 할 때의 일반적인 기준은 다음과 같습니다:

  1. 핵심 로직 여부: 핵심 로직이나 즉각적인 결과가 필요한 부분은 동기적으로 처리하는 것이 좋습니다. 즉, 주요 비즈니스 로직이 포함된 부분은 200 응답을 보내기 전에 완료되어야 합니다.
  2. IO 작업: 파일 쓰기, 데이터베이스 읽기/쓰기, 외부 API 호출 등 IO 대기 시간이 큰 작업은 비동기로 처리하여 응답 성능을 향상시킬 수 있습니다.
  3. 실패 핸들링: 비동기 작업이 실패했을 때는 재시도 로직을 포함하거나, 사용자에게 오류를 명확히 전달하는 방식으로 오류를 핸들링해야 합니다.

핸들링 방법은 주로 다음과 같습니다:
- 재시도 로직: 작업 실패 시 재시도 기회를 부여
- 로깅: 실패한 작업에 대한 로깅을 통해 모니터링과 추적 가능
- 알람 도입: 중요 작업의 실패 시 알람을 통해 빠른 대응 가능

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.