ChamomileGuides 3.0.4 Help

개요

  • 캐모마일 MSA 목적성:

    • 캐모마일을 활용하여 MSA 지원을 위한 개발 아키텍처 구성

    • 캐모마일 MSA 지원 하기 위한 표준개발 기준정의 및 프로세스 적용

    • DevOps, CI/CD, 컨테이너 등 다양한 요소 중 마이크로서비스 개발에 집중.

    • CircuitBreaker, RateLimiter 등의 기능을 통해 서비스 회복력과 안정성을 향상

    • Spring Cloud 환경 및 Cloud Native 환경내에서 활용방안

  • 도입시 고려사항

    • 1. 비용 및 복잡도

      • 도입 비용: MSA를 도입할 경우 비용이 얼마나 절감할 수 있는가?

      • 복잡도 관리: 마이크로서비스가 시스템 복잡도를 높이는가? 복잡도가 지나치게 높아 생산성을 저해하지 않는가?

    • 2. 생산성 및 이해도

      • 생산성 감소 가능성: 시스템의 복잡도가 증가함에 따라 생산성이 급격히 하락할 수 있음.

      • 팀의 기술 수준: 팀의 기술 역량이 모놀리식 또는 마이크로서비스 아키텍처를 충분히 운영할 수 있는가?

    • 3. 인프라 준비

      • 개발 및 운영 요구사항: 마이크로서비스 도입 시 개발자와 운영에 필요한 인프라가 충분히 준비되어 있는가?

구분

기존 애플리케이션

MSA

애플리케이션 구조

모놀리식 구조

마이크로서비스

결합

크고, 조밀한 결합

느슨한, 서비스 기반

실행환경

물리서버 중심

가상 컨테이너 중심

확장

수직 확장(Scale-Up)

수평 확장(Scale-Out)

인프라 의존성

인프라 의존

인프라 독립, 이식성 보장

개발방법

폭포수(Waterfall)

애자일(Agile, 민첩성)

빌드·배포

수작업, 긴 시간

CI/CD* 자동화, 짧은 시간 & 지속적

조직구조

단절된 개발, 운영, 보안 팀

데브옵스 협업

MSA 성숙도 모델 & 적용 레벨

MSA 아키텍처는 서비스 독립성, 데이터 분리성, SW 아키텍처 수준에 따라 4단계(Early, Inception, Expanding, Mature)로 구분 한다..
처음부터 MSA를 구축하는 경우(Greenfield Project) 또는 기존 모노리스를 MSA로 전환하는 경우(Brownfield Project)는 점진적으로 성숙도를 높여가며 적용할 수 있다.

구분

Early (Lv1)

Inception (Lv2)

Expanding (Lv3)

Mature (Lv4)

애플리케이션

모놀리식(Monolithic)

서비스 지향 통합(Service-Oriented Integrations)

서비스 지향 애플리케이션(Service-Oriented Applications)

API 중심(API-Centric),


도메인 기반 이벤트 및 CQRS 적용

데이터베이스

단일 엔터프라이즈 DB 사용

엔터프라이즈 DB + NoSQL 및 경량 DB 사용

폴리글랏 데이터베이스(Polyglot DB)

이벤트 기반 데이터 관리

인프라

물리적 서버(Physical Machines)

가상화(Virtualization)

클라우드(Cloud)

컨테이너(Container)

모니터링

인프라 모니터링

애플리케이션 및 인프라 모니터링

애플리케이션 성능 모니터링(Application Performance Monitoring)

중앙 로그 관리(Central Log Management)

프로세스

워터폴(Waterfall)

애자일 및 CI(Agile & CI)

자동화된 CI/CD(Automated CI/CD)

데브옵스(DevOps)

팀 구조

통합된 개발 및 운영팀

팀 간 작업 공유 및 내부 소스 공개

서비스별 독립적 팀 구성 (Cross-Functional)

도메인별 팀 구성, 책임 기반 운영

SW 아키텍처

서버사이드 렌더링, 단일 언어(e.g. Spring) 사용

서버사이드 클러스터 구성, MSA 지향 언어(e.g Spring boot)

클라이언트 렌더링 + Auth +Jwt(token)

클라이언트 렌더링 + Service Mesh 적용

Chamomile MSA

구성 내용

  • Chamomile MSA는 Spring Cloud 기반으로 API Gateway, Auth Gateway, Service Mesh를 통해 클라이언트 요청을 라우팅, 인증/인가, 서비스 검색 및 통신을 관리한다. 각 서비스는 Eureka와 Config Server를 통해 동적 설정 및 검색이 가능하며, Resilience4j와 Telemetry를 활용하여 안정성과 모니터링을 강화한다. 캐모마일 어드민 및 주요 백엔드 서비스(캐시, DB 등)와 통합하여 확장성과 장애 복원력을 보장한다.

구분

내용

API Gateway

API 라우팅 및 필터링 기능 구현

Auth Gateway

인증, 인가, JWT 검증 게이트웨이

Service Discovery

서비스 자동 등록 및 검색 기능 구축


API Gateway 가 서비스를 검색하는 매커니즘

Config Server

중앙에서 구성 파일을 관리하는 시스템 설정

Resilience4j

Resilience4j 적용으로 서비스 안정성 강화 (Circuit Breaker, Rate Limiter)


