IssuedAt : 25 - 09 - 23 (화)
Daily Study : 7
Java
| 참조형과 메서드 호출 활용
| 변수와 초기화
| null
| NullPointerException
(복습 #2)
-( GC ) 아무도 참조하지 않는 인스턴스의 최후
C와 같은 과거 프로그래밍 언어는 개발자가 직접 명령어를 사용해서 인스턴스를 메모리에서 제거해야 했다. 왜냐하면 메모리에 사용하지 않는 객체가 가득차면 메모리 부족 오류가 발생하게 된다.
자바에서는 인스턴스를 메모리에서 제거하는 것을 자동으로 처리해준다. 아무도 참조하지 않는 인스턴스가 있으면 JVM의 GC(가비지 컬렉션)가 더 이상 사용하지 않는 인스턴스라 판단하고 해당 인스턴스를 자동으로 메모리에서 제거해준다.
객체는 해당 객체를 참조하는 곳이 있으면, JVM이 종료할 때 까지 계속 생존한다. 중간에 해당 객체를 참조하는 곳이 모두 사라지면 그때 JVM은 필요 없는 객체로 판단하고 GC(가비지 컬렉션)를 사용해서 제거해준다.
보안구성
마이크로서비스 아키텍처에서는 각 서비스가 독립적으로 배포되고 통신하기 때문에 보안이 매우 중요하다.
데이터 보호, 인증 및 권한 부여, 통신 암호화 등을 통해 시스템의 보안성을 확보해야 한다.
-OAuth2
토큰 기반의 인증 및 권한 부여 프로토콜입니다.
클라이언트 애플리케이션이 리소스 소유자의 권한을 얻어 보호된 리소스에 접근할 수 있도록 합니다.
4가지의 역할을 정의합니다. 리소스 소유자, 클라이언트, 리소스 서버, 인증 서버
Authorization Code Grant : 인증 코드를 사용하여 액세스 토큰을 얻는 방식
Implicit Grant : 클라이언트 애플리케이션에서 직접 액세스 토큰을 얻는 방식
Resource Owner Password Credentials Grant : 사용자 이름과 비밀번호를 사용하여 액세스 토큰을 얻는 방식
Client Credentials Grant : 클라이언트 애플리케이션이 자신의 자격 증명을 사용하여 액세스 토큰을 얻는 방식
-JWT
Json Web Token 는 JSON 형식의 자가 포함된 토큰으로, 클레임(claim)을 포함하여 사용자에 대한 정보를 전달한다.
JWT는 세 부분으로 구성된다. 헤더, 페이로드, 서명
JWT는 암호화를 통해 데이터의 무결성과 출처를 보장한다.
자가 포함 : 토큰 자체에 모든 정보를 포함하고 있어 별도의 상태 저장이 필요 없습니다.
간결성 : 짧고 간결한 문자열로, URL, 헤더 등에 쉽게 포함될 수 있습니다.
서명 및 암호화 : 데이터의 무결성과 인증을 보장합니다.
-Bearer
OAuth2.0 에서는 약속이 있는데, 토큰 앞에 Bearer을 식별자를 붙이기로 했다.
-기타
MSA 아키텍처로 설계할 시, 방화벽 처리를 통해 클라이언트들이 게이트 웨이 포트만 활용할 수 있도록 해야 한다.
각각의 서비스들은 포트 번호가 있는데, 그 포트 번호들을 클라이언트가 다이렉트로 접속하여 사용할 수 없게 설계 해야하는 거 같다.
Config
-Spring Cloud Config
분산 시스템 환경에서 중앙 집중식 구성 관리를 제공하는 프레임워크이다.
애플리케이션의 설정을 중앙에서 관리하고, 변경 사항을 실시간으로 반영할 수 있다.
Git, 파일 시스템, JDBC등 다양한 저장소를 지원한다.
중앙 집중식 구성 관리 : 모든 마이크로서비스의 설정을 중앙에서 관리합니다.
환경별 구성 : 개발, 테스트, 운영 등 환경별로 구성을 분리하여 관리할 수 있습니다.
실시간 구성 변경 : 설정 변경 시 애플리케이션을 재시작하지 않고도 실시간으로 반영할 수 있습니다.
-실시간 구성 변경
실시간 구성 변경을 반영하는 방법에는 여러 가지가 있다.
| Spring Cloud Bus
| /actuator/refresh 엔드포인트를 호출
| Spring Boot DevTools
| Git 저장소 사용
--Spring Cloud Bus
설정 변경 사항을 실시간으로 클라이언트 애플리케이션에 반영할 수 있다.
이를 위해서는 메시징 시스템(RabbitMQ 또는 Kafka등)을 사용하여 변경 사항을 전파해야 한다.
--수동 구성 갱신 (/actuator/refresh 엔드포인트 사용)
Spring Cloud Bus를 사용하지 않는 경우, 클라이언트 애플리케이션에서 수동으로 설정을 갱신할 수 있다.
이를 위해 Spring Acturator의 /actuator/refresh 엔드포인트를 사용할 수 있다.
1. Config 서버에서 설정 파일을 변경한다.
2. 클라이언트 애플리케이션의 /actuator/refresh 엔드포인트를 POST 요청으로 호출하여 변경된 설정을 반영한다.
해당 방법은 간단하지만, 각 클라이언트 애플리케이션에서 수동으로 엔드포인트를 호출해야 한다.
--수동 구성 갱신 (Spring Boot DevTools 사용)
개발 환경에서 파일 변경을 자동으로 감지하고 애플리케이션을 재시작 할 수 있다.
이는 classpath 내의 파일 변경도 포함된다.
--Git 저장소 사용
Git 저장소에서 설정 파일을 읽어오도록 설정할 수 있다. 이는 설정 파일의 변경 사항을 쉽게 반영하고, 여러 서비스 간에 일관된 구성을 유지하는 데 유용하다.
-기타
실습하는 것은 네이티브 모드를 사용해서 진행하였다.
로컬 환경(네이티브 모드)에서는 설정 변경 후 반영하려면 애플리케이션을 재시작 해야한다.
현업에서는 직접 컨피그 서버를 구현하기보다는, 이미 구축된 컨피그 서버를 연동하여 사용하는 경우가 일반적일것이다.
분산추적
분산 추적은 분산 시스템에서 서비스 간의 요청 흐름을 추적하고 모니터링하는 방법이다.
각 서비스의 호출 관계와 성능을 시각화하여 문제를 진단하고 해결할 수 있도록 도와줍니다.
주요 개념 : 트레이스(Trace), 스펜(Span), 컨텍스트(Context)
-왜 분산 추적이 필요한가?
마이크로서비스 아키텍처에서는 여러 서비스가 협력하여 하나의 요청을 처리한다.
서비스 간의 복잡한 호출 관계로 인해 문제 발생 시 원인을 파악하기 어려울 수 있다.
분산 추적을 통해 각 서비스의 호출 흐름을 명확히 파악하고, 성능 병목이나 오류를 빠르게 진단할 수 있다.
-Micrometer
Spring 기반 애플리케이션에서 메트릭을 수집하고 모니터링하기 위한 라이브러리이다.
각 서비스의 성능 지표를 수집하고, Prometheus, Grafana등과 연동하여 시각화할 수 있다.
분산 추적을 위한 기능도 제공하여 서비스 간의 호출 흐름을 추적할 수 있습니다.
다양한 메트릭 수집 : 애플리케이션의 다양한 성능 지표를 수집할 수 있습니다.
유연한 연동 : Prometheus, Grafana 등 다양한 모니터링 도구와 연동할 수 있습니다.
추적 기능 : 서비스 간의 호출 흐름을 추적하여 성능 병목을 진단할 수 있습니다.
-Zipkin
트레이스 데이터를 수집하고 시각화하는 분산 추적 시스템입니다.
각 서비스의 트레이스와 스팬 데이터를 저장하고, 이를 통해 호출 흐름을 시각화합니다.
데이터 수집 및 저장 : 각 서비스에서 전송된 트레이스 데이터를 수집하고 저장합니다.
시각화 : 트레이스 데이터를 시각화하여 서비스 간의 호출 관계를 명확히 파악할 수 있습니다.
검색 및 필터링 : 특정 트레이스나 스팬을 검색하고 필터링하여 문제를 진단할 수 있습니다.
집킨을 사용하기 위해서는 도커가 필요하다.
이벤트 드리븐
-이벤트 드리븐 아키텍처란?
시스템에서 발생하는 이벤트(상태 변화나 행동)를 기반으로 동작하는 소프트웨어 설계 스타일입니다.
이벤트는 비동기적으로 처리되며, 서비스 간의 느슨한 결합을 통해 독립적으로 동작할 수 있게 합니다.
이벤트 : 시스템 내에서 발생하는 상태 변화나 행동을 나타내는 메시지입니다.
이벤트 소스 : 이벤트를 생성하여 이벤트 버스에 전달하는 역할을 합니다.
이벤트 핸들러 : 이벤트를 수신하여 처리하는 역할을 합니다.
이벤트 버스 : 이벤트 소스와 이벤트 핸들러 간의 메시지 전달을 중개합니다.
-이벤트 드리븐 아키텍처의 장점
--느슨한 결합
서비스 간의 강한 종속성을 제거하여 독립적인 개발과 배포가 가능하다.
이벤트 기반 통신을 통해 서비스 간의 결합도를 낮춘다.
--확장성
수평 확장이 용이하여 대규모 시스템에서 유용하다.
이벤트 프로듀서와 컨슈머를 독립적으로 확장 가능하다.
--비동기 처리
이벤트를 비동기적으로 처리하여 시스템의 응답성을 향상시킨다.
요청과 응답을 비동기적으로 처리하여 성능을 최적화한다.
-이벤트 드리븐 아키텍처의 단점
--복잡성 증가
이벤트 기반 통신으로 인해 시스템의 복잡성이 증가할 수 있다.
이벤트 흐름과 상태 관리를 체계적으로 설계할 필요가 있다.
--장애 전파
이벤트 실패 시 다른 서비스로 장애가 전파될 수 있다.
이벤트 재처리 및 장애 복구 메커니즘 구현이 필요하다.
-Spring Cloud Stream
이벤트 드리븐 마이크로서비스를 구축하기 위한 프레임워크입니다.
Kafka, RabbitMQ 등의 메시지 브로커와 통합하여 이벤트 스트리밍을 처리합니다.
프로듀서와 컨슈머 간의 통신을 추상화하여 간편하게 이벤트 기반 애플리케이션을 개발할 수 있습니다.
바인더 추상화 : 메시지 브로커와의 통합을 위한 추상화 레이어를 제공합니다.
프로듀서/컨슈머 모델 : 이벤트를 생성하고 처리하는 프로듀서와 컨슈머 모델을 지원합니다.
유연한 설정 : 다양한 설정 옵션을 통해 손쉽게 커스터마이징할 수 있습니다.
-Producer Consumer 패턴

프로듀서 : 이벤트를 발행 시켜서 주는 역할
컨슈머 : 이벤트를 받아서 처리하는 역할
주문이 한 건이 생성되면 배송지입력, 결제처리, 상품처리등을 메시지 큐로 전달이 된다.
메시지 큐에서 배송지입력, 결제처리, 상품처리를 각각 다른 Consumer에 전달이 된다.
Consumer 에서 각각 처리를 하는데.. 만약 상품처리에서 오류가 발생한다고 했을 때 이 패턴에서 가장 큰 문제가 발생한다.
상품이 처리가 안되면 결제도 안되고 배송지처리도 안되야 하는데 Consumer들은 큐만 바라보고 있기 때문에 오류가 발생한 것을 알수가 없다.
--이것을 처리하기 위해서는?
전략에 따라서 다를 수 있는데.. 우선 강사님의 해결 방법은 문제가 생긴거를 누군가에게 전파를 해줘야 한다고 한다. 메시지 큐를 보낸 producer에 전달을 해주거나, 또 하나의 애플리케이션 error를 처리하는 애플리케이션에 에러가 발생한 것을 전달 해줄 수 있다.
error 애플리케이션도 전달을 받을 때 메시지를 받을 때 메시지 큐를 통하여 전달 받는게 좋다고 한다.
결제, 배송지 입력도 에러가 날 수 있다.
수동으로 처리를 할 수 있고, 자동으로 처리를 할 수 있는데 설계하는것에 따라 다른데,
에러가 났을 때 에러 메시지를 확인하고 에러가 어떤 메시지라고 보낼 때 객체 내용에 에러발생 사유가 있을건데 그 사유를 넣어서 보내줄 건데 에러를 받아서 첫 번째로 어느 앱에서 온건지 확인하고 무슨 에러인지 확인해서 처리하도록 만들면 된다.
단순 지연으로 인한 처리가 안된거는 다시 큐로 데이터를 보내줄 수 있고, 다시 Consumer로 돌아가서 실행을 하는데 또 실패하는 경우 에러로 와서 카운트가 누적되고 누적해서 실패할경우 정말 에러로 판단하고 모든 작업을 되돌리거나 저장해서 엎는 처리를 할 수 있다고 생각할 수 있다.
플로우를 생각하고 어떤 처리가 있어야되겠다 라는 판단을 하면 된다.
기타
새로운 기능을 추가하거나 애플리케이션을 추가할 때 기존에 있는 패턴을 파악해서 동일하게 유지하면서 가는 것이 제일 좋다.
가장 좋은 방법은 CRUD를 확인하는 것이 좋다.
기존 CRUD를 어떻게 생성하는지 사이클을 샘플로 만들어 보는 것이 좋다.
RESTful이든, 레거시 방법이든 CRUD 확인해보자..
-쿠버네티스
컨테이너화된 애플리케이션의 배포, 확장, 운영을 자동화하는 오픈소스 플랫폼이다.
Google에서 개발하고 현재는 CNCF에서 관리한다. Cloud Native Computing Foundation
컨테이너 오케스트레이션 도구로, 다수의 컨테이너를 효율적으로 관리할 수 있다.
컨테이너 : 애플리케이션과 그 종속성을 함께 패키징한 가상화된 환경이다.
Pod : 쿠버네티스에서 실행되는 최소 단위의 배포 객체로, 하나 이상의 컨테이너를 포함한다.
노드(Node) : 쿠버네티스 클러스터에서 Pod가 실행되는 물리적 또는 가상 머신이다.
클러스트 : 여러 노드로 구성된 쿠버네티스의 집합이다.
네임스페이스 : 클러스터 내에서 리소스를 논리적으로 구분하는 단위이다.
-쿠버네티스와 Spring Cloud 비교
--공통점
확장성 : 둘 다 마이크로서비스 아키텍처의 확장성을 지원합니다.
관리성 : 서비스의 배포, 관리, 확장 등을 쉽게 할 수 있도록 도와준다.
고가용성 : 서비스의 가용성을 높이고, 장애 발생 시 자동 복구를 지원한다.
--차이점
( 초점 )
Spring Cloud는 마이크로서비스 간의 통신, 서비스 디스커버리, 구성 관리 등 애플리케이션 레벨의 문제 해결에 초점을 두고,
쿠버네티스는 컨테이너 관리, 배포, 스케일링 등 인프라 레벨의 문제 해결에 초점을 둔다.
( 구성 요소 )
Spring Cloud : Eureka, Ribbon, Zuul, Config Server, Hystrix 등 다양한 마이크로서비스 패턴을 지원하는 구성 요소
쿠버네티스 : Pod, Deployment, Service, Ingress, ConfigMap, Secret 등 컨테이너 오케스트레이션에 필요한 구성 요소.
( 배포 방식 )
Spring Cloud : 애플리케이션 코드와 함께 다양한 클라우드 서비스에 직접 배포.
쿠버네티스 : 컨테이너 이미지를 기반으로 클러스터 내에서 배포 및 관리.
-Spring Cloud와의 통합도 가능
Spring Cloud Kubernetes는 Spring Cloud와 Kubernetes의 통합을 지원합니다.
서비스 디스커버리, ConfigMap, Secrets등을 Spring Cloud 애플리케이션에서 사용할 수 있도록 지원합니다.
서비스 디스커버리 : Kubernetes API를 통해 서비스 인스턴스를 동적으로 검색하고 로드 밸런싱을 수행합니다.
구성 관리 : Kubernetes ConfigMap과 Secrets을 사용하여 애플리케이션 설정을 중앙에서 관리합니다.
자동화된 배포 : CI/CD 파이프라인과 통합하여 애플리케이션의 자동 배포와 관리를 지원합니다.
-쿠버네티스의 장점과 단점
--장점
확장성 : 수평 확장을 통해 대규모 트래픽을 처리할 수 있다.
자동화 : 배포, 스케일링, 복구 등의 작업을 자동화하여 운영 부담을 줄입니다.
유연성 : 다양한 인프라 환경에서 일관된 운영이 가능합니다.
--단점
복잡성 : 초기 설정과 운영에 대한 학습 곡선이 높습니다.
운영 비용 : 클러스터 운영과 모니터링에 추가적인 리소스가 필요합니다.
디버깅 어려움 : 분산 환경에서 문제를 추적하고 해결하는 것이 복잡할 수 있습니다.
메모장 프로젝트 설계
(복습 #2)
Create, Read 구현하기
(복습 #2)
-DTO
이름에서도 알 수 있듯이 DTO(Data Transfer Object)는 데이터 전송 및 이동을 위해 생성되는 객체를 의미한다.
Client에서 보내오는 데이터를 객체로 처리할 때 사용한다.
또한 서버의 계층간의 이동에도 사용합니다.
그리고 DB와의 소통을 담당하는 Java 클래스를 그대로 Client에 반환하는 것이 아니라 DTO로 한번 변환 후 반환할 때도 사용한다.
Request의 데이터를 처리할 때 사용되는 객체는 RequestDto
Response를 할 때 사용되는 객체는 ResponseDto라는 이름을 쓰는데
절대적인 규칙이 아니기 때문에 조직에 따라 규칙이 다를 수 있다.
Body부분에 JSON형태로 데이터가 넘어온다면 @RequestBody로 받을 수 있다.
Update, Delete 구현하기
(복습 #2)
'TIL & STUDY' 카테고리의 다른 글
| Daily Study : 9 (1) | 2025.09.25 |
|---|---|
| Daily Study : 8 (0) | 2025.09.24 |
| Daily Study : 6 (1) | 2025.09.22 |
| Daily Study : 5 (0) | 2025.09.20 |
| Daily Study : 4 (0) | 2025.09.19 |