IssuedAt : 25 - 09 - 22(월)
Daily Study : 6
JAVA - 기본형과 참조형 && 변수 대입 && 메서드 호출
(복습 #2)
"자바에서 참조형을 제대로 이해하는 것은 정말 중요하다"
자바에서 메서드의 매개변수( 파라미터 )는 항상 값에 의해 전달된다. 그러나 이 값이 실제 값이냐, 참조( 메모리 주소 )값이냐에 따라 동작이 달라진다.
기본형은 메서드로 기본형 데이터를 전달하면, 해당 값이 복사되어 전달된다. 이 경우, 메서드 내부에서 파라미터의 값을 변경해도, 호출자의 변수 값에는 영향이 없다.
참조형은 메서드로 참조형 데이터를 전달하면, 참조값이 복사되어 전달된다. 이 경우, 메서드 내부에서 파라미터로 전달된 객체의 멤버 변수를 변경하면, 호출자의 객체도 변경된다.
MSA 학습 시작
하나의 개발 언어와 프레임 워크를 정확하게 공부하는 것도 중요하지만, 다른 프레임 워크로 개발해야 할 상황이 생길 수 있다.
기능에 집중 할 필요가 있다.
예를 들어서 사용자 정보 중 암호는 반드시 암호화 해서 저장해야 한다 -> 어떤 프레임 워크로 개발해도 암호는 해당 언어의 난독화 기능을 사용해서 저장하면 된다.
리스트 페이징을 제공해야 한다 -> 스프링 부트에도 리스트를 제공하는 기능이 있으니 이 프레임 워크에도 있지 않을까? 없으면 똑같이 응답을 만들어서 내려줘야 겠다.
Microservices Architecture 는 하나의 애플리케이션을 여러 개의 독립적인 서비스로 분리하며 개발, 배포, 유지보수를 용이하게 하는 소프트웨어 아키텍처 스타일입니다.
각 서비스는 특정 비즈니스 기능을 수행하며, 서로 독립적으로 배포되고 확장될 수 있습니다.
서비스 간의 통신은 주로 HTTP/HTTPS, 메시지 큐 등을 통해 이루어집니다.
주요 특징으로는
독립적인 배포 가능성을 열어줍니다. 각 서비스는 독립적으로 배포할 수 있으며, 다른 서비스에 영향을 주지 않고 업데이트할 수 있습니다.
기술 스택의 다양성올려줍니다. 각 서비스는 적절한 기술 스택을 자유롭게 선택할 수 있습니다.
모놀리틱 아키텍처와 MSA 아키텍처

모놀리틱 부터 정의부터 확인해보면
모놀리틱 아키텍처는 하나의 큰 코드베이스로 구성된 애플리케이션입니다.
모든 기능이 하나의 애플리케이션 내에 포함되어 있습니다.
장점으로는 간단한 배포가 가능합니다. 모든 코드가 하나의 코드베이스에 포함되어 있어 배포가 단순합니다.
그리고 단일 데이터베이스가 있는데 하나의 데이터베이스를 사용하여 데이터 일관성을 쉽게 유지할 수 있습니다.
단점으로는 확장성이 부족합니다. 특정 기능을 확장하려면 전체 애플리케이션을 확장해야 합니다.
작은 변경 사항도 전체 애플리케이션을 다시 배포해야해서 개발 주기가 깁니다.
새로운 기술 도입이 어렵고, 특정 모듈에 종송적이라 유연성이 부족합니다.
MSA 정의도 확인해보면
MSA는 여러 개의 독립적인 서비스로 구성된 애플리케이션입니다.
각 서비스는 특정 비즈니스 기능을 수행합니다.
장점으로는 특정 서비스만 확장하여 성능을 최적화할 수 있기에 확장성이 넓어지고, 개별 서비스의 변경 사항을 독립적으로 배포할 수 있어 독립적 배포가 가능합니다. 서비스 별로 적합한 기술 스택을 선택할 수 있어서 유연성도 넓어집니다.
단점으로는 서비스 간 통신, 데이터 일관성 유지 등의 복잡성이 증가합니다. 각 서비스의 모니터링, 로깅 등을 개별적으로 관리해야 하여 운영 비용이 증가합니다.
초반에는 모놀리틱으로 프로젝트를 진행하면서 점점 규모가 커지면 MSA 아키텍처로 넘어가는 것이 좋다고 한다.
Spring Colud
마이크로서비스 개발을 위해 다양한 도구와 서비스를 제공하는 스프링 프레임 워크의 확장이다. 마이크로서비스 아키텍처를 쉽게 구현하고 운영할 수 있도록 도와준다.
주요 기능으로는
서비스 등록 및 디스커버리 : Eureka, consul, Zookeeper
로드 밸런싱 : Ribbon, Spring Cloud LoadBalancer
서킷 브레이커 : Hystrix, Resilience4j
APi 게이트웨이 : Zuul, Spring Cloud Gateway
구성 관리 : Spring Cloud Config
분산 추적 : Spring Cloud Sleuth, Zipkin
메시징 : Spring Cloud Stream
서비스 등록 및 디스커버리
( Eureka )
넷플릭스가 개발한 서비스 디스커버리 서버로, 마이크로서비스 아키텍처에서 각 서비스의 위치를 동적으로 관리합니다.
모든 서비스 인스턴스의 위치를 저장하는 중앙 저장소역할인 서비스 레지스트리이며,
서비스 인스턴스의 상태를 주기적으로 확인하여 가용성을 보장합니다. ( 헬스 체크 )
로드 밸런싱
( Ribbon )
넷플릭스가 개발한 클라이언트 사이트 로드 밸런서로, 서버 인스턴스 간의 부하를 분산합니다.
서비 리스트 제공자 : Eureka로 부터 서비스 인스턴스 리스트를 제공받아 로드 밸런싱에 사용합니다.
로드 밸런싱 알고리즘 : 라운드 로빈, 가중치 기반 등 다양한 로드 밸런싱 알고리즘을 지원합니다.
Failover : 요청 실패 시 다른 인스턴스로 자동 전환합니다.
서킷 브레이커
( Hystrix )
넷플릭스가 개발한 서킷 브레이커 라이브러리로, 서비스 간의 호출 실패를 감지하고 시스템의 전체적인 안정성을 유지
서빗 브레이커 상태 : 클로즏, 오픈, 하프-오픈 상태를 통해 호출 실패를 관리
Fallback : 호출 실패 시 대체 로직을 제공하여 시스템 안정성 확보
모니터링 : Hystrix Dashboard를 통해 서킷 브레이커 상태 모니터링
( Resilience4j )
자바 기반의 경량 서킷 브레이커 라이브러리로, 넷플릭스 Hystrix의 대안으로 개발
서킷 브레이커 : 호출 실패를 감지하고 서킷을 열어 추가적인 호출을 차단하여 시스템의 부하를 줄임
Fallback : 호출 실패 시 대체 로직을 실행하여 시스템의 안정성을 유지
타임아웃 설정 : 호출의 응답 시간을 설정하여 느린 서비스 호출에 대응할 수 있음
재시도 : 재시도 기능을 지원하여 일시적인 네트워크 문제 등에 대응할 수 있음.
API 게이트웨이
( Zuul )
넷플릭스가 개발한 API 게이트웨이로, 모든 서비스 요청을 중앙에서 관리
라우팅 : 요청 URL에 따라 적절한 서비스로 요청 전달
필터 : 요청 전후에 다양한 작업을 수행할 수 있는 필터 체인 제공
모니터링 : 요청 로그 및 메트릭을 통해 서비스 상태 모니터링 할 수 있음.
( Cloud gateway )
클라우드 게이트웨이는 스프링 클라우드에서 제공하는 API 게이트웨이로, 마이크로서비스 아키텍처에서 필수적인 역할
루팅 및 필터링 : 요청을 받아 특정 서비스로 라우팅하고 필요한 인증 및 권한 부여를 수행
보안 : 외부 요청으로부터 애플리케이션을 보호하고, 보안 정책을 적용함
효율성 : 마이크로서비스 아키텍처에서 필요한 요청 처리 및 분산 환경의 관리를 효율적으로 수행
구성 관리
( Spring Cloud Config )
분산된 환경에서 중앙 집중식 설정 관리를 제공 합니다.
Config 서버 : 중앙에서 설정 파일을 관리하고 각 서비스에 제공
Config 클라이언트 : Config 서버에서 설정을 받아서 사용하는 서비스
설정 갱신 : 설정 변경 시 서비스 재시작 없이 실시간으로 반영
서비스 디스커버리
📒 서비스 디스커버리란?
마이크로서비스 아키텍처에서 각 서비스의 위치를 동적으로 관리하고 찾아주는 기능
각 서비스는 등록 서버에 자신의 위치를 등록하고, 다른 서비스는 이를 조회하여 통신함
주요 기능으로는 서비스 등록, 서비스 조회, 헬스 체크 등.
현업에서는 apllication.properties 파일보다 yml 파일을 많이 사용할 것이고,
properties에서는 .(dot)으로 사용하는 반면 yml 에서는 들여쓰기 방식을 사용한다.
로드밸런싱
📒 로드 밸런싱이란?
로드 밸런싱은 네트워크 트래픽을 여러 서버로 분산시켜 서버의 부하를 줄이고, 시스템의 성능과 가용성을 높이는 기술이다.
서버 간 트래픽을 고르게 분배하여 특정 서버에 부하가 집중되는 것을 방지한다.
클라이언트 사이드 로드 밸런싱과 서버 사이드 로드 밸런싱 두 가지 종류가 있다.
클라이언트 사이드 로드 밸런싱이란 ?
클라이언트 사이드 로드 밸런싱은 클라이언트가 직접 여러 서버 중 하나를 선택하여 요청을 보내는 방식이다.
클라이언트는 서버의 목록을 가지고 있으며, 이를 바탕으로 로드 밸런싱을 수행한다.
📒 FeignClien?
FeignClient는 Spring Cloud에서 제공하는 HTTP 클라이언트로, 선언적으로 RESTful 웹 서비스를 호출할 수 있다.
Eureka와 같은 서비스 디스커버리와 연동하여 동적으로 서비스 인스턴스를 조회하고 로드 밸런싱을 수행한다.
선언적 HTTP 클라이언트 : 인터페이스와 어노테이션을 사용하여 REST API를 호출할 수 있다.
Eureka 연동 : Eureka와 통합하여 서비스 인스턴스 목록을 동적으로 조회하고 로드 밸런싱을 수행한다.
자동 로드 밸런싱 : Ribbon이 통합되어 있어 자동으로 로드 밸런싱을 수행한다.
📒 Ribbon
넷플릭스가 개발한 클라이언트 사이드 로드 밸런서로, 마이크로서비스 아키텍처에서 서비스 인스턴스 간의 부하를 분산한다.
다양한 로드 밸런싱 알고리즘을 지원하며, Eureka와 같은 서비스 디스커버리와 연동하여 사용한다.
서버 리스트 제공자 : Eureka등으로부터 서비스 인스턴스 리스트를 제공받아 로드 밸런싱에 사용한다.
로드 밸런싱 알고리즘 : 라운드 로빈, 가중치 기반 등 다양한 로드 밸런싱 알고리즘 지원한다.
Failover : 요청 실패 시 다른 인스턴스로 자동 전환한다.
📒 로드 밸런싱 알고리즘
라운드 로빈 : 각 서버에 순차적으로 요청을 분배하는 방식으로 간단하고 공평하게 트래픽을 분산시킨다.
가중치 기반 로드 밸런싱 : 각 서버에 가중치를 부여하고, 가중치에 비례하여 요청을 분배하는 방식으로 서버의 성능이나 네트워크 상태에 따라 가중치를 조절한다.
기타 알고리즘에는 최소 연결과 응답 시간 기반이 있는데
( 최소 연결 ) : 현재 연결된 클라이언트 수가 가장 적은 서버로 요청을 보내는 방식이다.
( 응답 시간 기반 ) : 서버의 응답 시간을 기준으로 가장 빠른 서버로 요청을 보내는 방식이다.
서킷 브레이커
서킷브레이커는 마이크로 서비스 간의 호출 실패를 감지하고 시스템의 전체적인 안정성을 유지하는 패턴이다.
외부 서비스 호출 실패 시 빠른 실패를 통해 장애를 격리하고, 시스템의 다른 부분에 영향을 주지 않도록 한다.
상태 변화 : 클로즈드 -> 오픈 -> 하프-오픈
( 클로즈드 )
- 기본 상태로, 모든 요청을 통과시킵니다.
- 이 상태에서 호출이 실패하면 실패 카운터가 증가합니다.
- 실패율이 설정된 임계값(예 50%)을 초과하면 서킷 브레이커가 오픈 상태로 전환됩니다.
예시 : 최근 5번의 호출 중 3번이 실패하여 실패율이 60%에 도달하면 오픈 상태로 전환됩니다.
( 오픈 )
- 서킷 브레이커가 오픈 상태로 전환되면 모든 요청을 즉시 실패로 처리합니다.
- 이 상태에서 요청이 실패하지 않고 바로 에러 응답을 반환합니다.
- 설정된 대기 시간이 지난 후, 서킷 브레이커는 하프-오픈 상태로 전환됩니다.
예시 : 서킷 브레이커가 오픈 상태로 전환되고 20초 동안 모든 요청이 차단됩니다.
( 하프-오픈 )
- 오픈 상태에서 대기 시간이 지나면 서킷 브레이커는 하프-오픈 상태로 전환됩니다.
- 하프-오픈 상태에서는 제한된 수의 요청을 허용하여 시스템이 정상 상태로 복구되었는지 확인합니다.
- 요청이 성공하면 서킷 브레이커는 클로즈드 상태로 전환됩니다.
- 요청이 다시 실패하면 서킷 브레이커는 다시 오픈 상태로 전환됩니다.
예시 : 하프-오픈 상태에서 3개의 요청을 허용하고 모두 성공하면 클로즈드 상태로 전환됩니다. 만약 하나라도 실패하면 다시 오픈 상태로 전환됩니다.
Fallback
호출 실패 시 대체 로직을 제공하여 시스템 안정성 확보
모니터링
서킷 브레이커 상태를 모니터링하고 관리할 수 있는 다양한 도구 제공
이 서킷브레이커 단계에서 Resilience4j 를 사용할 건데, maven 이나 spring.io 에서 dependency 추가할 때 Resilience4j 를 선택할 경우 추상화작업만 되어 있고 구현체는 없어서 코드를 구현하는데 있어서 복잡성이 증가한다.
그러므로 학습하는 단계에서는 구현체가 만들어져 있는 깃허브 코드에서 의존성을 받을 거고, 나중에 추가적으로 학습할 때 따로 알아봐야겠다..

Resilience4j Dashboard 를 사용하면 서킷 브레이커의 상태를 모니터링 할 수 있으며 설정은 yml파일에서 설정할 수 있다.
예시 코드
http://${hostname}:${port}/actuator/prometheus 에 접속하여 서킷브레이커 항목을 확인 가능하다.
Prometheus와 Grafana를 사용하여 Resilience4j 서킷 브레이커의 상태를 실시간으로 모니터링할 수 있습니다.
Prometheus를 통해 수집된 메트릭을 Grafana 대시보드에서 시각화할 수 있습니다.
Resilience4j는 Spring Cloud Netflix 패키지의 일부로, Eureka와 Ribbon등 다른 Spring Cloud 구성 요소와 쉽게 통합할 수 있다.
Spring Cloud 서비스 디스커버리와 로드 밸런싱을 이용하여 더욱 안정적인 마이크로서비스 아키텍처를 구축할 수 있다.
fallback 메서드를 테스트, 학습 해보기 위하여 새 프로젝트를 만들고, 상품을 조회하는 로직을 만들어보았다. 그리고 등록되지 않은 상품 예를 들어 111번의 상품이 없다고 했을 때 RuntimeException 예외가 발생하는 포인트를 만들고, 그 포인트가 발생했을 때 fallbackMethod가 실행되도록 로직을 구상하였다.
package com.spring_cloud.resilience4j.sample.products;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Product {
private String id;
private String title;
}
package com.spring_cloud.resilience4j.sample.products;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequiredArgsConstructor
public class ProductController {
private ProductService productService;
@GetMapping("/product/{id}")
public Product getProduct(@PathVariable String id) {
return productService.getProductDetails(id);
}
}
package com.spring_cloud.resilience4j.sample.products;
import io.github.resilience4j.circuitbreaker.annotation.CircuitBreaker;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
@Service
@RequiredArgsConstructor
public class ProductService {
@CircuitBreaker(name = "productService", fallbackMethod = "fallbackGetProductDetails")
public Product getProductDetails(String productId) {
if ("111".equals(productId)) {
throw new RuntimeException("Empty response body");
}
return new Product(productId, "Sample Product");
}
public Product fallbackGetProductDetails(String productId, Throwable throwable) {
return new Product(productId, "Fallback Product");
}
}
그런데, 실행을 했는데 화이트라벨 페이지가 나온다 !?
상태 코드는 500.. 서버 에러가 난 것이다.. 도대체 뭐가 잘못된걸까.. 하고 검색을 해보았는데
난 아직 코생아다.. 컨트롤러에서 service 객체를 의존 받을 때 final 을 붙이지 않으면 에러가 난다고 한다. 붙여주면 에러는 해결 하겠는데 왜 final을 받지 않으면 의존이 안되는거지?? 실제로 커맨드라인에 NullPointerException 으로 널 포인터가 확인이 되었는데 값을 못받아 온다는 뜻인거같다..
답안은 @RequiredConsturctor 에 있었다. 이 어노테이션은 final이 붙었을 경우에만 동작을 한다.
이런 실수를 하지 말고 꼭 신경써서 서비스 계층을 가져오자..
API 게이트웨이
API 게이트웨이란 클라이언트의 요청을 받아 백엔드 서비스로 라우팅하고, 다양한 부가 기능을 제공하는 중간 서버이다.
클라이언트와 서비스 간의 단일 진입점 역할을 하며 보안, 로깅, 모니터링, 요청 필터링 등을 처리합니다.
- 라우팅 : 클라이언트 요청을 적절한 서비스로 전달
- 인증 및 권한 부여 : 요청의 인증 및 권한을 검증
- 로드 밸런싱 : 여러 서비스 인스턴스 간의 부하 분산
- 모니터링 및 로깅 : 요청 및 응답을 로깅하고 모니터링
- 요청 및 응답 변환 : 요청과 응답을 변환하거나 필터링
비동기 프로그램은 순차적이지 않기 때문에 다음 프로세스 상에서 이루어질 동작들이 어떻게 되야 할지 판단하고 중요하게 생각해야 한다.
'TIL & STUDY' 카테고리의 다른 글
| Daily Study : 8 (0) | 2025.09.24 |
|---|---|
| Daily Study : 7 (0) | 2025.09.23 |
| Daily Study : 5 (0) | 2025.09.20 |
| Daily Study : 4 (0) | 2025.09.19 |
| Daily Study : 3 (3) | 2025.09.18 |