서비스간 장애 전파 차단

Springdoc OpenAPI

Springdoc OpenAPI를 활용하여 API 명세 작성 및 Swagger UI 제공


마이크로서비스별 통합 API 문서화 제공

OpenFeignClient

마이크로 서비스 간 통신을 간소화하여 HTTP 호출을 쉽게 구현

부하테스트

JMeter를 활용한 로컬 및 AWS 환경 내 Gateway 부하테스트 진행

표준 가이드 제공

캐모마일 MSA Architecture에 대한 표준가이드 작성

전자정부 프레임워크 비교 (샘플 및 모듈 제공 유무)

  • 캐모마일에선 위에 설명한 구성 요소에 모든 샘플을 제공 한다.

구분

캐모마일

전자정부 프레임워크

API Gateway

O

O

Auth Gateway

O

JWT, Security 기반 인증인가 추가 구성 필요

Service Discovery

O

O

Config Server

O

O

Resilience4j

Gateway, 서비스내 설정 및 샘플 제공

Gateway 내 별도 추가 구성 필요

Springdoc OpenAPI

Gateway를 통해 모든 서비스 API 호출 가능

추가구성 필요

OpenFeignClient

O

추가구성 필요

ELK

X

O

가이드

O

O

부하테스트

(TPS 200 ~ 300)

X

기술스택

  • JDK: 11

  • ChamomileFrameWork: 3.0.4

  • Spring Boot:

    • spring-boot-starter: 2.7.x

    • spring-boot-starter-test: 2.7.x

    • spring-boot-test: 2.7.x

    • spring-boot-starter-web: 2.7.x

  • Spring Framework: 5.3.x

  • Spring Security:5.7.x

  • Spring Cloud: Spring Cloud Starter Build 2021.0.8

    • resilience4j

  • Swagger (springdoc-openapi): 1.6.9

구성도 (Spring Cloud 기반)

(1) Auth Gateway (인증, JWT 검증), 마이크로 서비스 (인가)

image

(2) Auth Gateway (인증, 인가, JWT 검증)

image

(3) 마이크로 서비스(인증, 인가, JWT 검증) (권장)

image

  • Gateway (API Gateway)

    • chamomile-cloud-gateway

    • 클라이언트 요청을 받아서 라우팅하거나 처리하는 역할.

    • 주요 기능:

      • Circuit Breaker: 장애 전파 방지.

      • Rate Limiter: 요청 빈도 제한.

      • Load Balancer: 부하 분산.

      • Service Router: 라우팅 제어.

      • OpenAPI : 스웨거를 통한 모든 서비스 API 명세 및 테스트

      • Actuator: 모니터링 및 관리.

  • Auth Gateway (인증 게이트웨이)

    • chamomile-cloud-auth-gateway

    • 클라이언트 요청에 대한 인증 인가 및 JWT 토큰 검증이 수행되는 영역.

      • 유효한 요청인지 확인 후 게이트웨이를 통해 서비스로 전달.

  • Service Mesh

    • chamomile-cloud-eureka-server, chamomile-config-server

    • 서비스 간 통신 관리.

      • Discovery Server: 서비스 검색.

      • Open Feign: 간소화된 서비스 간 통신.

      • Config Server : 프로퍼티 관리

  • Chamomile Admin

    • chamomile-cloud-admin

    • 인증 및 어드민 기능 제공.

      • Access Token (Login): 사용자 로그인 처리.

      • Refresh Token: 토큰 갱신.

      • Eureka ClientConfig Client

  • Runtime Platform

    • 실제 비즈니스 로직이 수행되는 서비스 영역.

      • Eureka Client와 **Config Client

  • Backing Services

    • 백엔드의 공통 자원 제공.

      • Cache: 캐싱 시스템.

      • Persistence: 데이터 저장소.

      • Third-Party

  • Telemetry

    • 서비스 상태 모니터링 및 진단 도구.

지원 도구 (Circuit Breaker)

  • 캐모마일 서비스간 통신시 지원

    1. 서비스간 통신 (chamomile-sample-boot-circuit) 샘플제공

    2. MSA 게이트웨이를 통한 통신(chamomile-cloud-gateway) 샘플 제공

  • 서킷브레이커는 누전 차단기가 화재를 막는 것처럼 서비스 간 장애 전파를 막는 역할을 한다.

    • 문제가 발생한 지점을 감지하고 실패하는 요청을 계속 호출하지 않도록 방지 한다.

    • 시스템의 장애 확산을 막고 장애 복구한다

    • 클라이언트 유저는 장애 발생시 불필요한 대기가 필요 없다.

  1. Circuit Breaker:

    • 서비스 간 통신에서 장애 발생 시 회로를 차단하고 장애가 해결되기를 기다림.

    • 장애 전파를 방지하고 서비스 가용성을 높임.

  2. Retry:

    • 장애 발생 시 지정된 시간 간격으로 서비스 호출을 다시 시도.

    • 일시적인 장애로 인한 서비스 중단 방지.

  3. Rate Limiting:

    • 특정 리소스나 서비스 호출에 대한 요청 속도 제한 설정.

    • 과도한 요청으로 인한 서비스 과부하 방지.

  4. Bulkhead:

    • 서비스 호출을 분리된 스레드 풀에서 처리하여 격리 유지.

    • 한 서비스의 장애가 다른 서비스에 영향을 미치지 않도록 처리.

  5. Fallback:

    • 실패한 요청에 대한 대체 데이터 또는 동작을 제공.

    • 사용자에게 오류 대신 안정적인 데이터나 메시지를 제공.

  6. Latency Metrics:

    • 서비스 호출의 지연과 성능을 모니터링하고 지연 지표를 수집.

    • 시스템 성능을 분석하고 최적화 가능.

