이전 글: 2022.03.25 - [개발/reactive] - [spring] spring-web and spring-webflux
springboot2를 사용하게 되면 서블렛 기반으로 갈지 리엑티브 기반으로 갈지 고민하게 된다. 예전 강의나 자료에서는 둘 중 하나만 골라서 얹어야 한다고 그러는데, 요즘에는 둘 다 얹어서 사용 가능하다(정확히 말하자면 둘 다 있으면 서블랫 기반으로 돌고 webflux의 몇몇 라이브러리를 사용할 수 있다)
새로운 프로젝트를 하기로 했고, 역시나 새로운 기술의 도입의 유혹에서 벗어나지 못하고 있다. spring-web기반으로만 작업해보아서 webflux를 사용해보려고 하는데,, 하면서 이게 맞는지 확신이 안서는데, 빠르게 결정을 해야 하는 상황을 맞닥뜨렸다. 다음은 고민의 일지이다.
1. web/webflux를 동시 사용해보자. 딱히 소스가 달라지는건 없지만 restTemplate가 없어진다는데 그거라도 보완하는 거야..
즉 spring-mvc(톰캣)를 사용하면서 api 요청 부분은 webClient로 비동기 처리, 디비는 동기
-> 어드민 백엔드와 같이 단순 CRUD 일 경우 활용하기로 하였다.
implementation "org.springframework.boot:spring-boot-starter-web"
implementation "org.springframework.boot:spring-boot-starter-webflux"
implementation "org.springframework.boot:spring-boot-starter-data-jpa"
implementation "org.springdoc:springdoc-openapi-ui:${swaggerVersion}"
implementation "org.springdoc:springdoc-openapi-webflux-core:${swaggerVersion}"
2. 너무 달라지는 게 없는 것 같으니까 spring-webflux로만 개발해보자, 근데 아직 R2DBC는 개발 장벽이 너무 커, 그리고 아직 DB까지 비동기로 진행할 일도 별로 없어..
즉 spring-webflux(netty)를 메인으로 사용하되 디비는 동기방식 사용
-> 테스트해보니 몇몇 필터만 수정해주면 spring-mvc방식으로 개발했던 코드도 동일하게 작동하였다. 게다가 reactive 공부하면서 바로바로 적용 가능하니 api서버 개발 시 시도해볼 만한 스택이다.
implementation "org.springframework.boot:spring-boot-starter-webflux"
implementation "org.springframework.boot:spring-boot-starter-data-jpa"
implementation "org.springdoc:springdoc-openapi-webflux-ui:${swaggerVersion}"
spring-webflux가 controller -> service -> repository 구조도 지원하지만(annotation 기반)
router -> handler/service -> repository 구조가 진짜 모습이다.(함수형 프로그래밍 모델 기반)
하지만 진짜 webflux의 기능을 쓰지 못하기 때문에 성능상 이점이 없을 듯하여 굳이 이렇게 사용하지 않아도 될 것 같다.
게다가 webflux 디펜덴시만 있으면 스웨거나 filter 설정 등 기존 로직에 영향이 있을 수 있다.
고생에 비해 성과가 미미할 수 있으니 고민이 필요하다.
3. webflux with r2dbc.. 디비까지 모든 걸 다 리액티브로 바꾸자니 소스에 하나라도 블로킹 걸리면 의미가 없으니 조심해야 하고, 개발 장벽도 있고 무엇보다 혼자 하는 게 아니라 팀으로 개발하니 팀원들의 동의도 구해야 하고.. 개발 속도도 안 날 것 같으니 우선 보류!
디비마저도 비동기로 처리하는 설정, 궁극적으로 지향해야 하는 부분이지만 일반적인 api에는 이렇게까지 사용할 필요는 없을 것 같다. 진짜 콜이 많거나 백그라운드에서 동작하는 것들이 많을 때(배치성 업무) 효력이 좋을 것 같다.
implementation("org.springframework.boot:spring-boot-starter-webflux")
implementation("org.springframework.boot:spring-boot-starter-data-r2dbc")
//implementation("org.springframework.boot:spring-boot-starter-data-redis-reactive")
//implementation("io.projectreactor.kotlin:reactor-kotlin-extensions")
//implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactor")
//implementation("org.jetbrains.kotlinx:kotlinx-coroutines-debug")
implementation("org.springdoc:springdoc-openapi-webflux-ui:$openApiVersion")
implementation("dev.miku:r2dbc-mysql")
router, handler, r2dbc 관련 처리에 익숙하면 해볼 만한데 아직 미숙하여 100프로 전환은 아직 무리가 아닐까 싶다.
위 설정에서 조심해야 하는 게 webflux의 유무에 따른 swagger dependency도 달라져야 한다는 건데, 까딱하다가는 스웨거가 안 나올 수 있으니 꼭 같이 확인해야 한다.
우선 시험 삼아 어드민 백엔드에는 spring-web, spring-webflux /springfox3.0 swagger의 형태로 유지,
api 서버에는 spring-web을 드러내고 spring-webflux / springdoc3 swagger만 둔 형태로 유지해 볼 생각이다. 약간 모험이긴 한데 공부를 하고 알아갈 때마다 바로바로 개선할 수 있다는 이점이 있달까..
참고
https://www.baeldung.com/spring-mvc-async-vs-webflux
https://marrrang.tistory.com/4
https://dreamchaser3.tistory.com/13
'개발 > reactive' 카테고리의 다른 글
[webclient] 비슷한데 뭘 써야할지 모르겠는 것들 (0) | 2022.04.01 |
---|---|
[webflux] block vs toFuture (0) | 2022.03.31 |
[spring] spring-web and spring-webflux (0) | 2022.03.25 |
[reactive] 10. Flux (0) | 2022.03.25 |
[reactive] 9. Mono (0) | 2022.03.23 |