강의

멘토링

커뮤니티

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

kbm0598님의 프로필 이미지
kbm0598

작성한 질문수

Kotlin + Spring MVC 사용 시 Dispatchers 생략

작성

·

10

0

안녕하세요~

현재 아래 기술 스택을 사용한 API 서버가 존재합니다.

  • Spring Boot 3

  • Kotlin

  • JPA(JDBC)

  • WebClient

예를 들면 아래와 같이 구성되어 있고,

@RestController
class SampleController(
    private val service: SampleService
) {

    @GetMapping("/sample")
    suspend fun start() {
        service.withoutDispatchers()
    }

}

@Component
class SampleClient {

    private val webClient: WebClient by lazy {
        WebClient.builder()
            .baseUrl("https://api.com")
            .build()
    }

    suspend fun fetch(): Int {
        return webClient.get()
            .uri { uriBuilder ->
                uriBuilder.path("/number").build()
            }
            .retrieve()
            .awaitBody()
    }

}

interface SampleRepository : JpaRepository<SampleEntity, Long>
@Service
class SampleService(
    private val client: SampleClient,
    private val repository: SampleRepository,
) {

    suspend fun withoutDispatchers(): Int = coroutineScope {
        // non-blocking
        val deferred: Deferred<Int> = async {
            client.fetch()
        }

        // blocking
        val entity: List<SampleEntity> = repository.findAll()

        deferred.await() + entity.size
    }

}


Controller에서부터 suspend function으로 시작되면 Dispatchers.Unconfined를 사용하여 API 요청에 의해 할당받은 Tomcat 스레드를 그대로 사용하는 것으로 알고 있습니다.

이후 Service 레이어에서 suspend function이 동일하게 Dispatchers.Unconfined를 유지하기 때문에 요청 시 Tomcat 스레드는 그대로 사용되고

 

WebClient 요청 시 Dispatchers.IO를 사용하면,
Tomcat 스레드와 별개로 Dispatchers 스레드 풀에서 스레드를 가져와 사용하는 것으로 알고 있습니다. 1번의 요청에서 Tomcat 스레드 1개 + Dispatchers 스레드 1개 = 총 2개가 사용됩니다.

WebClient 요청 시 Dispatchers.IO를 생략하고 Dispatchers.Unconfined를 유지하면,
코루틴의 재개 시 WebClient 응답을 동일한 Tomcat 스레드가 처리하게 하여 스레드 1개만을 사용하는 것이 서버에 더 효율적이지 않을까? 하는 생각이 들었습니다.
스레드가 Blocking되어도 WebClient의 NIO 이벤트 루프에 들어온 요청은 처리되어 응답에 대한 처리만 대기하고 있을 것이고, 테스트해보았을 때도 WebClient의 요청을 시작한 스레드가 JPARepository를 사용하는 코드에 의해 Blocking되어도 await()에서 문제 없이 응답을 받아올 수 있었습니다.
혹시 제가 생각하지 못한 또 다른 문제가 있을까요?

제가 혹시 잘못 알고 있는 부분이 있거나 Dispatchers.IO를 생략하지 못 하는 이유가 있다면
설명해주시면 감사하겠습니다!

답변

답변을 기다리고 있는 질문이에요
첫번째 답변을 남겨보세요!
kbm0598님의 프로필 이미지
kbm0598

작성한 질문수

질문하기