JVM 80

Spring Gateway, Eureka 연동

워크 플로우 클라이언트의 요청은 게이트웨이가 받아서 유레카 서버에 서비스의 주소를 받아서 라우팅한다. 서비스 인스턴스가 여러개일 경우 라운드로빈 방식(한번씩 돌아가면서 호출)으로 라우팅 된다. API Gateway 설정 server: port: 8000 # 유레카 클라이언트로 등록한다. eureka: client: register-with-eureka: true fetch-registry: true service-url: defaultZone: http://localhost:8761/eureka spring: application: name: apigateway-service cloud: gateway: routes: - id: first-service # 유레카 서버에 등록된 서비스의 애플리케이션 이름..

JVM/SpringCloud 2023.09.03

@Value 어노테이션 사용시 발생 오류

오류 FeignClient 사용시 url 부분에서 An annotation argument must be a compile-time constant 오류가 발생하였다. 코틀린에는 문자열에 연결을 위해 사용하는 구문이기에 ${} 이는 동적 할당에 해당하는 구문 오류라는 것. @FeignClient(name = "naverAPIClient", url = "${oauth.open-api.naver}") interface NaverAPIClient { } 해결 이스케이프 문자를 사용하면 간단히 해결된다. @FeignClient(name = "naverAPIClient", url = "/${oauth.open-api.naver}") interface NaverAPIClient { }

JVM/Kotlin 2023.08.27

Spring Cloud Gateway

Spring Cloud GatewaySpring Cloud Gateway는 마이크로 서비스 아키텍처에서의 진입점으로 사용되는 서비스이다. 이 서비스는 다양한 기능을 제공하여 마이크로 서비스 간의 통신과 관리를 용이하게 만든다.Spring Cloud Gateway는 비동기 방식으로 동작하며, Netty를 사용하여 효율적인 네트워크 통신을 지원한다.Predicates는 요청을 어떤 서비스로 라우팅할지 결정하는 역할을, Filter는 요청 및 응답에 대한 추가적인 로직을 수행하며, 이 두 가지를 조합하여 유연한 라우팅 및 처리를 가능케 한다.사용자의 인증 및 권한 부여를 관리하여 보안을 강화한다마이크로 서비스의 동적인 변화에 대응하기 위해 서비스 검색을 통합하여 서비스 간의 통신을 간편하게 처리한다.응답 캐싱..

JVM/SpringCloud 2023.08.23

Spring Cloud Netflix Eureka

Spring Cloud Netflix Eureka Server Spring Cloud Netflix Eureka는 마이크로서비스 아키텍처에서 서비스 디스커버리와 로드 밸런싱을 지원하기 위한 모듈 중 하나이다. 각각의 서비스는 Eureka 서버에 자신의 정보를 키-값 형태로 등록하고, 다른 서비스들도 이를 검색할 수 있다. org.springframework.cloud:spring-cloud-starter-netflix-eureka-server 라이브러리를 필요로한다. @EnableEurekaServer import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplica..

JVM/SpringCloud 2023.08.23

2차 캐시

애플리케이션 범위에서 공유하는 캐시를 Shared Cache, Secon Level Cache, L2 Cache라고 부른다. DB에서 조회한 데이터는 2차 캐시에 보관되고, 2차 캐시는 해당 엔티티의 복사본을 만들어 1차 캐시에 반환한다. 하지만 스프링이 지원하는 캐시를 서비스 계층에서 사용하는 것이 더 효과적이다. Entity에 @Cacheable을 붙여주면 캐시 모드를 설정할 수 있다. spring: jpa: properties: javax: persistence: sharedCache: mode: ENABLE_SELECTIVE hibernate: generate_statistics: true format_sql: true cache: use_second_level_cache: true region:..

JVM/JPA 2023.07.05

낙관적 락과 비관적 락