image
  • Circuit Breaker 상태변경 FLOW

image

Cloud Native (K8S) MSA 지원 방향

  • 표시 부분 -> 캐모마일 지원 영역

    image

  • Ingress Layer

    • 클라이언트 요청이 가장 먼저 도달하는 진입점.

      • Ingress (Nginx, Kong):

        • HTTP(S) 요청을 수신하여 적절한 서비스로 라우팅.

        • Gateway와 유사하지만 Kubernetes 환경에서 네이티브로 사용 가능.

        • 트래픽 관리, 인증, TLS 종료 등의 역할.

        • Circuit Breaker: 서비스 장애 감지 및 차단.

        • Load Balancer: 트래픽 부하 분산.

        • Actuator: 애플리케이션 상태 및 메트릭 제공.

  • Auth Gateway

    • 인증과 토큰 검증을 담당하는 인증 게이트웨이. (필요에따라 제거 가능)

      • Auth Server:

        • 클라이언트의 인증 요청을 처리.

        • JWT 발급 및 유효성 검증.

      • Validation(JWT):

        • 각 요청의 JWT를 확인하여 서비스 호출 여부를 결정.

      • Auto-Scaling:

        • 클라이언트 요청량에 따라 Auth Gateway Pod의 수를 동적으로 조정.

  • Service Mesh

    • Kubernetes 기반 서비스 간의 통신과 네트워크 정책을 관리.

      • Istio:

        • 서비스 디스커버리, 트래픽 라우팅, 장애 복구 지원.

        • 서비스 간 통신 시 암호화(TLS) 및 인증 제공.

      • ConfigMap:

        • 서비스 환경설정을 외부화하여 관리.

      • Secrets:

        • 민감한 데이터(예: API 키, DB 비밀번호)를 안전하게 관리.

  • Runtime Platform

    • 실제 비즈니스 로직을 처리하는 서비스들이 배포된 영역.

      • Service Pods:

        • 개별 마이크로서비스가 Pod로 배포.

        • Pod 간 통신은 Service Mesh를 통해 관리.

      • Authentication / Authorization 서비스:

        • 인증 및 권한 관리를 각각 전담.

        • 요청에 따라 서비스 Pod 수를 Auto-Scaling.

  • Chamomile Admin

    • 캐모마일 어드민 기능제공

    • 관리 및 토큰 발급 관련 기능 제공.

      • Access Token (Login):

        • 로그인 요청 처리 및 JWT 발급.

      • Refresh Token:

        • 만료된 토큰 갱신.

      • Config Client:

        • ConfigMap과 Secrets 데이터를 활용하여 설정 관리.

      • Eureka Client:

        • 서비스 디스커버리를 지원.

  • Backing Services

    • 주요 백엔드 리소스 및 외부 시스템.

      • Cache: Redis와 같은 캐싱 서비스.

      • Persistence: MySQL, PostgreSQL 등 데이터베이스.

      • Third-Party:

        • 외부 API와 연동(예: 결제, 메시징 등).

  • Telemetry

    • 모니터링 및 장애 진단.

      • Monitoring: Prometheus, Grafana 등을 통해 서비스 상태 확인.

      • Diagnostics: 장애 원인을 파악하고 문제를 해결.

Spring Cloud와 Kubernetes의 기술 요소 매핑

MSA 관심사

Spring Cloud

Kubernetes

Configuration Management

Config Server

Kubernetes ConfigMap & Secrets

Service Discovery

Netflix Eureka

Kubernetes Service & Ingress Resources

Load Balancing

Spring Cloud LoadBalancer

Kubernetes Service

API Gateway

Spring Cloud Gateway

Kubernetes Service & Ingress Resources

Service Security

Spring Cloud Security

-

Resilience & Fault Tolerance

Spring Cloud Circuit Breaker

Kubernetes Health Check & resource isolation

Auto Scaling & Self Healing

-

Kubernetes Health Check, Self Healing, Autoscaling

사용법

1. 샘플 프로젝트 생성

image
  • archetype 생성

    • chamomile-cloud-admin-project

      • 캐모마일 MSA 샘플 어드민

    • chamomile-cloud-gateway

      • 게이트웨이

    • chamomile-cloud-auth-gateway (필수X)

      • 인증,인가,JWT 검증 게이트웨이

    • chamomile-cloud-eureka-server

      • Discovery 서버

    • chamomile-cloud-config-server (필수X)

      • Config 서버

    • chamomile-cloud-timetable (필수X)

      • 마이크로 서비스

  • 구동 순서

    • 구동순서는 필수는 아니지만 기본적인 순서는 아래와 같다.

    • 6개 서버가 정상 구동 되는지 확인 후 게이트웨이에서 등록 된 서비스들간 API 호출이 정상적인지 확인 할 수 있다.


      http://localhost:8000/webjars/swagger-ui/index.html 접속한다.

    • 오른쪽 상단 Select a definition 에서 해당 프로젝트(ADMIN) 선택후


      /health-check -> Execute 후 아래와 같이 SUCCESS 응답시 전반적인 연결 성공이다.

    • image
  • 각 프로젝트에 대한 내용은 위에 아키텍처 구성 내용을 참조한다.

    • 설명 되는 모든 내용은 샘플 프로젝트 내 제공 된다.

