코딩공작소

MSA(2) - 스프링 클라우드를 통한 MSA 구축 본문

어플리케이션개발/MSA

MSA(2) - 스프링 클라우드를 통한 MSA 구축

안잡아모찌 2024. 6. 24. 20:17

스프링 클라우드란 ?

프로젝트 설정 및 구성을 단순화하고 가장 흔히 접할 수 있는 패턴의 해결안을 스프링 애플리케이션에 제공하는 것이다. 

시스템이 더 많이 분산될수록 실패할 곳은 더 많아진다.

--> 그리하여 스프링 클라우드는 최소한의 구성으로 마이크로서비스 아키텍처를 빠르게 구축할 수 있는 일련의 기능(서비스 등록, 디스커버리, 회로 차단기, 모니터링 등)을 제공한다.

 

 

 

스프링 클라우드가 제공하는 각 서비스 및 패턴들을 간단하게 먼저 알아보자

 

 

스프링 클라우드 컨피그

애플리케이션의 구성 데이터를 관리하는 서비스이다.
깃, 콘술, 유레카 등과 결합하여 통합관리를 할 수도 있다.

 

 

스프링 클라우드 서비스 디스커버리

서버가 배포된 물리적 위치(IP 및 서버 이름)을 추상화할 수 있다. 클라이언트는 논리적 이름을 사용하여 서버의 비즈니스 로직을 호출한다.

 

 

스프링 클라우드 로드 밸런서와 Resilience4j

로드 밸런서를 통해 클라이언트 부하 분산 기능을 제공하며, Resilience4j를 통해 회로 차단기, 재시도, 벌크헤드 등의 회복성 패턴을 제공하여 보다 유연한 운영환경을 제공한다.

 

 

스프링 클라우드 API 게이트웨이

애플리케이션을 위한 서비스 라우팅 기능을 제공하며, 서비스 요청을 프록싱하고 대상 서비스가 호출되기 전에 모든 호출이 현관을 통과하도록 하는 서비스 게이트웨이다.

서비스 호출의 중앙 집중화로 보안 인가, 인증, 필터링, 라우팅 규칙 등 표준 서비스 정책을 시행할 수 있다.

 

 

스프링 클라우드 스트림

경량 메시지 처리 기능을 마이크로서비스에 쉽게 통합하는 기술이며, 비동기 이벤트를 사용하는 지능형 마이크로서비스를 구축할 수 있다. RabbitMQ와 카프카 같은 메시지 브로커와 마이크로서비스를 빠르게 통합할 수 있게 해준다.

 

 

스프링 클라우드 슬루스

추적 번호를 사용하여 애플리케이션 내 여러 서비스를 통과하는 트랜잭션을 추적할 수 있게 해준다.

 

 

스프링 클라우드 시큐리티

인증 시스템에서 발급된 토큰을 사용하여 서로 통신할 수 있도록 해준다.

 

 

스프링 클라우드의 간단한 예제 소개

원격서비스에 대한 서비스 디스커버리와 클라이언트 부하 분산 기능을 통합하는 방법을 살짝 보여준다.

 

@EnableEurekaClient : 서비스를 유레카 서비스 디스커버리 에이전트에 등록하여 원격 서비스 위치를 검색하도록 지정한다.

RestTemplate : 논리적 서비스 ID를 받으면 내부에서 유레카는 서비스의 물리적 위치를 검색한다.

 

 

 


그렇다면 클라우드 네이티브 마이크로서비스는 어떻게 구축하는 걸까?

클라우드 네이티브 개발을 위한 4가지 원칙이 있다.

  1. 데브옵스는 개발 운영의 약어로 개발자와 IT 운영 간 커뮤니케이션과 협업, 통합에 중점을 준 개발 방법론을 말한다.
  2. 마이크로서비스는 작고, 느슨하게 결합된 분산 서비스다
  3. 지속적 전달은 소프트웨어 개발 관행이다. 전달 프로세스를 자동화하여 운영 환경에서 단기간 전달이 가능하다.
  4. 컨테이너는 가상 머신 이미지에 마이크로서비스를 배포하는 자연스러운 확장이다.

 

 

해당 교재에서는 마이크로서비스 구축을 위한 12가지 모범사례를 활용할 것이며, 이는 12 팩터 애플리케이션이라 한다.

 

코드베이스

여러 배포 환경을 포함할 수 있지만 다른 마이크로서비스와 공유되지 않는다. 즉 각 서비스는 각각의 코드베이스를 갖는다.

 

의존성

메이븐이나 그레이등 같은 빌드도구로 사용되는 의존성을 선언할 수 있다.

 

구성 정보

구성 정보를 배포할 마이크로서비스와 완전히 분리한다. 이렇게 따로 구성하면 실행 중 구성정보를 갱신할 수 있다.

 

백엔드 서비스

대게 데이터베이스나 API RESTful, 다른 서버, 메시징 시스템 등과 네트워크로 통신을 하게  된다.

 

빌드, 릴리스, 실행

배포단계에서 빌드, 릴리스, 실행 단계를 철저히 분리시켜야 하며 독립적으로 마이크로서비스를 구축해야 한다.

 

프로세스

마이크로서비스는 항상 무상태가 되어야 한다. 세션 데이터(상태)를 서버에 저장하지 않고 SQL 또는 NoSQL 데이터베이스를 사용하여 모든 정보를 저장한다.

 

포트 바인딩

특정 포트로 서비스를 게시할 수 있다.

 

동시성

수직확장(하드웨어 증량), 수평 확장(스케일 아웃, 인스턴스 추가)등이 있다.

 

폐기 가능

탄력적으로 확장을 유도하고 코드나 구성 변경 사항을 신속하게 배포하고자 필요에 따라 시작하고 중지할 수 있다.

 

개발 및 운영 환경 일치

유사한 개발 및 운영 환경을 유지하여 발생할 수 있는 모든 시나리오를 통제할 수 있다.

 

로그

이벤트 스트림으로 로그를 관리한다. 로그를 수집하고 중앙 저장소에 기록하는 로그스태시나 플루언티드를 사용할 수 있다.

 

관리 프로세스

스크립트를 통해 수동 작업 없이 관리할 수 있도록 작업들을 관리해야 한다.

 

 

 

예제 프로젝트를 진행해보자 (뼈대만들기)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
<?xml version="1.0" encoding="UTF-8"?>
    <modelVersion>4.0.0</modelVersion>
       <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId> --> 메이븐에 스프링 부트 스타터 킷 의존성을 추가한다.
        <version>2.2.3.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.optimagrowth</groupId>
    <artifactId>licensing-service</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>License Service</name>
    <description>Ostock Licensing Service</description>
 
    <properties>
        <java.version>11</java.version> --> 스프링 5를 사용하기 위해 자바 11을 사용한다.
    </properties>
 
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId> --> 메이븐에 스프링 액추에이터 의존성 추가
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId> --> 메이븐에 스프링 웹 의존성 추가
        </dependency>
 
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
         <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <scope>provided</scope>
        </dependency>
    </dependencies>
 
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId> --> 애플리케이션을 빌드하고 배포하도록 스프링용 메이븐 플러그인 추가
            </plugin>
        </plugins>
    </build>
</project>
cs

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
package com.optimagrowth.license;
 
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
 
@SpringBootApplication
public class LicenseServiceApplication {
 
    public static void main(String[] args) {
        SpringApplication.run(LicenseServiceApplication.class, args);
    }
 
}
cs

@SpringBootApplication : 스프링 부트 프레임워크에 이 클래스를 프로젝트의 부트스트랩 클래스로 지정