티스토리 뷰

 이번 프로젝트에서 여러 서버로 요청을 보내는 기능을 하나 맡게 되었는데, 구현하는 과정에서 겪은 어려움과 어떻게 해결했는지 기록해본다.


 내가 맡은 기능은 스케줄을 돌면서 여러 서버로 요청을 보내고 결과를 받아서 처리하는 기능이었다. 기존코드는 한 스케줄이 시작되면 다른 스케줄은 접근할 수 없도록 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가 적합했다.

300x250
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
글 보관함