2. 주요 구성 내용

1. chamomile-cloud-gateway

  • Spring Cloud Gateway는 마이크로서비스 아키텍처에서 API 게이트웨이로 사용 되며 로드 벨런서, 디스커버리 연동, 서킷 브레이커 기능을 제공한다.

  1. pom.xml (주요 의존성) -> 전체 소스는 프로젝트내 pom.xml 확인

<!-- Spring Boot and Cloud --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-loadbalancer</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency> <!-- SpringDoc OpenAPI --> <dependency> <groupId>org.springdoc</groupId> <artifactId>springdoc-openapi-webflux-ui</artifactId> <version>1.6.15</version> </dependency> <dependency> <groupId>org.springdoc</groupId> <artifactId>springdoc-openapi-webflux-core</artifactId> <version>1.6.15</version> </dependency> <!-- Resilience4j --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-circuitbreaker-reactor-resilience4j</artifactId> </dependency> <dependency> <groupId>io.github.resilience4j</groupId> <artifactId>resilience4j-spring-boot2</artifactId> </dependency> <!-- Redis Reactive --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis-reactive</artifactId> </dependency> <!-- Actuator --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
  1. application.yml-> 전체 소스는 프로젝트내 application.yml 확인

server: port: 8000 max-http-header-size: 200KB # HTTP 헤더의 최대 크기 설정 (기본값보다 증가) spring: application: name: chamomile-cloud-gateway config: import: "optional:configserver:" # 외부 Config Server에서 설정 가져오기 (옵션) cloud: config: uri: http://localhost:8888 # Config Server URL fail-fast: false # Config Server 연결 실패 시 애플리케이션 실행 중단 여부 enabled: false # Config Server 사용 비활성화 (필요시 활성화 gateway: httpclient: pool: type: fixed # 고정 크기의 커넥션 풀 사용 max-connections: 2000 # 최대 커넥션 수 설정 max-idle-time: 30s # 유휴 커넥션 유지 시간 globalcors: cors-configurations: '[/**]': # 모든 경로에 대해 CORS 설정 allowed-origins: "*" # 모든 도메인 허용 allowed-methods: "*" # 모든 HTTP 메서드 허용 allowed-headers: "*" # 모든 헤더 허용 allow-credentials: false # 인증 정보 전달 허용하지 않음 routes: # Gateway 라우팅 설정 #################### chamomile-cloud-auth-gateway 사용시 아래 주석 해제 ##################### # - id: chamomile-cloud-auth-gateway # 라우트 ID# uri: lb://CHAMOMILE-CLOUD-AUTH-GATEWAY # 로드 밸런싱을 통한 URI 지정 # predicates: # - Path=/auth/** # /auth/로 시작하는 경로 매칭 # filters: # - RewritePath=/auth/(?<segment>.*), /$\{segment} # /auth/ 제거 후 전달 ############################################################################################# - id: chamomile-cloud-admin-project uri: lb://CHAMOMILE-CLOUD-ADMIN-PROJECT # 로드 밸런싱된 Admin 프로젝트 서비스 predicates: - Path=/chmm/** # /chmm/로 시작하는 경로 매칭 filters: - RewritePath=/chmm/(?<segment>.*), /$\{segment} # /chmm/ 제거 - name: RequestRateLimiter args: key-resolver: "#{@ipKeyResolver}" # 요청 제한 Key Resolver redis-rate-limiter.replenishRate: 1500 # 초당 새로 고침 속도 redis-rate-limiter.burstCapacity: 3000 # 최대 버스트 요청 수 - name: CircuitBreaker args: name: exampleClientCircuitBreaker # Circuit Breaker 이름 fallbackUri: forward:/fallback/authFailure # 실패 시 Fallback URI 설정 # - name: GatewayIdFilter # 커스텀 필터 예시 (주석 처리됨) - id: chamomile-cloud-timetable uri: lb://CHAMOMILE-CLOUD-TIMETABLE # 로드 밸런싱된 Timetable 서비스 predicates: - Path=/timetable/** # /timetable/로 시작하는 경로 매칭 filters: - RewritePath=/timetable/(?<segment>.*), /$\{segment} # /timetable/ 제거 management: endpoints: web: exposure: include: refresh, health, beans, httptrace, circuitbreakers # 노출할 관리 엔드포인트 endpoint: health: show-details: always # Health 엔드포인트의 세부 정보 항상 표시 eureka: instance: instance-id:${spring.cloud.client.hostname}:${spring.application.instance_id:${random.value}} # Eureka에 등록될 인스턴스 ID client: register-with-eureka: true # Eureka에 클라이언트 등록 fetch-registry: true # Eureka 레지스트리 정보 가져오기 service-url: defaultZone: http://localhost:8761/eureka # Eureka 서버 URL springdoc: enable-native-support: true # Native OpenAPI 문서 지원 활성화 api-docs: enabled: true # API 문서 활성화 swagger-ui: enabled: true # Swagger UI 활성화 path: /swagger-ui.html # Swagger UI 경로 config-url: /v3/api-docs/swagger-config # Swagger 구성 URL urls: # OpenAPI 문서 경로 설정 - url: /chmm/api-docs name: ADMIN - url: /timetable/api-docs name: TIMETABLE resilience4j: circuitbreaker: instances: exampleClientCircuitBreaker: failureRateThreshold: 90 # 실패 비율이 90% 이상이면 Circuit이 열림 waitDurationInOpenState: 10000 # Circuit이 열린 후 10초 동안 대기 slidingWindowSize: 1000 # 최근 1000개의 호출 기준으로 실패 비율 계산 slowCallRateThreshold: 80 # 느린 호출 비율이 80%를 넘으면 Circuit이 열림 slowCallDurationThreshold: 30000 # 30초 이상 소요되면 느린 호출로 간주 permittedNumberOfCallsInHalfOpenState: 5 # 반 열림 상태에서 최대 5번 호출 허용 maxWaitDurationInHalfOpenState: 30000 # 반 열림 상태에서 최대 30초 대기 slidingWindowType: COUNT_BASED # 호출 횟수 기준으로 실패 비율 계산 minimumNumberOfCalls: 1000 # 최소 1000번 호출 후 실패 비율 계산 registerHealthIndicator: true # Health Indicator 등록 timelimiter: configs: default: timeoutDuration: 60s # 호출 타임아웃 60초 설정 cancelRunningFuture: false # 타임아웃 발생 시 실행 중 작업 취소하지 않음 logging: level: org.springframework.cloud.gateway: INFO # Gateway 로깅 레벨 org.springframework.cloud.gateway.filter.rateLimit.RedisRateLimiter: INFO# RateLimiter 로깅 레벨
  • Server 설정

    • server.port: 애플리케이션이 사용하는 포트를 지정한다. (예: 8000)

    • server.max-http-header-size: HTTP 요청 헤더의 최대 크기를 설정한다. (예: 200KB)

  • Spring 애플리케이션 설정

    • spring.application.name: 서비스의 이름을 지정한다. (예: chamomile-cloud-gateway)

    • spring.config.import: 외부 설정(Config Server)에서 추가 설정을 가져오도록 한다. optional:로 설정 시 서버 연결 실패에도 애플리케이션이 실행된다.

    • spring.cloud.config.uri: Config Server의 URL을 설정한다. (예: http://localhost:8888)

    • spring.cloud.config.fail-fast: Config Server 연결 실패 시 애플리케이션 실행 중단 여부를 설정한다. (기본값: false)

    • spring.cloud.config.enabled: Config Server 사용 여부를 설정한다. (예: false)

  • Spring Cloud Gateway 설정

    • HTTP 클라이언트 풀 설정:

      • spring.cloud.gateway.httpclient.pool.type: 고정 크기 풀을 사용하도록 한다. (값: fixed)

      • spring.cloud.gateway.httpclient.pool.max-connections: 최대 연결 수를 설정한다. (예: 2000)

      • spring.cloud.gateway.httpclient.pool.max-idle-time: 유휴 연결 유지 시간을 설정한다. (예: 30s)

    • 글로벌 CORS 설정:

      • 모든 경로에 대해 모든 도메인(*), 메서드(*), 헤더(* )를 허용하며 인증 정보는 포함하지 않도록 한다.

    • 라우팅 설정:

      • Authentication Gateway

        • id: chamomile-cloud-auth-gateway

        • uri: lb://CHAMOMILE-CLOUD-AUTH-GATEWAY

        • predicates: /auth/**로 시작하는 경로에 매칭되도록 한다.

        • filters: /auth/를 제거한 후 내부 서비스에 요청을 전달하도록 한다.

      • Admin Project

        • id: chamomile-cloud-admin-project

        • uri: lb://CHAMOMILE-CLOUD-ADMIN-PROJECT

        • predicates: /chmm/**로 시작하는 경로에 매칭되도록 한다.

        • filters:

          • RewritePath: /chmm/를 제거한 후 내부 서비스로 전달하도록 한다.

          • RequestRateLimiter:

            • key-resolver: 요청 제한의 기준 키를 설정한다. (예: 클라이언트의 IP 주소)

            • redis-rate-limiter.replenishRate: 초당 허용되는 요청 수를 설정한다. (예: 1500)

            • redis-rate-limiter.burstCapacity: 최대 허용 버스트 요청 수를 설정한다. (예: 3000)

          • CircuitBreaker:

            • name: CircuitBreaker 이름을 설정한다. (예: exampleClientCircuitBreaker)

            • fallbackUri: 장애 발생 시 요청을 전달할 경로를 설정한다. (예: /fallback/authFailure)

      • Timetable Service

        • id: chamomile-cloud-timetable

        • uri: lb://CHAMOMILE-CLOUD-TIMETABLE

        • predicates: /timetable/**로 시작하는 경로에 매칭되도록 한다.

        • filters: /timetable/를 제거한 후 내부 서비스로 요청을 전달하도록 한다.

  • 관리 엔드포인트 설정

    • management.endpoints.web.exposure.include: 노출할 관리 엔드포인트를 지정한다. (예: refresh, health, beans, httptrace, circuitbreakers)

    • management.endpoint.health.show-details: Health 엔드포인트에서 세부 정보를 항상 표시하도록 한다.

  • Eureka 설정

    • eureka.instance.instance-id: Eureka 서버에 등록되는 서비스의 ID를 설정한다.

    • eureka.client.register-with-eureka: 클라이언트가 Eureka 서버에 등록되도록 설정한다.

    • eureka.client.fetch-registry: Eureka 서버에서 다른 서비스 정보를 가져오도록 설정한다.

    • eureka.client.service-url.defaultZone: Eureka 서버의 URL을 설정한다. (예: http://localhost:8761/eureka)

  • SpringDoc 설정

    • Swagger UI를 활성화하여 API 문서를 제공하도록 한다.

    • springdoc.swagger-ui.urls: 서비스별 OpenAPI 문서 경로를 지정한다.

    • 서비스별 API 명세 및 테스트 진행이 가능하다.

    • http://localhost:8000/webjars/swagger-ui/index.html (게이트웨이 ip)

    • image
  • Resilience4j 설정

    • CircuitBreaker:

      • failureRateThreshold: 실패율 임계값. (90%)

      • slidingWindowSize: 최근 1000개 호출 기준으로 실패 비율 계산

      • slowCallRateThreshold: 느린 호출 비율 80% 초과 시 Circuit 열림

      • fallbackUri: 장애 발생 시 요청 전달 경로. (/fallback/authFailure)

        • 장애 발생시 FallbackController.java 내에서 별도의 비지니스 로직이나 exception 처리 가능

      • FallbackController.java

@RestController @RequestMapping("/fallback") public class FallbackController { @GetMapping("/authFailure") public ResponseEntity<String> authFailure(ServerWebExchange exchange) { // CIRCUITBREAKER_EXECUTION_EXCEPTION_ATTR 속성에서 발생한 예외를 가져옴 Throwable exception = exchange.getAttribute(ServerWebExchangeUtils.CIRCUITBREAKER_EXECUTION_EXCEPTION_ATTR); // 예외가 없는 경우 기본 메시지 반환 if (exception == null) { return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) .body("Fallback triggered, but no specific exception was found."); } // 요청 경로를 가져옴 String requestPath = exchange.getRequest().getPath().toString(); String responseMessage; if (exception instanceof CallNotPermittedException) { responseMessage = "CircuitBreaker Open error on path " + requestPath + ": " + exception.getMessage(); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(responseMessage); } // 기타 예외 처리 else { responseMessage = "An unknown error occurred on path " + requestPath + "."; return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(responseMessage); } } }
    • TimeLimiter:

      • timeoutDuration: 요청 타임아웃을 지정한다. (예: 60s)

    • **RequestRateLimiter ** :

      • Redis 6.x 이상 설치 권장 필요

      • Redis를 백엔드로 사용하여 요청 속도를 제한하도록 한다.

      • key-resolver: 요청 제한에 사용할 키를 정의한다. (예: 클라이언트 IP)

        • RateLimiterConfig.java 내 IP Key Resolver Bean 설정

      • redis-rate-limiter.replenishRate: 초당 허용되는 요청 수를 설정한다. (예: 1500)

      • redis-rate-limiter.burstCapacity: 최대 허용되는 버스트 요청 수를 설정한다. (예: 3000)

      • 동작 원리:

        • 클라이언트 요청마다 키를 생성하여 Redis에서 요청 카운트를 추적한다.

        • 설정된 속도와 용량을 초과한 요청은 차단되도록 한다.

  • 로깅 설정

    • logging.level: 로깅 레벨을 설정한다.

      • Gateway와 RateLimiter 관련 로그 수준을 INFO로 설정하여 주요 이벤트만 기록되도록 한다.

chamomile-cloud-auth-gateway

  • 클라이언트 요청에 대한 인증 인가 및 JWT 토큰 검증이 수행되는 영역 이다. 유효한 요청인지 확인 후 게이트웨이를 통해 서비스로 전달하게 된다.

  • 인증 인가 및 JWT 토큰 검증을 서비스에서 진행하고 싶다면 생략해도 된다.

  1. pom.xml (주요 의존성) -> 전체 소스는 프로젝트내 pom.xml 확인

<!-- Spring Boot and Cloud --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-loadbalancer</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <!-- Resilience4j --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-circuitbreaker-reactor-resilience4j</artifactId> </dependency> <!-- Additional Libraries --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <!-- chamomile --> <dependency> <groupId>net.lotte.chamomile.module</groupId> <artifactId>chamomile-database</artifactId> </dependency> <dependency> <groupId>net.lotte.chamomile.module</groupId> <artifactId>chamomile-cache-redis</artifactId> </dependency> <dependency> <groupId>net.lotte.chamomile.module</groupId> <artifactId>chamomile-security-jwt</artifactId> <exclusions> <exclusion> <groupId>net.lotte.chamomile.module</groupId> <artifactId>chamomile-web</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>net.lotte.chamomile.boot</groupId> <artifactId>chamomile-boot-autoconfigure</artifactId> </dependency> <dependency> <groupId>net.lotte.chamomile</groupId> <artifactId>chamomile-core</artifactId> </dependency>
  1. application.yml-> 전체 소스는 프로젝트내 application.yml 확인**

server: port: 8900 max-http-header-size: 200KB # Spring 애플리케이션 설정 spring: main: allow-bean-definition-overriding: true # 빈 정의를 재정의할 수 있는지 여부 application: name: chamomile-cloud-auth-gateway # 애플리케이션 이름 cloud: gateway: httpclient: pool: type: fixed # 고정 크기의 커넥션 풀 사용 max-connections: 2000 # 최대 커넥션 수 설정 max-idle-time: 30s # 유휴 커넥션 유지 시간 default-filters: - RemoveResponseHeader=Vary # 응답 헤더에서 'Vary' 제거 routes: - id: chamomile-cloud-gateway # 라우트 ID uri: lb://CHAMOMILE-CLOUD-GATEWAY # 로드 밸런싱된 URI predicates: - Path=/** # 모든 경로와 매칭 filters: - RewritePath=/(?<segment>.*), /${segment} # 경로를 리라이트 - AddRequestHeader=X-Gateway-ID, auth-gateway # 요청 헤더에 추가 management: endpoints: web: exposure: include: refresh, health, beans, httptrace, circuitbreakers endpoint: health: show-details: always # Health 엔드포인트의 세부 정보 항상 표시 rate-limiter: enabled: true # Rate Limiter의 health 체크 활성화 여부 eureka: instance: instance-id: springtestgateway:${spring.application.instance_id:${random.value}} client: register-with-eureka: true fetch-registry: true service-url: defaultZone: http://localhost:8761/eureka chmm: cache: instance: redis # 캐시 인스턴스 설정 (none/redis/hazelcast) auth-enable: true # 인증.인가 캐시 활성화 여부 resilience4j: timelimiter: configs: default: timeoutDuration: 60s # 호출 타임아웃 60초 설정 cancelRunningFuture: false # 타임아웃 발생 시 실행 중 작업 취소하지 않음
  • Spring Cloud Gateway 설정

    • default-filters: 모든 요청에 기본적으로 적용할 필터를 설정한다.

      • RemoveResponseHeader=Vary: 응답 헤더에서 Vary를 제거한다.

    • routes: 경로와 필터를 정의하여 요청을 처리하는 방식을 설정한다.

      • 라우트 ID: chamomile-cloud-gateway

        • uri: lb://CHAMOMILE-CLOUD-GATEWAY로 로드 밸런싱된 서비스에 요청을 전달한다.

        • predicates: 모든 경로(/** )에 대해 요청을 매칭한다.

        • filters:

          • RewritePath=/(?<segment>.*), /${segment}: 경로를 리라이트하여 전달한다.

          • AddRequestHeader=X-Gateway-ID, auth-gateway: 요청 헤더에 X-Gateway-ID: auth-gateway를 추가한다.

  • Eureka 설정

    • eureka.instance.instance-id: Eureka 서버에 등록되는 서비스의 고유 ID를 설정한다. (예: springtestgateway:<랜덤값>)

    • eureka.client.register-with-eureka: 클라이언트가 Eureka 서버에 등록되도록 설정한다.

    • eureka.client.fetch-registry: Eureka 레지스트리에서 다른 서비스 정보를 가져오도록 설정한다.

    • eureka.client.service-url.defaultZone: Eureka 서버의 URL을 설정한다. (예: http://localhost:8761/eureka)

  • 캐시 설정

    • spring.cache.instance: 캐시 인스턴스를 설정한다. (예: redis, hazelcast, none)

    • spring.cache.auth-enable: 인증, 인가를 캐시할지 여부를 설정한다. (예: true)

chamomile-cloud-eureka-server

  • Spring Cloud Eureka는 마이크로서비스 아키텍처(MSA)에서 중요한 역할을 하는 서비스 등록 및 디스커버리 서버이다. MSA 환경에서는 여러 개의 독립적인 서비스가 서로 통신하며 협력해야 하는데, 이 과정에서 서비스 간의 위치를 동적으로 관리하고 발견하는 것이 중요하다. Spring Cloud Eureka는 이러한 문제를 해결하는 데 도움을 준다.

  • http://localhost:8761/ 접속후 연결된 어플리게이션을 확인 할 수 있다. ![[msa11.png]]

서버설정

  1. pom.xml

<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency>
  1. application.yml

server: port: 8761 spring: application: name: chamomile-cloud-eureka-server # Eureka 설정 eureka: instance: metadata-map: gateway-id: auth-gateway # Eureka 인스턴스의 메타데이터 설정, 'gateway-id'를 'auth-gateway'로 설정 client: register-with-eureka: true # 클라이언트가 Eureka 서버에 등록되도록 설정 fetch-registry: true # Eureka 서버에서 다른 서비스 레지스트리를 가져옴

**클라이언트 설정

  1. application.yml

eureka: instance: instance-id: ${spring.cloud.client.hostname}:${spring.application.instance_id:${random.value}} #동적 서비스 등록을 위한 인스턴스 설정 client: register-with-eureka: true #자기 자신을 유레카에 등록하는지 여부 fetch-registry: true #유레카를 사용해 다른 엔드포인트에 대한 접근을 탐색할지 여부 service-url: defaultZone: http://localhost:8761/eureka #바라볼 유레카 서버에 대한 정보

선택 옵션 (서버 설정)

eureka: instance: hostname: localhost # 인스턴스의 호스트 이름 client: register-with-eureka: false # Eureka 서버에 자신을 등록할지 여부 fetch-registry: false # Eureka 서버에서 레지스트리를 가져올지 여부 service-url: defaultZone: http://localhost:8761/eureka/ # Eureka 서버의 기본 URL server: enable-self-preservation: true # 자기 보호 모드를 활성화할지 여부 eviction-interval-timer-in-ms: 60000 # 인스턴스 제거 주기 (밀리초)

선택 옵션(클라이언트 설정)

spring: application: name: my-service # 애플리케이션 이름 cloud: inetutils: ignored-interfaces: eth0, eth1 # 무시할 네트워크 인터페이스 eureka: instance: hostname: my-hostname # 인스턴스의 호스트 이름 non-secure-port: 80 # 비보안 포트 secure-port: 443 # 보안 포트 secure-port-enabled: true # 보안 포트를 활성화할지 여부 metadata-map: instanceId: ${spring.application.name}:${spring.application.instance_id:${random.value}} # 메타데이터 맵 client: enabled: true # 클라이언트를 활성화할지 여부 healthcheck: enabled: true # 헬스체크를 활성화할지 여부 service-url: defaultZone: http://localhost:8761/eureka/ # Eureka 서버의 기본 URL registry-fetch-interval-seconds: 30 # 레지스트리 가져오기 주기 (초) initial-instance-info-replication-interval-seconds: 40 # 초기 인스턴스 정보 복제 주기 (초) eureka-service-url-poll-interval-seconds: 5 # Eureka 서비스 URL 폴링 주기 (초) heartbeat-executor-thread-pool-size: 5 # 하트비트 실행자 스레드 풀 크기 cache-refresh-executor-thread-pool-size: 5 # 캐시 새로고침 실행자 스레드 풀 크기 eureka-server-connect-timeout-seconds: 5 # Eureka 서버 연결 타임아웃 (초) eureka-server-read-timeout-seconds: 8 # Eureka 서버 읽기 타임아웃 (초) eureka-connection-idle-timeout-seconds: 30 # Eureka 연결 유휴 타임아웃 (초) eureka-server-total-connections: 200 # Eureka 서버 총 연결 수 eureka-server-total-connections-per-host: 50 # 호스트당 Eureka 서버 총 연결 수 backup-registry-impl: com.example.MyBackupRegistry # 백업 레지스트리 구현 클래스 use-dns-for-fetching-service-urls: false # 서비스 URL을 가져오기 위해 DNS를 사용할지 여부 fetch-registry-for-remote-regions: false # 원격 지역의 레지스트리를 가져올지 여부 availability-zones: default: defaultZone # 가용 영역 region: us-east-1 # 지역

chamomile-cloud-config-server

  • Spring Cloud Config는 마이크로서비스 아키텍처(MSA) 환경에서 매우 중요한 역할을 한다. MSA 환경에서는 여러 개의 독립적인 서비스가 협력하여 하나의 시스템을 구성하게 되는데, 이때 각 서비스의 설정(configuration)을 효율적으로 관리하는 것이 중요하다.

서버 설정

  1. application.yml

# Server 설정 server: port: 8888 # Config Server가 실행될 포트 # Jasypt 설정 jasypt: encryptor: password: # Spring 애플리케이션 설정 spring: application: name: chamomile-cloud-config-server # 애플리케이션 이름 (Config Server로 사용) profiles: active: native # Active Profile로 native를 활성화 (로컬 파일에서 설정을 읽음) cloud: config: server: native: search-locations: file:///C:/config-repo/ # 로컬 파일에서 설정을 읽어올 경로 # Git 기반 Config Server 예제 (주석 처리됨) # Git 리포지토리를 사용하는 Config Server 설정 예제입니다. # spring: # cloud: # config: # server: # git: # uri: http://s-gitlab.lotteinnovate.com/ # Git 리포지토리 URL# # username: # Git 리포지토리에 접근할 사용자 이름 # password: ENC(Biq7rC6u4Yu6ItfyM+t33q+oKOH+VeYA) # 암호화된 Git 비밀번호

클라이언트 설정

  1. pom.xml

<!-- 스프링 클라우드 사용을 위한 의존성 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency>
  1. application.yml

spring: config: import: "optional:configserver:" # 외부 Config Server에서 설정 가져오기 (옵션) cloud: config: name: chamomile-cloud-gateway uri: http://localhost:8888 # Config Server URL fail-fast: false # Config Server 연결 실패 시 애플리케이션 실행 중단 여부 enabled: false # Config Server 사용 비활성화 (필요시 활성화

chamomile-cloud-admin-project

  • MSA내 캐모마일 어드민 구성을 위한 샘플 프로젝트이다.

    • 주요 구성 내용은 chamomile-admin-project 와 같다.

chamomile-cloud-timetable

  • MSA내 비즈니스 서비스 구성을 위한 샘플 프로젝트이다.

    • OpenFeign 등 샘플 소스를 구성하고 있으며 프로젝트 상황에 맞게 수정하거나 별도 프로젝트를 구성해서 사용 하면 된다.

Last modified: 10 1월 2025