뭔 자료찾기도 힘들고 덤프떠서 디버깅안하면 작동원리 모를거같음


webclient + corouitne을 쓰는상황

1. runBlocking하면 해당 쓰레드에서 지지고볶으니까 suspend로 정지가능한 곳에서 넘겨줄때 해당쓰레드에서만 작동하고,

다른 코루틴 쓰레드와는 영향x일 것이다?


2. 컨트롤러에 suspend를 하면안되는이유-> 코루틴이 지맘대로 쓰레드풀만들것이다 or suspend함수로 인해 성능저하 생긴다?


3. GlobalScope를 쓰면안되는이유 -> 코루틴이 쓸데없이 쓰레드풀만들어서일것이다?


4. MVC에 webclient를 쓰면 webflux용 쓰레드풀 따로 더 생기는거 맞음??


gpt임마도 모르는거같은데



GPT

간단히 말해서, 컨트롤러에 suspend를 쓰면 안 되는 이유는 다음과 같음.


1. 스레드 블로킹 이슈: suspend를 쓰면 비동기적으로 작동할 거라고 기대하겠지만, 서블릿 기반 Spring MVC는 기본적으로 스레드 블로킹 방식으로 작동함. 이게 왜 문제냐면, 컨트롤러에 suspend 붙여봤자 결국 워커 스레드에서 블로킹이 발생해서 성능이 좆망함.

2. 비동기 처리의 의미가 없음: Spring WebFlux 같은 리액티브 방식이라면 괜찮겠지만, 서블릿 기반에선 기존의 스레드 기반 비동기 처리 방식이 더 나음. suspend의미가 없어진다는 거지. 차라리 비동기 API를 쓰는 게 맞음.

3. GlobalScope.launch는 쓰레기임: GlobalScope.launch는 진짜 쓰레기 중 쓰레기임. 왜냐면, 앱 전체 스코프에서 코루틴을 관리하는데, 에러 핸들링도 제대로 안 되고, 스코프 관리도 엉망이라 자원 누수가 발생하기 쉬움. 진짜 다루기 까다로움. 차라리 CoroutineScope를 적절히 사용해라.


결론: Spring MVC에선 비동기적으로 돌아가는 코드를 컨트롤러에서 사용하는 건 (특히 서블릿 기반에서는) 좆망임. Spring WebFlux 같은 완전한 비동기 처리 프레임워크로 넘어가면 모를까, 서블릿에서는 suspend는 쓸 필요 없고, GlobalScope는 아예 손대지 말자.


---

스프링 MVC에서 runblocking을 쓰고 webclient의 비동기 api 를 사용할떄

쓰레드 뭐를 쓰는거야?


코루틴이 쓸데없이 쓰레드를 만들어?


---

GPT

스프링 MVC에서 runBlocking을 쓸 때랑 WebClient의 비동기 API를 사용할 때, 각각의 스레드 동작 방식이 다르니까 헷갈릴 수 있는데, 하나씩 까보자.


1. runBlocking이 뭐냐


runBlocking은 코루틴이 완전히 블로킹되는 방식임. 내부적으로는 코루틴을 블로킹식으로 동작하게 만들어서 현재 스레드를 차단하는 거지. 스레드를 추가로 생성하지 않음, 대신 메인 스레드를 잡고 있어서 다른 작업을 못 하게 만들어버림. 이건 사실상 코루틴을 비동기적으로 쓰려는 의미가 없음. 동기 방식이랑 다를 게 없지.


스레드 점유 방식: 그냥 워커 스레드에서 runBlocking이 실행되고, 그 스레드를 막아버림. 따라서 이건 쓸 이유가 없음. 성능을 완전히 잡아먹음.


2. WebClient의 비동기 API는?


WebClient의 비동기 API는 진짜 비동기적인 방식으로 동작해. 여기서 Netty 기반의 Event Loop가 동작하는데, 이건 실제로 스레드를 점유하지 않고, I/O가 준비되면 스레드 풀에서 자유롭게 스레드를 할당받아서 처리하는 방식임.


