| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| 8 | 9 | 10 | 11 | 12 | 13 | 14 |
| 15 | 16 | 17 | 18 | 19 | 20 | 21 |
| 22 | 23 | 24 | 25 | 26 | 27 | 28 |
- jvm
- 메가테라
- CORS
- 자바
- 부트캠프
- JavaScript
- 소프트웨어장인정신
- Spring
- til
- 헤리턴스아라
- HTTP 완벽가이드
- 이펙티브자바
- 2022회고
- 바닐라코딩
- 자바스크립트
- http
- 신혼여행
- 주간회고
- Hibernate Reactive
- SpringSecurity
- 클로저
- 취업회고
- leetcode
- java
- css
- 포트폴리오
- 상속
- html
- http 완벽 가이드
- 몰디브
- Today
- Total
codingBird
TIL - Spring project를 빌드하면 출력되는 로그들은 뭘까? 본문

스프링 프로젝트에서 @SpringBootApplication 어노테이션이 있는 클래스, 즉 메인 클래스를 run() 했을 때 터미널에 많은 문자들이 출력이 되고 오류가 없다면 성공적으로 빌드가 된다.
지난 주에는 생각없이 지나쳤으나 이번 주에 강의에서 빌드 과정에서 출력되는 문자를 통해 JDBC:URL을 알아내서 h2-console에 입력하는 것을 보고 어떤 내용들이 출력되는지 알아보면 좋을 것 같아 조사하게 되었다.
그럼 spring 프로젝트의 main 클래스를 실행시키면 어떠한 과정을 거치면서 빌드를 하게 될까? 한 번 알아보는 시간을 가져보자.
로그 정보

좌에서 우로 출력되는 정보는 아래와 같다.
- Date and Time : 로그 아이템의 발생 날짜와 시간에 대한 정보가 담긴다.
- Log Level : 로그의 information level 정보를 제공한다. information level은 TRACE, DEBUG, INFO, WARN, ERROR, FATAL 그리고 OFF가 있다.
- Process ID: 현재 실행 중인 spring boot application에 대한 process ID 정보를 제공한다.
- Separator: 분리자. 로그의 파트를 분리한다.
- Thread Name: Thread Name은 대괄호([ ])로 감싸져있고, 대부분 logging thread나 요소가 있는 thread를 포함한다.
- Logger Name: 일반적으로 소스의 class name 정보를 가지고 있다.
- Log Message: 로그 메세지는 어플리케이션에서 따라야 하는 방법을 설명하고 애플리케이션에 오류가 발생할 경우 원인을 추적하는데 도움이 되는 정보를 제공한다.
Log Level
- FATAL : 어플리케이션의 중요한 비즈니스 기능이 더 이상 작동하지 않는 상태일 경우
- ERROR : 어플리케이션의 기능이 제대로 작동하지 않는 을 경우
- WARN : 어플리케이션에 문제 또는 방해가 될 수 있는 상황이 발생했을 경우
- INFO : 어플리케이션이 특정 상태에 들어갔는지 등 보여주는 표준 로그.
- DEBUG : 문제를 해결하는데 필요할 수 있는 정보를 제공. 테스트 환경에서 실행할 경우 사용
- TRACE : 어플리케이션의 모든 상황을 완벽하게 파악해야 하는 상황에서 사용. 로그 정보가 상세하게 제공됨.
분석 시작
정상적으로 빌드가 되었을 가정하에 출력되는 로그에 대해 알아보는 것임으로 Date and Time 그리고 Log Level은 생략함.

