[241125 TIL]

    MSA 학습

    MSA 프로젝트 만들어보기

    • 강의 마무리
    • 프로젝트

    MSA 프로젝트

     

     

     

     


    [241122 TIL]

    MSA 학습

    • 보안구성
    • Config
    • 분산추적
    • 이벤트 드리븐

    보안구성

    • 마이크로서비스 아키텍처에서는 각 서비스가 독립적으로 배포되고 통신하기 때문에 보안이 매우 중요
    • 데이터 보호, 인증 및 권한 부여, 통신 암호화 등을 통해 시스템의 보안성을 확보해야 함

    ✏️

    jwt - 변조, 수정의 보안을 말하는거 즉, 데이터 무결성을 확인 페이로드 안에 데이터(정보) 확인을 못하게 암호화한다를 뜻하는 게 아님

    gateway 만 알고 나머지는 사용자가 접근못하게 방화벽 처리 19091로만 접속가능하게


    Spring Cloud Config

    • 분산 시스템 환경에서 중앙 집중식 구성 관리를 제공하는 프레임워크
    • 애플리케이션의 설정을 중앙에서 관리하고, 변경 사항을 실시간으로 반영
    • Git, 파일 시스템, JDBC 등 다양한 저장소를 지원
    • 중앙 집중식 구성 관리: 모든 마이크로서비스의 설정을 중앙에서 관리
    • 환경별 구성: 개발, 테스트, 운영 등 환경별로 구성을 분리하여 관리 가능
    • 실시간 구성 변경: 설정 변경 시 애플리케이션을 재시작하지 않고도 실시간으로 반영할 수 있음

    ✏️

    Config 서버가 native 프로필로 로컬 파일 시스템을 사용할 경우, 파일 변경을 자동으로 감지하지 않음

    그래서 config 가 변경되면 config 서버는 재실행해줘야함!


    분산 추적

    • 분산 시스템에서 서비스 간의 요청 흐름을 추적하고 모니터링하는 방법
    • 각 서비스의 호출 관계와 성능을 시각화하여 문제를 진단하고 해결할 수 있도록 도움
    • 트레이스(Trace) : 하나의 요청이 시작부터 끝까지 각 서비스를 거치는 전체 흐름을 나타냄
    • 스팬(Span) : 분산 추적에서 가장 작은 단위로, 특정 서비스 내에서의 개별 작업 또는 요청을 나타냄
    • 컨텍스트(Context): 요청이 서비스 간에 전달될 때 함께 전파되어, 각 서비스가 요청의 전체 흐름에 대한 정보를 가질 수 있게함
    • 필요성
      • 마이크로서비스 아키텍처에서는 여러 서비스가 협력하여 하나의 요청을 처리
      • 서비스 간의 복잡한 호출 관계로 인해 문제 발생 시 원인을 파악하기 어려울 수 있음
      • 분산 추적을 통해 각 서비스의 호출 흐름을 명확히 파악하고, 성능 병목이나 오류를 빠르게 진단할 수 있음

    이벤트 드리븐 아키텍처

    • 시스템에서 발생하는 이벤트(상태 변화나 행동)를 기반으로 동작하는 소프트웨어 설계 스타일
    • 이벤트는 비동기적으로 처리되며, 서비스 간의 느슨한 결합을 통해 독립적으로 동작할 수 있게함
    • 이벤트: 시스템 내에서 발생하는 상태 변화나 행동을 나타내는 메시지
    • 이벤트 소스: 이벤트를 생성하여 이벤트 버스에 전달하는 역할
    • 이벤트 핸들러: 이벤트를 수신하여 처리하는 역할
    • 이벤트 버스: 이벤트 소스와 이벤트 핸들러 간의 메시지 전달을 중개
    • 장점
      • 느슨한 결합
        • 서비스 간의 강한 종속성을 제거하여 독립적인 개발과 배포가 가능
        • 이벤트 기반 통신을 통해 서비스 간의 결합도 낮춤
      • 확장성
        • 수평 확장이 용이하여 대규모 시스템에서 유용
        • 이벤트 프로듀서와 컨슈머를 독립적으로 확장 가능
      • 비동기 처리
        • 이벤트를 비동기적으로 처리하여 시스템의 응답성 향상
        • 요청과 응답을 비동기적으로 처리하여 성능 최적화
    • 단점
      • 복잡성 증가
        • 이벤트 기반 통신으로 인해 시스템의 복잡성 증가 가능
        • 이벤트 흐름과 상태 관리를 체계적으로 설계 필요
      • 장애 전파
        • 이벤트 실패 시 다른 서비스로 장애가 전파될 수 있음
        • 이벤트 재처리 및 장애 복구 메커니즘 구현 필요

    [241121 TIL]

    MSA 학습

    • 서비스 디스커버리
    • 로드 밸런싱
    • 서킷 브레이커
    • API GW

    서비스 디스커버리

    • 마이크로서비스 아키텍처에서 각 서비스의 위치를 동적으로 관리하고 찾아주는 기능
    • 각 서비스는 등록 서버에 자신의 위치를 등록하고, 다른 서비스는 이를 조회하여 통신

    Eureka

    • 넷플릭스가 개발한 서비스 디스커버리
    • 모든 서비스 인스턴스의 위치를 저장하는 중앙 저장소 역할을 하며, 서비스 인스턴스의 상태를 주기적으로 확인하여 가용성 보장
    • 여러 인스턴스를 지원하여 고가용성 유지
    • Eureka Server
      • 설정 파일을 통해 서버를 구성하고, 클라이언트가 등록할 수 있도록 준비
    • Eureka Client
      • spring-cloud-starter-netflix-eureka-client 의존성 사용
    • 서비스 디스커버리
      • RestTemplate 사용 - @LoadBalanced
      • FeignClient 사용 - @EnableFeignClients, @FeignClient

    로드 밸런싱

    • 네트워크 트래픽을 여러 서버로 분산시켜 서버의 부하를 줄이고, 시스템의 성능과 가용성을 높이는 기술
    • 서버 간 트래픽을 고르게 분배하여 특정 서버에 부하가 집중되는 것을 방지
    • 클라이언트 사이드 로드 밸런싱
      • 클라이언트가 직접 여러 서버 중 하나를 선택하여 요청을 보내는 방식
      • 클라이언트는 서버 목록을 가지고 있으며, 이를 바탕으로 로드 밸런싱 수행

     

    FeignClient

    • Spring Cloud 에서 제공하는 HTTP 클라이언트로, 선언적으로 RESTful 웹 서비스를 호출할 수 있음
    • Eureka 와 같은 서비스 디스커버리와 연동하여 동적으로 서비스 인스턴스를 조회하고 로브 밸런싱 수행
    • 선언적 HTTP 클라이언트: 인터페이스와 어노테이션을 사용하여 REST API 를 호출할 수 있음
    • Eureka 연동: Eureka 와 통합하여 서비스 인스턴스 목록을 동적으로 조회하고 로드 밸런싱 수행
    • 자동 로드 밸런싱: Ribbon 이 통합되어 있어 자동으로 로드 밸런싱 수행

     

    Ribbon

    • 넷플릭스가 개발한 클라이언트 사이드 로드 밸런서
    • 다양한 로드 밸런싱 알고리즘 지원하며, Eureka 와 같은 서비스 디스커버리와 연동하여 사용
    • 서버 리스트 제공자: Eureka 등으로부터 서비스 인스턴스 리스트를 제공 받아 로드 밸런싱에 사용
    • 로드 밸런싱 알고리즘: 라운드 로빈, 가중치 기반 등 다양한 로드 밸런싱 알고리즘 지원
    • Failover: 요청 실패 시 다른 인스턴스로 자동 전환

    ✏️ Ribbon 기본이 라운드 로빈 방식인듯!


    서킷 브레이커

    • 마이크로서비스 간의 호출 실패를 감지하고 시스템의 전체적인 안정성을 유지하는 패턴
    • 외부 서비스 호출 실패 시 빠른 실패를 통해 장애를 격리하고, 시스템의 다른 부분에 영향을 주지 않도록 함
    • 상태 변화: 클로즈드 -> 오픈 -> 하프 오픈

     

    Resilience4j

    • 서킷 브레이커 라이브러리
    • 상태
      • 클로즈드(Closed)
        • 기본 상태로 모든 요청 통과, 호출 실패시 실패 카운터 증가
        • 실패율이 설정된 임계값을 초과하면 서킷 브레이커가 오픈 상태로 전환
      • 오픈(Open)
        • 오픈 상태로 전환시, 모든 요청을 즉시 실패 처리, 바로 에러 응답 반환
        • 설정된 대기 시간 경과 후, 하프-오픈 상태로 전환
      • 하프-오픈(Half-Open)
        • 오픈 상태에서 대기 시간이 지나면 하프-오픈 상태로 전환
        • 제한된 수의 요청을 허용하여 시스템이 정상 상태로 복구되었는지 확인
        • 요청 성공시, 클로즈드 상태로 전환 / 요청 실패시, 오픈 상태로 전환
    • Fallback: 호출 실패 시 대체 로직을 제공하여 시스템 안정성 확보
    • 모니터링: 서킷 브레이커 상태를 모니터링하고 관리할 수 있는 다양한 도구 제공

    API GW

    • 클라이언트의 요청을 받아 백엔드 서비스로 라우팅하고, 다양한 부가 기능을 제공하는 중간 서버
    • 클라이언트와 서비스 간의 단일 진입점 역할을 하며, 보안, 로깅, 모니터링, 요청 필터링 등을 처리

     

    Spring Cloud Gateway

    • Spring 프로젝트의 일환으로 개발된 API 게이트웨이
    • 동적 라우팅: 요청의 URL 패턴에 따라 동적으로 라우팅
    • 필터링: 요청 전후에 다양한 작업을 수행할 수 있는 필터 체인 제공
      • Global Filter: 모든 요청에 대해 작동하는 필터
      • Gateway Filter: 특정 라우트에만 적용되는 필터
      • PreFilter: 요청이 처리되기 전에 실행
      • PostFilter: 요청이 처리된 후, 응답이 반환되기 전에 실행
    • 모니터링: 요청 로그 및 메트릭을 통해 서비스 상태 모니터링
    • 보안: 요청의 인증 및 권한 검증

     

    ✏️ gw 가 없으면 사용자가 다 다른 호스트로 api 요청해야함

    ✏️ gw 가 있으면 gw 로 요청하면 gw 가 알아서 라우팅!


    [241120 TIL]

    MSA 학습

    • 코드카타
    • MAS 강의

    모놀리식 아키텍처(Monolithic Architecture: MA)

     

    • 하나의 큰 코드베이스로 구성된 애플리케이션
    • 모든 기능이 하나의 애플리케이션 내에 포함
    • 장점
      • 간단한 배포: 모든 코드가 하나의 코드베이스에 포함되어 있어 배포가 단순
      • 단일 데이터베이스: 하나의 데이터베이스를 사용하여 데이터 일관성을 쉽게 유지
    • 단점
      • 확장성 부족: 특정 기능을 확장하려면 전체 애플리케이션을 확장해야 함
      • 긴 개발 주기: 작은 변경 사항에도 전체 애플리케이션을 다시 배포해야 함
      • 유연성 부족: 새로운 기술 도입이 어렵고, 특정 모듈에 종속적
      • ex) 회원에서 기능 변경 및 확장이 생기면, 상품/주문 서비스에서는 해당 사항이 없어도 전체 애플리케이션을 확장/배포해야 함

    MSA(Microservice Architecture)

    • 여러 개의 독립적인 서비스로 구성된 애플리케이션
    • 각 서비스는 특정 비즈니스 기능을 수행
    • 장점
      • 확장성: 특정 서비스만 확장 가능, 특정 기능에 대한 성능 최적화가 용이
      • 독립적 배포: 개별 서비스의 변경 사항을 독립적으로 배포할 수 있음 -> 배포 주기 단축
      • 유연성: 다양한 기술 스택을 사용하여 서비스별 최적화 가능
      • 작은 구성: 서비스별 작은 팀으로 구성되어 민첩한 개발 가능
    • 단점
      • 복잡성 증가: 서비스 간 통신, 데이터 일관성 유지, 트랜잭션 관리 등의 복잡성 증가
      • 운영비용 증가: 각 서비스의 모니터링, 로깅, 장애 대등 등을 개별적으로 관리해야 함
      • 데이터 관리: 분산된 데이터베이스로 인해 데이터 일관성 유지가 어려울 수 있음
      • 네트워크 지연: 서비스 간의 통신이 네트워크를 통해 이루어지므로 지연 시간이 발생할 수 있음

    Spring Cloud

    • 마이크로서비스 개발을 위해 다양한 도구와 서비스를 제공하는 스프링 프레임워크의 확장
    • 마이크로서비스 아키텍처를 쉽게 구현하고 운영할 수 있도록 도움

     

    주요 모듈

    • 서비스 등록 및 디스커버리
      • Eureka: 넷플릭스가 개발한 서비스 디스커버리 서버로, 마이크로서비스 아키텍처에서 각 서비스의 위치를 동적으로 관리
    • 로드 밸런싱
      • Ribbon: 넷플릭스가 개발한 클라이언트 사이드 로드 밸런서로, 서비스 인스턴스 간의 부하를 분산
    • 서킷 브레이커
      • Hystrix: 넷플릭스가 개발한 서킷 브레이커 라이브러리로, 서비스 간의 호출 실패를 감지하고 시스템의 전체적인 안정성 유지
      • Resilience4j: 자바 기반의 경량 서킷 브레이커 라이브러리로, 넷플릭스 Hystrix 의 대안으로 개발

     

    구성 요소의 활용

    • API 게이트웨이
      • Zuul: 넷플릭스가 개발한 API 게이트웨이로, 모든 서비스 요청을 중앙에서 관리
      • Cloud Gateway: 스프링 클라우드에서 제공하는 API 게이트웨이로, 마이크로서비스 아키텍처에서 필수적인 역할
    • 구성 관리
      • Spring Cloud Config: 분산된 환경에서 중앙 집중식 설정 관리를 제공


     


    [241119 TIL]

    AI 검증 비즈니스 프로젝트

    프로젝트 발표 및 마무리

    • 발표 자료 검수
    • 발표 피드백 정리

    발표 피드백

    • 예외 처리, 예외 처리 응답 메세지 등 공통 로직 처리 👍
    • 리뷰 평점 계산 방법을 스케줄러로 배치 작업 👍 - 실무에서도 이렇게 많이 한다고 하셨다!
    • 아쉬운 점으로 작성한 API 관련 문제는 실무에서도 그렇기 때문에 크게 걱정하지 않아도 된다고 하셨다!

    이번 AI 검증 비즈니스 프로젝트를 진행하면서, 아직 많이 미숙했던 Spring 에 조금은 적응한 것 같아서 이것만으로도 큰 성과라고 생각한다! 프로젝트의 도전 과제는 구현하지 못했지만, 필수 기능들은 전부 완료했고 그 과정을 통해 Controller, Service, Entity, Repository, Dto 에 대해서 많이 이해하고 배웠던 것 같다. 강의 자료를 무작정 따라하는 것이 아니라 기능을 하나씩 생각하면서 직접 CRUD 를 전부 구현해보면서 나름 성장했다고 생각한다...!

    또, Github 를 통해 제대로 된 팀 프로젝트를 진행하는 것도 처음이었는데, 팀원분들이 다들 너무 친절하셔서 차근차근 다 알려주시고, 기다려주셔서 Github 에서 이슈, 브랜치를 생성하고 PR 을 날리고 코드리뷰를 진행하는 것들을 배우고 이에 익숙해질 수 있었다!

    Docker + Github Action 으로 자동 배포도 도전해봤는데, 마음만 급해서 제대로 성공하지 못한 것도 아쉽고, 더 많은 기능들을 구현할 수 있었을 것 같고, 도전 과제도 진행해보고 싶다는 아쉬움도 남지만! 그래도 첫 프로젝트치고는 만족스럽다:)

     

     

     

    GitHub - p3j1/gourmate

    Contribute to p3j1/gourmate development by creating an account on GitHub.

    github.com

     


    [241118 TIL] AI 검증 비즈니스 프로젝트

    Soft Delete 적용 - IsDeletedFalse 활용

    Soft Delete 수정

    ✔️ BaseEntity & IsDeletedFalse 활용

    • 수정 전 예시
    @SQLDelete(sql = "UPDATE p_reviews SET is_deleted = true WHERE id = ?")
    @Where(clause = "is_deleted = false")
    reviewRepository.deleteById(reviewId);
    
    • 수정 후
    public void delete(Long userId) {
        this.deletedAt = LocalDateTime.now();
        this.deletedBy = userId;
        this.isDeleted = true;
    }
    review.delete(user.getId());
    
    Optional<Review> findByIdAndIsDeletedFalse(UUID id);
    
    List<Review> findAllByUserIdAndIsDeletedFalse(Long userId);
    
    Page<Review> findAllByStoreIdAndIsDeletedFalse(UUID storeId, Pageable pageable);

     

    • @SQLDelete ➡️ BaseEntity 활용
      • deleteById ➡️ delete 함수 생성 후 Soft Delete 적용
    • @Where ➡️ IsDeletedFalse 활용

    Soft Delete 구현

    1) 어려웠던 점

    • 논리적 삭제 처리: 데이터를 물리적으로 삭제하지 않고 isDeleted 컬럼을 활용해 논리적으로 삭제 상태를 관리하고자 했습니다. 이는 삭제된 데이터 복구와 조회를 가능하게 하지만, 모든 조회 쿼리에 삭제 상태를 고려해야 한다는 어려움이 있었습니다.
    • 테이블 간 연관 관계: 테이블 간 연관 관계가 설정된 상태에서, 삭제된 데이터를 제외하고 연관 데이터를 조회하거나 처리하는 데에 복잡함이 있었습니다.

    2) 해결 방안

    • isDeleted 컬럼 추가
      • 각 테이블에 isDeleted컬럼을 추가하여 논리적 삭제 여부를 관리했습니다.
      • 삭제 시 데이터를 물리적으로 제거하지 않고, 해당 컬럼 값을 true로 설정하여 삭제 상태를 표시하도록 구현했습니다.
    • JPA 메서드 조건 활용
      • JPA의 Spring Data 메서드 쿼리를 활용하여, isDeleted가 false인 데이터만 조회되도록 구현하였습니다.
      • 예: findByIdAndIsDeletedFalse
    • 연관 데이터 처리
      • 연관된 테이블 간 Soft Delete를 고려하여 데이터 무결성을 유지하였습니다.
      • 예: 리뷰 평점 계산 시 삭제 상태인 리뷰 데이터를 제외하고 평점을 계산하도록 구현

    3) 더 효율적으로 하려면

    • 공통 처리 메서드화: Soft delete를 처리하는 로직을 각 엔티티의 서비스에서 반복적으로 작성하기보다, 공통적인 로직을 **AOP(Aspect-Oriented Programming)**나 BaseRepository를 사용 중복을 최소화할 수 있을 것 입니다.

    + Recent posts