JPA는 데이터베이스에 대한 동시 접근으로부터 엔티티에 대한 무결성을 유지할 수 있게 해주는 동시성 제어 메커니즘을 지원한다. 이 메커니즘에는 낙관적 락과 비관적 락이 존재한다. JPA는 데이터베이스의 트랜잭션 격리 레벨을 READ COMMITTED 정도로 가정한다. 낙관적 락 (Optimistic Lock) 대부분의 트랜잭션이 충돌이 발생하지 않을 것이라고 낙관적으로 가정하는 방법이다. 따라서 데이터베이스가 제공하는 락 기능을 사용하지 않고, 엔티티의 버전을 통해 동시성을 제어한다. 즉, 애플리케이션 레벨에서 지원하는 락이다. @Version JPA는 @Version 어노테이션을 제공하는데, 이를 사용하여 엔티티의 버전을 관리할 수 있다. @Version 적용이 가능한 타입은 Long(long), In..

JVM/JPA 2023.07.05

트랜잭션을 지원하는 쓰기 지연

JDBC가 제공하는 SQL 배치 기능을 사용하면 쓰기 SQL을 모아서 데이터베이스에 한번에 보낼 수 있다. hibernate.jdbc.batch_size 속성의 값을 50으로 주면 최대 50건씩 모아서 SQL 배치를 실행한다. 하지만 SQL 배치는 같은 SQL일 때만 유효하다. 중간에 다른 처리가 들어가면 SQL 배치를 다시 시작한다. JPA의 쓰기 지연 기능은 데이터베이스 락이 걸리는 시간을 최소화해서 동시에 더 많은 트랜잭션을 처리할 수 있는 장점이 있다.em.persist(new Member()); //1 em.persist(new Member()); //2 em.persist(new Member()); //3 em.persist(new Member()); //4 em.persist(new Chil..

JVM/JPA 2023.07.04

SQL 쿼리 힌트 사용

SQL 힌트(데이터베이스 벤더에게 제공하는 힌트)를 사용하려면 하이버네이트를 직접 사용해야 한다. 오라클이 아닌 다른 데이터베이스에서 SQL 힌트를 사용하려면 각 방언에서 org.hibernate.dialect.Dialect.getQueryHintString() 메소드를 오버라이딩해서 기능을 구현해야 한다. Session session = em.unwrap(Session.class); List list = session.createQuery("SELECT m FROM Member m") .addQueryHint("FULL (MEMBER)") .list();

JVM/JPA 2023.07.04

읽기 전용 쿼리의 성능 최적화

영속성 컨텍스트는 변경 감지를 위해 스냅샷 인스턴스를 보관하므로 더 많은 메모리를 사용하는 단점이 있다. 다시 조회할 일도 수정할 일도 없이 딱 한 번만 읽어서 화면에 출력하면 될 때는 읽기 전용으로 엔티티를 조회하면 메모리 사용량을 최적화할 수 있다. 메모리를 최적화하려면 하이버네이트가 제공하는 읽기 전용 쿼리 힌트를 사용하고, 플러시 호출을 막아서 속도를 최적화하려면 읽기 전용 트랜잭션을 사용하는 것이 가장 효과적이다. 스칼라 타입으로 조회 스칼라 타입은 영속성 컨텍스트가 결과를 관리하지 않는다. SELECT o.id, o.name, o.price FROM Order o 읽기 전용 쿼리 힌트 사용 하이버네이트 전용 힌트인 org.hibernate.readOnly를 사용하면 읽기 전용으로 조회할 수 있..

JVM/JPA 2023.07.04

N+1 문제

N+1 문제 연관된 엔티티를 조회할 때 SQL문이 실행되는 것을 N+1 문제라고 한다. 즉시 로딩을 사용할 때도 JPQL은 JPQL만 사용해서 SQL을 생성하기에 N+1 문제가 발생할 수 있다. 모두 지연 로딩으로 설정하고 성능 최적화가 꼭 필요한 곳에는 JPQL 페치 조인을 사용하자. 페치 조인 사용 N+1 문제를 해결하는 가장 일반적인 방법은 페치 조인을 사용하는 것이다. 이때 조심해야 할 것은 일대다 조인일 경우 중복된 결과가 나타날 수 있으므로 JPQL의 DISTINCT를 사용해서 중복을 제거하는 것이다. 하이버네이트 @BatchSize 연관된 엔티티를 조회할 때 지정한 size만큼 SQL의 IN 절을 사용해서 조회한다. 만약 조회한 회원이 10명인데 size=5로 지정하면 2번의 SQL만 추가로..

JVM/JPA 2023.07.04