공통적인 부분 : Thread Name이 [main]이 아닌 [restartedMain]인 이유는 spring-boot-devtools 의존성을 추가하면 클래스 경로에서 파일 변경이 일어날 때마다 어플리케이션을 다시 시작하게 되어 main thread가 아닌 restartedMain tread로 실행된다.
- 실행 중인 소스의 클래스 이름과 자바 버전, 로컬 환경 프로세스 ID 정보 그리고 파일 경로 등 정보를 제공.
- Spring Profiles는 환경에 따라 서로 다른 어플리케이션 설정을 사용할 수 있도록 하는 기능이고 @Component @Configuration @ConfigurationProperties 즉 IoC컨테이너가 관리하는 Bean에 @Profile 어노테이션을 이용해 설정할 수 있다. 그리고 application.properties 에서 활성화할 profile을 지정 할 수 있다. 해당 내용은 설정된 profile이 없어 default profile로 설정이 되었다는 뜻.
- Spring.Devtools 은 편의를 위해 여러가지 기능을 제공하는데 예를 들면 template engines은 컴파일된 templates들을 캐싱해 반복인 파싱 작업을 하지 않도록 도와주며 Spring MVC나 HTTP caching 같은 기능도 제공한다. 이를 원하지 않으면 spring.devtools.add.properties에서 false로 설정해 기본 설정을 해제할 수 있다.
- 웹과 연관된 추가적인 로깅을 원하면 logging.level.web의 속성을 DEBUG로 설정하라는 정보를 제공한다.
- Default Mode**로 JPA를 Bootstrap 즉 가동시킨다는 의미.
- Spring Data가 1개의 JPA repository interface를 스캔했고 22ms가 걸렸다는 정보를 제공. 해당 프로젝트에는 PostRepository extends JpaRepostiory<Post, Id>가 있었음.
- TomCat은 서블릿 컨테이너만 있는 웹 어플리케이션 서버(WAS). 웹 서버(정적)와 연동해 실행할 수 있는 자바 환경을 제공하여 JSP와 자바 서블릿이 실행할 수 있는 환경을 제공한다. 해당 로그는 3000 port로 서버가 초기화되었다는 것.
- 톰캣이 서비스를 시작했다는 정보를 제공
- 서블릿 엔진**이 시작되었다는 정보를 제공
- WebApplicationContext**가 등록된 Spring을 초기화 시작 되었다는 정보를 제공
- Root WebApplicationContext**: 초기화가 600ms 걸려 초기화 완료되었다는 정보를 제공
- Hikari CP로 DB와 연결을 시작한다는 정보를 제공
- Hikari CP로 DB와 연결이 완료 되었다는 정보를 제공
- DB로 사용되는 H2 Database와 연결이 되었으니 jdbc:h2:./data/board URL을 이용해 h2-console을 사용할 수 있다는 정보를 제공
- PersistenceUnitInfo**를 처리 중이라는 정보를 제공 [name: default]
- 사용 중인 Hibernate ORM core 버전 정보를 제공
- 사용하는 Hibernate Commons Annotations 버전 정보를 제공
- ‘default’ persistence unit을 위한 JPA EntityManagerFactory**를 초기화했다는 정보를 제공
- org.hibernate.dialect.H2Dialect으로 DIalect**을 설정한다는 정보를 제공.
- JtaPlatform*의 구현체인 NoJtaPlatform을 사용한다는 정보를 제공.
- jpa.opn.in.view는 기본적으로 enabled인 상태라는 정보를 제공. OSIV전략은 트랜잭션 시작처럼 최초 데이터베이스 커넥션 시작 시점부터 API 응답이 끝날 때까지 영속성 컨텍스트와 데이터베이스 커넥션을 유지한다는 것을 의미. → 너무 오랜시간 데이터베이스 커넥션 리소스를 사용하기 때문에 실시간 트래픽이 중요한 어플리케이션에서는 커넥션이 모자랄 수 있고 이는 장애로 이어질 수 있다.
- liveReload server를 35279 포트에서 실행 시킨다는 정보를 제공. livereload는 파일의 변경을 주시하고 있다가 변경이 되면 웹브라우저에 변경을 자동으로 반영해준다.
- Tomcat이 http 프로토콜을 사용하는 3000 포트에서 작동 되었다는 정보를 제공.
- JVM에서 6.587초를 사용해 BoardApplication을 빌드를 했다는 정보를 제공.
BootStrap Mode
Spring Data는 repositories를 스캔하고 bean을 싱글톤 스코프 빈으로 정의한다. 초기화하는 동안 repositories는 EntityManager를 얻고. JPA 메타모델을 가져오고 선언된 쿼리의 유효성을 검사한다.
JPA는 기본적으로 동기적으로 부트스트랩 되는데, 결과적으로 부트스트랩 프로세스가 완료되어야 repository의 인스턴스화가 시작된다. 따라서 repository의 수가 증가하면 어플리케이션이 요청을 수락하기 까지 시간이 오래걸릴 수 있다.
Modes
- Default :
Default로 설정하면 repositories를 즉시 로딩한다. 따라서 다른 Spring beans와 동일하게 의존성 주입될 때 바로 인스턴스화가 된다.
- Lazy :
JPA repostiory에 Lazy mode를 적용하면, Spring은 repository의 bean 정의를 등록하지만 바로 인스턴스화를 시키지 않는다. 따라서 Lazy mode를 적용하면 처음 사용할 때 초기화가 진행된다.
- Spring은 초기화된 repository없이 요청 수락을 할 수 있으므로 첫 번째 repository가 처리될 때 까지 latency가 증가한다
- BootStrapMode를 전역적으로 lazy 모드로 설정하면 오류가 발생하기 쉽다. Spring은 테스트에 포함되지 않는 repository에 포함된 쿼리 및 메타데이터의 유효성을 검사하지 않는다.
production 배포에서 초기화 오류가 발생할 가능성이 있을 때에만 lazy 모드를 설정해야 한다.
3.Deferred
Deferred은 JPA를 비동기적으로 bootstrap할 때 사용되는 모드이다. Deferred 모드를 사용하면 repositories는 EntityManager가 초기화 될 때까지 기다리지 않는다. → Spring Data는 repositories를 어플리케이션 시작 전에 초기화하고 포함된 쿼리와 메타데이터 유효성을 검사함.
Servlet Engine
Servlet : 서블릿은 클라이언트 요청을 처리하고, 그 결과를 반환하는 Servlet 클래스의 구현 규칙을 지킨 자바 웹 프로그래밍 기술. 즉 클라이언트가 어떤 요청을 하면 그에 대한 결과를 다시 전송해주는 역할을 하는 자바 프로그램. 요청을 처리하고 다음 페이지를 띄우는 역할을 수행함. 자바로 구현된 CGI라고 한다.
Servlet Engine: 서블릿 엔진은 기본으로 서블릿에 대한 지원을 포함하는 서버이다. 이런 엔진은 모든 것이 즉시 작동한다는 장점이 있다. 예를들어 Tomcat서버가 있고 Tomcat서버는 servlet과 JSP 구현을 참조한다. 그리고 모든 것이 JAVA로 작성되어 있음.
Contexts
ApplicationContext는 Spring의 인터페이스로 어플리케이션의 context를 가지고 IoC 컨터이너로써 빈을 만들고 관리하고 의존성을 주입해준다.
WebApplicationContext는 ApplicationContext를 상속받은 자식으로 ApplicationContext의 기능과 추가적으로 getServletContext메서드를 이용해 servlet context 또한 가지게 되어 웹 어플리케이션에 필요한 기능들을 추가한 인터페이스다.
Root WebApplicationContext는 어플리케이션에 하나만 존재하는 최상의 context 여러 servlet에 공유할 수 있느 bean들을 설정하는 곳. @Repository, @Service 등
Servlet에서 IoC 컨테이너에 등록되어 있는 빈들을 사용할 수 있는 이유는 contextLoaderListener에서 servletContext에 WebApplicationContext를 등록하기 때문에.
Hikari CP
**Hikari CP(히카리 커넥션풀)**은 JDBC의 일종인데 JDBC는 Java Database Connectivity의 약자로 자바에서 데이터베이스에 접속할 수 있도록 하는 자바 API이다. JDBC는 데이터베이스에서 자료를 쿼리하거나 업데이트하는 방법을 제공한다.
DB 커넥션 풀 : 일반적인 데이터 연동과정은 웹 어플리케이션이 필요할 때마다 데이터베이스에 연결하여 작업하는 방식이지만 필요할 때마다 연동해서 작업할 경우 시간이 많이 걸린다. 이를 해결하기 위해 웹 어플리케이션이 실행됨과 동시에 연동할 데이터베이스와의 연결을 미리 설정해준다. 그리고 필요할 때마다 미리 연결해 놓은 상태를 이용해 빠르게 데이터베이스와 연동해 작업을 한다. 이렇게 미리 데이터베이스와 연결시킨 상태를 유지하는 기술을 커넥션 풀(Connection Pool, CP)라고 한다.
PersistenceUnitInfo
EntityManagerFactory 생성에 제공되는 persistence provider이다.
JPA EntityManagerFactory
- Hibernate는 자바 언어를 위한 객체 관계 매핑 프레임워크. 객체 지향 도메인 모델인 객체로 데이터베이스에 있는 데이터를 맵핑해 가져올 수 있고 Hiberante는 이를 자동적으로 변환시켜준다.
- EntityManagerFactory는 동일한 데이터베이스에 연결하기 위한 EntityManager 인스턴스를 제공한다. 모든 인스턴스는 기본 구현에 정의한 것과 동일한 설정을 사용하도록 구성되고, 다른 데이터 자장소에 연결하기 위해 여러 EntityManagerFactory를 준비할 수 있다.
- JPA EntityManager는 특정 애플리케이션의 데이터베이스에 접근하는데 사용된다. persistence Entity를 관리하고 primary key identity로 entity를 찾고 모든 엔티티를 쿼리하는데 사용된다.
Dialect
표준 SQL인 ANSI SQL 외에, DBMS인 Oracle, MySQL, PostgreSQL 등, SQL마다 문법과 함수가 다른 경우가 있다. 이러한 SQL 표준을 지키지 않는 특정 벤더별 기능을 방언(Dialect)이라고 부른다
JPA는 기본적으로 어플리케이션에서 직접 JDBC 레벨의 SQL을 작성하지 않고 JPA가 직접 SQL을 작성하고 실행한다. 문제는 DBMS 종류마다 사용하는 SQL이 다르고 JPA가 해당 DMBS에 맞춰 SQL을 생성해야 하는 상황에서 어떤 DBMS에 맞는 SQL을 생성해야 하는지 모르면 문제가 발생한다. Dialect 설정은 이런 상황에서 JPA에 어떤 DBMS를 사용하고 있는지 알려주는 방법이다. JPA에 Dialect를 설정할 수 있는 추상화 Dialect 방언 클래스를 제공하고 설정된 Dialect으로 각 DBMS에 맞는 구현체를 제공한다.
JTA Platform
JTA : Java Transaction API는 데이터베이스 간의 분산 트랜잭션을 처리하는 자바 API
JTA platform : 주어진 플랫폼/환경에서 다양한 JTA 서비스와 상호 작용하는 방법을 정의하는 인터페이스
'TIL' 카테고리의 다른 글
| TIL - 칠전팔기 코딩도장 (0) | 2022.10.26 |
|---|---|
| TIL- 작은 하마(객체) 이야기 (0) | 2022.10.26 |
| TIL - 강의에 생긴 의존성. (0) | 2022.10.22 |
| TIL - Objects everywhere (2) (0) | 2022.10.20 |
| TIL - Async (2) 이벤트 루프 (0) | 2022.10.19 |