[Common] Multiple Fetch 병목 현상 해결 with Semaphore

seohyun Kang·2022년 12월 13일
0

Common

목록 보기
7/8

개요

최근 프로젝트에서 아래의 그림과 같이 서버에서 받은 값을 계산하고 계산 값을 바탕으로 주기적으로 서버에 Audit을 요청하는 프로그램을 개발했습니다.

기존 시나리오는 하나의 프로그램에서 하나의 Audit만을 수행하려 했으나, 사용자의 편의성 개선을 위해 무제한 Audit이 가능하도록 개발 방향이 수정되었습니다.

이 과정에서 이슈가 발생했는데 FE에서 동시에 서버에 많은 요청을 보내니 Audit이 요청한 시간에 제대로 서버에 도착하지 못하고 Fetch Request를 하는 과정에서 Delay 되는 문제가 발생했습니다.

문제 상황 정리

서버에 Fetch Request를 하는 과정에서 병목이 발생하였고 요청을 순차적으로 처리할 상호 배제(Mutex) 프로세싱을 적용해야 했습니다.

개발

이미 진행 중인 요청이 있을 경우 후속 요청을 큐(Array)에 밀어 넣은 뒤, 앞선 요청이 완료되었을 때 다음 Audit을 요청하도록 작업했습니다.

// apis.tsx

const auditSemaphore = new Semaphore(20);

const requestPlanetAudit = async () => {
	await auditSemaphore.acquire();
    try {
    	await get(...something)
    } catch(e) {
		throw e;
	} finally {
    	auditSemaphore.release();
    }
}

// Semaphore.tsx

class Semaphore {

  capacity: number;
  waiting: Array<any> = [];

  constructor(capacity: number) {
    this.capacity = capacity;
  }

  acquire(): Promise<void> {
    if (this.capacity > 0) {
      this.capacity--;
      return new Promise((resolve, reject) => {
        resolve();
      });
    } else {
      return new Promise((resolve, reject) => {
        this.waiting.push({ resolve, reject });
        console.log("@@@@ acquire waiting length: " + this.waiting.length)
      });
    }
  }

  release() {
    this.capacity++;
    if (this.waiting.length > 0) {
      this.capacity--;
      this.waiting.shift().resolve();
      console.log("@ release waiting length: " + this.waiting.length)
    }
  }

}

export default Semaphore;

프론트 엔드에서 Worker의 Trigger로 requestPlanetAudit를 실행하면, Semaphore 객체는 capacity를 하나씩 줄이면서 해당 요청을 수행합니다.

요청이 20개를 넘어가게 되면 capacity가 0이 되고 이후 들어오는 requestPlanetAudit 요청은 모두 waiting 배열 변수에 들어갑니다.

마지막으로, requestPlanetAudit가 서버로 응답을 받고 나서 auditSemaphore.release()를 통해 waiting 배열에 들어가 있던 이후 요청이 순차적으로 수행되게 됩니다.

마지막으로

이전에 Chart UI를 그리면서 Chart를 그리는데 필요한 데이터가 많다보니 병목이 발생했고 최초 요청 이후에 들어오는 요청은 탈락 시키는 작업을 하면서 Semaphore라는 개념을 활용했던 기억이 있습니다.

다만, 당시에는 해당 프로세싱이 Semaphore 혹은 Mutex라고 불리는 것도 몰랐고, 어떠한 개념으로 사용해야겠다 보다는 문제 해결을 위해 이렇게 하면 되지 않을까 수준에서 멈췄었습니다.

Audit 프로그램을 개발하면서 Semaphore라는 개념을 확실히 사용해야 했고 이번 프로젝트를 통해 활용 방법에 대해서 깊이 알 수 있는 계기가 되지 않았나 생각합니다.

0개의 댓글