티스토리 뷰
이번 프로젝트에서 여러 서버로 요청을 보내는 기능을 하나 맡게 되었는데, 구현하는 과정에서 겪은 어려움과 어떻게 해결했는지 기록해본다.
내가 맡은 기능은 스케줄을 돌면서 여러 서버로 요청을 보내고 결과를 받아서 처리하는 기능이었다. 기존코드는 한 스케줄이 시작되면 다른 스케줄은 접근할 수 없도록 AtomicBoolean으로 처리가 되어 있었고, 서버를 for문을 돌리며 요청하고 있었다.
그런데 한 가지 문제가 발생했다. 결과를 줘야하는 상대서버에서도 고도화를 진행하면서 응답속도가 현저히 느려졌다. 각 서버를 굳이 for문을 돌리며 요청할 필요가 없었기 때문에 속도를 위해 서버들에 비동기로 요청하는 것으로 변경했다.
서버들에 비동기로 요청하면서 발생하는 문제 중 하나는 비동기작업이 끝났는지 어떻게 알 수 있느냐는 것이었다. 비동기작업이 종료되면 AtomicBoolean값을 변경해서 다음 스케줄이 접근할 수 있도록 해야 했다. 이 부분에 얼마전에 공부했던 CountDownLatch를 적용했다. CountDownLatch는 이와 같이 한 스레드(하나 이상도)가 다른 스레드들의 작업을 기다리도록 할 때 사용할 수 있다. 아래와 같이 작업 시작 전 작업 개수만큼의 카운트다운래치를 생성하고, 작업 종료되면 카운트다운을 시키고(개수 - 1), 개수가 0이 되면 비동기작업이 끝난 것이기 때문에 본작업이 재개된다.
// 서버 개수 만큼의 카운트다운래치 생성
CountDownLatch latch = new CountDownLatch(serverList.size());
// 작업 종료시 카운트다운 시킴
latch.countDown();
// 작업 완료 대기
latch.await();
// 대기중인 작업 개수 조회
int awaitingCount = latch.getCount();
이때 주의할 점은 CountDownLatch는 카운트 값이 0이 될 때까지 대기 중인 스레드는 진행하지 않고 블록되기 때문에 countDown()이 잘 작동할 수 있는 위치에 놔줘야 한다는 것이다.
비동기작업이 완료되었는지 확인하는 데에는 CountDownLatch말고도 AtomicInteger를 사용할 수도 있을 것 같아서 chatGPT에 물어보니 아래와 같이 대답했다.
비동기 작업 완료 확인에는 상황에 따라 CountdownLatch와 AtomicInteger 둘 다 사용될 수 있습니다. 작업의 개수를 미리 알고 있고 그 수가 고정되어 있을 때는 CountdownLatch를 사용하는 것이 편리하며, 작업의 개수가 동적이거나 미리 알 수 없는 경우에는 AtomicInteger를 사용하여 작업의 상태를 추적하는 것이 유용합니다.
나의 경우, 미리 작업 개수를 알고 있고 그 수가 고정되어 있기 때문에 CountDownLatch가 적합했다.
'업무 경험 및 성과' 카테고리의 다른 글
JSESSIONID에서 세션 클러스터링까지 (0) | 2023.07.03 |
---|---|
bootstrap-datepicker로 일 선택, 월 선택 전환 가능하게 만들기 (0) | 2023.06.28 |
산출물 취합에서 공동작업으로, 시간 절약 (0) | 2023.03.26 |
메모리를 과도하게 사용하는 이유를 찾아보자 (0) | 2023.01.30 |
같은 예외일 때 뷰나 데이터를 내려주는 분기처리에 대한 고민 해결 (0) | 2023.01.17 |