즉, WebClient가 비동기 처리를 할 때는, 굳이 새로운 스레드를 생성하는 게 아니라, 이벤트 루프 방식으로 이미 준비된 스레드 풀에서 최소한의 스레드만 점유해서 돌아감. 그래서 비동기 처리의 장점을 살릴 수 있는 거지.


3. 코루틴이 쓰레드를 “쓸데없이” 만드는가?


코루틴 자체는 기본적으로 스레드를 만들지 않음. 코루틴은 스레드를 효율적으로 쓰려고 나온 개념인데, runBlocking이나 잘못된 방식으로 쓰면 스레드 점유가 비효율적으로 일어남. 예를 들어, GlobalScope.launch 같은 걸 쓸 때, 필요 없는 스레드를 생성할 가능성이 커지는데, 컨트롤이 불가능한 코루틴 스코프라 관리가 안 됨.


반대로, 코루틴을 적절하게 사용하면, 최소한의 스레드로도 많은 작업을 처리할 수 있음.


결론


Spring MVC에서 runBlocking 쓰면 스레드를 점유하고 블로킹시키는 쓰레기 짓이 되는 거고, WebClient 비동기 API는 최소한의 스레드로 비동기 처리를 하는 거라 제대로 비동기 처리를 하고 있는 거지.


그래서 코루틴 자체가 쓸데없이 스레드를 만드는 게 아니라, 어떻게 쓰느냐에 따라 효율적으로 쓸 수도 있고, 성능을 좆망하게 만들 수도 있음.


---

아니 스프링의 기본 워커쓰레드 200개말고 다른거 만드냐고


---

GPT

아, 그러니까 스프링 MVC 기본 워커 스레드 200개 말고, runBlocking이나 WebClient 비동기 API 쓸 때 추가적인 스레드를 생성하냐는 거지?


1. runBlocking의 경우


runBlocking을 사용하면 추가적인 스레드는 만들지 않음. 스프링 MVC의 기본 워커 스레드 풀(기본적으로 200개)에서 그냥 하나를 차지하고 그걸 블로킹하는 거임. 새로운 스레드를 만드는 게 아니라, 기존의 워커 스레드를 홀딩하는 식으로 돌아가기 때문에 쓰레기 코드가 되는 거지.


2. WebClient 비동기 API의 경우


WebClient는 기본적으로 NettyReactor 같은 비동기 논블로킹 I/O 기반으로 작동하는데, 이 경우에는 이벤트 루프 방식으로 돌아가.

이건 스프링의 워커 스레드 풀(200개)와는 다른 스레드 풀을 사용하는 거임. WebClient는 기본적으로 Netty의 이벤트 루프에서 돌아가고, 이 이벤트 루프는 필요할 때 적절하게 스레드 풀을 추가로 사용할 수 있어. 하지만, 워커 스레드 풀과는 별개로 운영되는 거라 추가 스레드를 생성하는 것처럼 느낄 수 있음.


즉, WebClient의 비동기 API를 사용하면 기본 워커 스레드 풀(200개) 외에 다른 I/O 전용 스레드 풀따로 동작하는 거지. 그래서 스레드 풀을 추가로 사용하는 건 맞음.


3. 정리


runBlocking: 추가적인 스레드를 만들진 않고, 기존 워커 스레드(200개 중 하나)를 블로킹해서 성능에 좆같은 영향을 미침.

WebClient 비동기 API: 기본 워커 스레드(200개) 말고, NettyReactor이벤트 루프에서 별도의 I/O 스레드 풀을 사용함. 추가적인 스레드 풀을 사용하는 건 맞지만, 이것도 효율적으로 논블로킹으로 작동해서 성능에는 크게 문제 없음.


결론: Spring MVC에서 기본 워커 스레드 200개 말고, WebClient 쓰면 별도의 I/O 스레드 풀이 따로 작동함. 새로 만드는 건 맞지만, 그게 문제는 아님.