구글 클라우드의 Cloud Run 환경에서 Java 애플리케이션, 특히 Spring 프레임워크를 이용하는 서버리스 애플리케이션을 개발하는 분들에게 몇 가지 중요한 성능 최적화 팁을 소개합니다.
이러한 최적화 방법은 애플리케이션의 응답 시간을 단축하고 비용을 줄이는 동시에 사용자 경험을 개선하는데 도움이 됩니다.
⚙️ Cloud Run과 Cold Start 최적화
Cloud Run은 사용하지 않을 때는 자원을 아끼기 위해 서비스를 자동으로 줄여 비용을 절약해 주는 훌륭한 서비스입니다. 그러나 이 서비스를 다시 사용하려 할 때 필요한 서비스를 다시 준비하기 위해 새로운 ‘인스턴스’를 만들어야 하며, 이 과정에는 약간의 시간이 걸리는데요. 이런 현상을 ‘콜드 스타트’라고 부릅니다.
콜드 스타트 문제를 줄이는 한 가지 방법은 Cloud Run 서비스를 완전히 0으로 줄어들지 않도록 최소한의 인스턴스 수를 설정하는 것입니다. 이렇게 하면 서비스가 바로 시작될 수 있어 대기 시간이 줄어듭니다. 단, 이 방법은 서비스를 항상 준비 상태로 유지해야 하므로 비용이 조금 더 들 수 있습니다. 또 다른 방법은 애플리케이션 자체를 빠르게 시작할 수 있도록 최적화하는 것입니다. 이 방법은 추가 비용 없이 콜드 스타트 문제를 완화할 수 있는 효과적인 방법입니다.
💻 Cloud Runtime 환경 최적화
Cloud Run에서는 서비스의 처리 능력을 높이기 위해 사용하는 CPU의 개수를 늘릴 수 있습니다. 이는 애플리케이션을 더 빠르게 시작하는 데 도움을 줍니다. 또한, Cloud Run에는 CPU Boost라는 특별한 기능이 있는데, 이를 사용하면 애플리케이션이 시작될 때 잠시 동안 더 많은 CPU를 사용할 수 있어 애플리케이션의 시작 시간을 더욱 단축할 수 있습니다. 애플리케이션이 완전히 시작된 후에는 다시 평소처럼 적은 수의 CPU를 사용하게 되므로, 이 기능은 성능 향상을 위해 잠깐 동안만 필요한 추가 자원을 제공하면서도 비용을 아끼는 방법입니다.
💻 Java Runtime 최적화
Java 가상 머신(JVM)의 설정을 조정함으로써, 애플리케이션의 시작 시간과 메모리 사용량을 개선할 수 있습니다. 예를 들어 가비지 컬렉터를 직접 설정하고 컨테이너에 할당된 메모리의 75%를 실제 사용할 메모리로 지정하는 것이 좋습니다. 또한 JVM이 사용할 프로세서의 수를 알려주고 기본 스택의 크기를 줄이면 더 효율적으로 메모리를 관리할 수 있습니다.
한편 GraalVM을 사용하면 Java 소스 코드를 직접 기계어 코드로 컴파일하는 ‘네이티브 이미지’를 생성할 수 있습니다. 이 방법을 통해 JVM 단계를 거치지 않고 바로 코드를 실행할 수 있어 애플리케이션의 시작 시간을 대폭 줄이고 메모리 사용량도 줄일 수 있습니다. 그러나 이 방식은 모든 Java 애플리케이션에 적합한 것은 아니며 애플리케이션의 특성과 요구 사항에 따라 적절한 선택이 필요합니다.
데이터를 어디에 저장할지 결정하는 것도 중요한데요. 구글 클라우드 스토리지는 사용자의 필요에 맞게 데이터를 저장할 수 있는 세 가지 옵션을 제공합니다. ‘리전’은 특정 지역에 데이터를 저장하고, ‘듀얼-리전’은 두 개의 지역에, ‘멀티-리전’은 여러 지역에 데이터를 분산시켜 보관할 수 있게 해줍니다. 이렇게 다양한 저장 옵션을 제공하여 성능이나 비용 측면에서 가장 이상적인 선택을 할 수 있도록 도와줍니다.
😊 프레임워크 최적화
Spring 같은 프레임워크는 개발자가 더 빠르고 효율적으로 작업할 수 있게 도와주지만, 때로는 클래스를 불러오거나 리플렉션(프로그램이 실행 중에 자신의 구조를 조사하고 수정할 수 있는 기능)을 사용하는 과정에서 시간이 더 걸릴 수 있습니다. 이는 애플리케이션의 반응 속도가 느려지는 원인이 될 수 있습니다.
성능을 향상하기 위한 첫 걸음은 항상 프레임워크와 Java 가상 머신(JVM)의 최신 장기 지원(LTS) 버전을 사용하는 것입니다. 이렇게 하면 최신 개선 사항과 최적화를 활용할 수 있습니다. 그러나 새로운 프레임워크로 바꾸는 것은 많은 시간과 노력이 필요한 일이므로, 이런 큰 변경을 결정하기 전에는 현재 사용 중인 프레임워크와 비교하여 실제 성능 개선이 있는지 충분히 평가해야 합니다. 성능이 실제로 개선될 것인지, 팀이 새 프레임워크에 적응하는 데 얼마나 걸릴지, 그리고 전환 과정에서 잠재적인 어려움은 무엇인지 고려해야 합니다. 이러한 평가를 통해, 성능을 위해 프레임워크를 변경하는 것이 정말로 필요한지 결정할 수 있습니다.
😊 애플리케이션 코드 최적화
애플리케이션이 시작될 때 많은 양의 데이터를 메모리에 바로 불러오는 것은 애플리케이션이 준비되는 데 걸리는 시간, 즉 ‘콜드 스타트’ 시간을 늘릴 수 있습니다. 이 시간을 줄이기 위해, 다음과 같은 방법을 고려해 볼 수 있습니다.
- 데이터 캐싱 또는 지연 로딩 사용: 필요할 때까지 데이터 로딩을 미루거나, 자주 사용되는 데이터는 캐시에서 빠르게 불러올 수 있도록 합니다. 이는 초기 로딩 시간을 단축시킬 수 있습니다.
- 불필요한 의존성 제거: 애플리케이션에 필요하지 않은 라이브러리나 모듈을 제거함으로써 컨테이너 이미지의 크기를 줄입니다. 이는 애플리케이션의 시작 속도를 빠르게 합니다.
- 다른 서비스 호출 최소화: 애플리케이션 시작 시 다른 외부 서비스를 호출하는 것은 피하고, 필요한 경우에만 호출하도록 합니다.
- 연결 풀: 애플리케이션 시작 시 모든 연결을 한꺼번에 생성하기보다는 필요에 따라 점진적으로 연결 수를 늘리는 것이 좋습니다. 이는 리소스 사용을 최적화하고 시작 시간을 단축시킬 수 있습니다.
서버리스 환경에서는 애플리케이션이 자주 시작되고 중지되는데, Cloud Run 같은 서비스에서 애플리케이션이 요청을 처리할 준비가 완전히 되었는지 확인하기 위해 ‘스타트업 프로브’를 설정하는 것이 좋습니다. 스타트업 프로브는 애플리케이션이 준비 상태에 도달했는지를 자동으로 확인하여, 사용자 요청을 처리할 준비가 되었을 때만 트래픽을 받도록 합니다. 이는 불필요한 오류를 방지하고 사용자 경험을 개선하는 데 도움이 됩니다.
👍 더 자세한 성능 최적화 방안이 필요하다면
Cloud Run과 같은 서버리스 플랫폼에서 Java 애플리케이션을 최적화하는 과정은 클라우드 환경 설정부터 시작해 Java 런타임 옵션, 사용하는 프레임워크의 선택 그리고 애플리케이션 코드 자체의 최적화에 이르기까지, 여러 요소에 의해 영향을 받습니다. 이러한 다양한 최적화 작업을 통해, 애플리케이션의 로딩 시간을 줄이고 리소스 사용을 최소화하며 전체적인 성능을 개선할 수 있습니다. 소개한 팁 외에 Cloud Run에서 Java 애플리케이션의 성능을 향상시키는 방법이 궁금하다면, 메가존소프트가 도움을 드리겠습니다. 👉 메가존소프트 문의 바로 가기