최근 사이프에서 코루틴에 대한 미션 스터디를 진행하면서, Spring MVC + Coroutine 환경에서의 멋진 퍼포먼스를 확인한 경험이 있었습니다. 그런데 요즘 Java 21의 Virtual Thread가 떠오르면서 "코루틴의 대체재", "코틀린 환경에 제한된 코루틴보다 좋은 퍼포먼스" 라는 후기들로부터 여러 아티클에서 코루틴 vs VT(Virtual Thread) 성능 비교 내용을 확인하면 VT가 압도적까지는 아니지만 코루틴보다 나이스한 퍼포먼스를 내는 것을 확인하였습니다.
그래서 디프만에서 진행했던 10분만 프로젝트에 Java 17 -> 21 마이그레이션 시도를 하여 어떠한 과정이 있는 지 살펴보고, VT에 대한 내용은 시간될 때 한번 작성하도록 해보겠습니다!.!
https://tech.kakaopay.com/post/coroutine_virtual_thread_wayne/
최근 이 글이 초큼 떠오르면서 많은 커뮤니티에서 "Virtual Thread가 요즘 그렇게 좋다네요!", "Virtual Thread가 뭔씹..👥..👥(웅성웅성)", "코루틴보다 성능이 멋지다" 등등... 그래서 좀 알아보았는데
Heap에 수많은 Virtual Thread를 할당해놓고, Platform Thread에 대상 Virtual Thread를 마운트/언마운트하여 컨텍스트 스위칭을 수행한다고 합니다. 기존 Platform Thread에서의 컨텍스트 스위칭에 비용보다 효율적으로 사용되는 걸 확인할 수 있습니다.
그 외 Virtual Thread의 상태, Pinning, Spring boot로 어떻게 마이그레이션 되는 지에 대한 내용은 아래 참고 링크 남길테니 한번 정독하는 것도 좋을 듯합니다
그리고 이후 Virtual Thread에 대한 글은 시간이 된다면 별도 작성하도록 하겠습니다 🙇
출처: https://d2.naver.com/helloworld/1203723
우선 JDK 21 중 amazon-corretto를 사용하였고, 단순히 17 이라는 숫자를 21로 바꾸면 해결아닌가? 라고 생각할 수 있는데 당연히 말도 안되는 생각입니다.
17에서 21로 변하면서 처음에 어떤 점을 고려했는 지 간단하게 리스트 업 해보았습니다.
우선 이 점부터 고려하여 마이그레이션을 진행해보았습니다.
마이그레이션 커밋: https://github.com/depromeet/10mm-server/pull/420/commits/5fe2c8fc6b17265520b2fc72f5690f76f8109add
이후 Test 코드를 실행했더니 Spring boot 3.4.0 버전부터는 MockBean이 Deprecated 되었다고 합니다. 그래서 해결 방안이 무엇인가? 특별한 건 없습니다.
간단하게 MockitoBean으로 바꾸면 된다합니다.😂
공식 문서에서도 MockBean이 Deprecated 된다는 이야기가 있습니다.
Workflow에서는 별다른 문제는 없었습니다. temurin을 사용하고 있었는데 21 버전이 LTS라 다행히(?) 문제는 없었습니다.
다음 Gradle version에 대한 이슈가 있었는데, Spring boot 3.4.0으로 변경 시 친절하게 IntelliJ에서 Gradle 버전 변경 안내를 띄워줬습니다. 이번에 3.4 버전 이후로는 Gradle 8.4가 호환이 안되는 듯합니다. 이후 변경 후 테스트를 진행했습니다.
제가 붙잡고 있었던 이슈에 대해 이야기해보겠습니다.
테스트 진행 후 단위 테스트 케이스에서 모두 통과되었지만, 테스트는 실패로 떨어졌는데... 🤔
처음엔 JDK 버전이 제대로 안먹었나 생각하여 프로젝트 설정부터 확인했는데 잘 적용된 것을 확인했나 그런데 그 아래 에러 전문을 확인해보니 Jacoco 에러도 보인 것을 확인할 수 있었습니다.
그래서 Jacoco Repo의 릴리즈 노트를 확인했더니 0.8.9는 실험적 배포를 하였고 0.8.11부터 공식적으로 21에 대한 지원이 이루어진다 하였습니다.
그러하여 Jacoco 0.8.12의 최신 버전으로 변경 후 테스트는 정상적으로 이뤄졌습니다.
테스트도 정상이고 애플리케이션 실행도 문제없이 동작되었으니 Dev 서버 배포 Action도 정상적으로 동작된 것을 확인했습니다. API 기능 동작도 잘 되고 순탄하다 생각했으나...?
Swagger를 접속하니 /v3/api-docs에서 500 에러를 마주했습니다.
🤔... 뭐지.. 이번에도 어김없이 공식 Release 내용을 보니 현재 버전이 2.0.2이였는데, 2.7.0 버전에서는 fix 사항에 대해 대응이 되어 있더라고요.
Java 21에서는 getFirst(), getLast()가 추가되었죠?
해당 메서드는 Pojo Getter이므로 Jackson은 직렬화 중에 getFirst(), getLast()들을 추가하는데 Java 21 이전과 Java 21부터 시작하는 두 가지 다른 결과가 보인 듯합니다.
그에 대한 대응이 이뤄진 2.7.0 버전을 도입하였고, Swagger도 정상 동작되는 것을 확인하였습니다.
버전을 새롭게 마이그레이션 하는 것이 그렇게 "어렵다... 우리는 언제 올리지..." 이야기가 나오는데 저도 그나마 짧은 업그레이드였지만, 대응되는 라이브러리 공식 문서도 읽고 릴리즈 노트를 확인하면서 많은 공부가 되었습니다.
소프트웨어 엔지니어의 역할을 수행하면서 앞으로도 새로운 기술에 접하고 도태되지 않은 제품을 개발하려면 이번처럼 마이그레이션하는 역량도 필요하다 생각됩니다!
감사합니다:)
작업 PR