안녕하세요 오늘은 백엔드 시스템을 구축할 때 대표적으로 사용하는 Spring Boot와 Node js 그리고 PHP의 특징에 대해서 알아보고 추후 투다에 어떤 것을 적용할 지 알아보는 시간을 가져보도록 하겠습니다.
현재 투다는 PHP로 백엔드 시스템이 이루어져 있습니다. PHP의 경우 fastcgi 통신을 통해 Nginx에 붙어 사용되는데 Nginx 특성 상 메모리 소모가 적기 때문에 비용 측면에서 가성비 있게 사용 가능합니다. 하지만 PHP의 경우 커넥션 풀을 제공하지 않기 때문에 DB와의 연결 시 비효율적이어서 별도의 프록시를 통해 연결을 진행해야 하는데, 현재 사용 중인 RDS Proxy에서의 설정 커스텀을 진행하기 어려워서(커스텀 방법이 없는 건지 아니면 있는데 못 찾는건지는 모르겠지만 발견하지 못했습니다..ㅎ) 대중적으로 많이 사용하는 2개의 백엔드 시스템을 살펴보았습니다.
우선 Spring Boot의 경우 Java 기반의 프레임워크로 Tomcat이라는 WAS가 존재하고 의존성 관리 등을 자동적으로 진행해주어 개발부터 배포까지 쉽게 만들어줍니다. 반면 Node js의 경우 Javascript 런타임으로, Jvascript 언어가 실행될 수 있도록 해주는 환경입니다. Node js를 통해 독립적으로 Javacsript를 실행시킬 수 있어 백엔드 서버로 많이 사용하고 있습니다.
출처 : https://well-made-codestory.tistory.com/31
둘의 직접적인 차이는 동작 방식에 있습니다. Node js는 NGINX와 유사하게 이벤트 루프 기반 싱글 스레드 방식으로 작동합니다. 이벤트 루프가 싱글 스레드로 요청을 받으면, 즉 이벤트가 발생하면 스레드 풀에 요청을 보내고 스레드 풀에서 요청을 처리하여 결과값을 반환합니다. 이 때 요청을 비동기 방식으로 처리하여 특정 요청으로 인해 블로킹되지 않도록 합니다. 따라서 I/O 요청이 많은 서버에 효율적이나, 싱글 스레드 기반으로 동작하기 때문에 CPU 연산이 많거나 복잡한 프로그램에는 적합하지 않습니다.
출처 : https://exhibitlove.tistory.com/312
반면 Spring Boot의 경우 멀티 스레드 방식으로 동작합니다. Spring Boot 동작 방식을 이해하려면 Tomcat의 동작 방식을 이해해야 합니다. Tomcat은 JVM 위에서 동작하는 WAS로 서블릿 컨테이너에서 요청을 받으면 HttpServletRequest, HttpServeletResponse라는 두 객체를 형성하고, 요청받은 URI을 통해 어느 서블릿에 대한 요청인지를 탐색합니다. 이 때 서블릿이 한 번도 실행된 적이 없거나 메모리에 인스턴스가 존재하지 않을 경우 초기화 후 스레드를 생성하고, 메모리에 인스턴스가 존재할 경우 초기화 작업 없이 스레드를 하나 추가적으로 생성합니다. 각 인스턴스에서 POST,GET 등 HTTP 통신 방법에 따라 다른 메소드를 호출하고, 이 때 실행된 메소드의 결과값이 HttpServeletResponse으로 보내져 클라이언트로 통신하게 됩니다. 이 과정에서 요청이 들어올 때마다 스레드를 생성하는 방식으로 요청을 처리하는 것을 확인할 수 있습니다.
출처 : https://hanseom.tistory.com/253
Spring Boot에서는 DispatcherServlet을 이용하여 모든 요청을 한 곳으로 받아서 처리합니다. 클라이언트 요청을 DisPatcherServlet이 받아 Handler Mapping으로 전달합니다. Handler Mapping에서는 원하는 Handler를 찾아오는 역할을 수행하며, 요청값에 적절한 Controller를 선택하여 요청을 전달합니다. Controller에서는 로직을 수행하고 처리된 결과값을 JSON 또는 XML 형태의 데이터 포맷으로 반환합니다. 이렇게 반환된 데이터는 HTTPResponse 형태로 클라이언트에게 보내지게 됩니다.
Spring Boot는 Tomcat이 내장되어 어플리케이션이 구동하기 때문에 멀티 스레드 방식으로 동작합니다. 따라서 CPU 연산이 많은 복잡한 작업을 처리할 때 유리하지만, 많은 I/O 요청이 발생할 경우 스레드가 너무 많이 생성되어 컨텍스트 스위칭으로 인한 오버헤드가 발생하여 오히려 성능 저하가 발생할 우려가 있습니다.
저는 투다의 백엔드 시스템으로 Spring Boot를 고려하고 있습니다. 멀티 스레드 방식으로 인해 순간적으로 트래픽이 발생할 경우 성능 저하의 우려가 있지만 스레드 관리를 통해 이 부분을 개선해나갈 수 있다고 생각합니다. 가장 큰 이유 중 하나는 추후 투다의 기획에 따라 CPU 연산이 많이 발생할 요청이 발생했을 시 Node js로 진행한 백엔드 시스템을 다시 변경하는 것이 더 불편하기 때문에 장기적으로 Spring Boot를 관리하며 서비스를 운영하려고 합니다. Spring Boot와 함께 바뀔 투다의 새로운 백엔드 시스템을 기대해주시고 오늘의 포스팅 마치도록 하겠습니다!