[MSA] Service Discovery

Dev_Sanizzang·2023년 5월 28일
0

MSA

목록 보기
1/10

📕 개요

이번 포스팅 부터는 MSA에 대해서 복습해보려고 한다. 기존에 github의 TIL에 정리해 놓은 것이 있었으나, 정리가 제대로 안돼 있어서 다시 참조해서 보기가 힘들었다. 고로 MSA 복습겸 Spring Cloud로 개발하는 마이크로서비스 애플리케이션 강의를 참고하여 정리해 보도록 하겠다.

Spring Cloud Netflix Eureka

우리가 가지고 있는 PC나 노트북이 한 대일 경우에는 여러개의 서비스를 동시에 실행하기 위해서는 port를 나눠서 실행을 해야한다.

http://localhost:8080
http://localhost:8081
http://localhost:8082

만약에 가용할 수 있는 PC가 한 대 이상이라면 같은 port를 사용할 수 있다.

http://my-server1:8080
http://my-server2:8080
http://my-server3:8080

우리가 만들고 있는 모든 마이크로서비스는 모두 Spring Cloud Netflix Eureka라는 곳에 등록을 먼저 할 것이다.

💡 Eureka가 하는 역할을 Service-Discovery라고 한다.
: 외부에서 다른 서비스들이 마이크로 서비스를 검색하기 위해서 사용되는 개념
(일종의 전화부 책이라고 보면된다)

  • Key, Value가 저장되있다고 가정하자.
    -> 어떠한 서버가 어느 위치에 있는지 등록하고 있는 정보가 Service Discovery라고 보면된다.

  • 서비스들의 등록, 검색에 관련된 작업을 해주는 것을 Discovery Service라고 한다.
    -> Netflix의 Eureka라는 서비스를 사용해서 구현

💡 Netflix의 클라우드 기술을 자바스프링 제단에 기부해서 사용할 수 있는 것이 Eureka 제품이다.

  • 각각의 마이크로서비스가 전부다 자신의 위치정보를 Spring Cloud Netflix Eureka 서버에 등록이라는 작업을 먼저한다.

동작 과정

  1. 마이크로서비스를 사용하고 싶은 클라이언트는 제일 먼저 자신이 필요한 요청 정보를 Load Balancer라던가 Gateway(API Gateway)에다가 자신이 필요한 요청정보를 전달
  2. 그 요청 정보가 Service Discovery에 전달이 되서 내가 필요한 정보가 어디에 있냐고 물어봄
  3. Service Discovery는 이 요청에 해당 필요 정보가 저장된 서버로 가라고 시켜주게 되면 사용자 요청 정보가 해당 서버로 호출되고 그거에 대한 결과값을 가져간다.

Service-Discovery가 해주는 역할은 각각의 마이크로서비스가 어디에 누가 저장되어 있으며, 요청정보가 들어왔을 때 요청정보에 따라서 필요한 서비스들의 위치를 알려주는 역할을 한다.

뭘 만들거냐?

: 사용자, 상품, 주문을 가지고 있는 간단한 온라인 쇼핑몰

Eureka Server 설정

Dependencies 추가

Spring Cloud Discovery > Eureka Server 추가

메인 클래스에 @EnableEurekaServer 추가

@SpringBootApplication 이 붙어 있는 클래스에
@EnableEurekaServer 추가

@SpringBootApplication
@EnableEurekaServer
public class DiscoveryServiceApplication {

	public static void main(String[] args) {
		SpringApplication.run(DiscoveryServiceApplication.class, args);
	}

}

yml 파일 설정 (application.properties도 사용 가능)

application.yml

server:
  port: 8761

spring:
  application:
    name: discoveryservice

eureka:
  client:
    register-with-eureka: false
    fetch-registry: false

설명

server:
  port: 8761
  • 서버 포트 번호
  • Eureka 서버가 WebService의 성격으로써 기동이 됨에 있어서 port번호를 어떻게 할지
spring:
  application:
    name: discoveryservice
  • spring boot라는 프레임워크에서 마이크로서비스의 고유한 id 역할
eureka:
  client:
    register-with-eureka: false
    fetch-registry: false
  • Eureka Client 설정

    💡 Server를 기동하고 있는데 Client 설정을 해야되는 이유?
    : Eureka 라이브러리가 포함된 채 스프링 부트가 기동이 되면 기본적으로 Eureka Client 역할로써 어딘가에다 등록하는 작업을 시도하게 된다.
    그중에서 register-with-eureka과 fetch-registry 설정 값은 설정하지 않으면 기본적(default)으로 현재 작업하고 있는 것을 client 역할로 전화번호부에 등록하듯이 자신의 정보를 자신에게 등록하게 되는데 의미가 없는 작업이기 때문에 false라고 지정해야 되는 것이다.
    Eureka 서버는 기동은 하되 자기 자신의 정보를 외부에 있는 다른 마이크로서비스가 Eureka 서버로 부터 어떤 정보를 주고받는 역할을 할 필요가 없기 때문에 자기 자신은 등록하지 않는 것!
    -> 서버로써 기동만 되어 있으면 됨

  • http://localhost:8761 dashboard를 가보면 마이크로서비스로 등록된 instance들을 볼 수 있다.

User Service 생성

설정

Dependencies

  • Eureka Discovery Client
  • Spring Boot DevTools
  • Lombok
  • Spring Web

@EnableDiscoveryClient 추가

@SpringBootApplication
@EnableDiscoveryClient
public class UserServiceApplication {
...

yml 설정

server:
  port: 9001

spring:
  application:
    name: user-service

eureka:
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      defaultZone: http://127.0.0.1:8761/eureka

설명

fetch-registry: true

EUREKA 서버로부터 인스턴스들의 정보를 주기적으로 가져올 것인지를 설정하는 속성. true로 설정 시 갱신된 정보를 받겠다는 설정이다.

service-url:
  defaultZone: http://127.0.0.1:8761/eureka

지금 만들고 있는 user-service는 eureka라는 서버에 등록된 eureka client 역할을 한다.
Eureka 서버의 위치가 어디인지 그 항목을 지정하는 부분이다.

Application 기동 방법 3가지

1. 기본 방법

위의 그림에서 재생 버튼 클릭

실행을 하면 Eureka에 instance가 추가되는 것을 볼 수 있다.

2. 사용자 서비스 2개 생성

UserServiceApplication 뿐만 아니라 새로운 사용자 서비스를 등록하고자 한다.

  1. Edit Configurations에서 UserServiceApplication-2를 생성
  • 서로 같은 포트에서 실행하면 에러가 나기 때문에 port값을 달리해야 한다.
  1. Environment의 VM options -Dserver.port=9002로 포트 번호 지정
  • -D 옵션은 옵션을 추가하겠다는 의미
  • server.port 라는 환경 설정(application.yml)값

서버 자체에 코드가 변경되는 것이 아니기 때문에 매번 실행할 때 마다 포트값을 달리할 수 있다.
한번 작성되어진 코드가 다시 빌드되고 다시 배포되어지는 과정이 아니라 서버를 기동하는 방법에 의해서 서버를 기동할 때 부가적인 파라미터를 전달 함으로써 동적으로 변경될 수 있는 서버 포트를 지정할 수 있다는 특징이 있다.

위와 같은 설정을 하고 2개를 실행해 보면
Eureka Service Directory안에 UserService가 2개가 등록된걸 확인할 수 있다.
외부에서 클라이언트 요청이 UserService에 전달이된다라고 하면 이제 discovery service 안에서 9001번 port로 전달될지 9002번 port로 전달될지 어떠한 인스턴스가 살아있는지 정보값을 Gateway라던가 라우팅 서비스한테 전달해주게 되면 2가지 서비스에 대해서 분산된 서비스가 실행되게 할 수 있다.

3. 빌드 후 커맨드라인 실행

빌드하는 방법?

IntelliJ 옆을 보면 Gradle이라는 메뉴를 볼 수 있다.
해당 메뉴에서 build가 가능하다.

랜덤 port 사용

application.yml

server:
  port: 0
  • 랜덤 포트를 사용하겠다는 의미, 같은 서비스를 사용하더라도 매번 실행할 때마다 랜덤한 포트 번호가 할당된다.

위와 같이 설정을 수정하고 application을 2개를 구동하면

Eureka 서버에 instance가 하나밖에 구동이 안되는 것으로 보인다.

위의 문제를 해결하기 위해 instance id 부여해야한다.

eureka:
  instance:
    instance-id: ${spring.cloud.client.hostname}:${spring.application.instance_id:${random.value}}
  • Spring Cloud의 서비스 디스커버리를 사용하는 애플리케이션에서 사용될 수 있는 인스턴스 ID 생성하는데 사용
  • ${spring.cloud.client.hostname}: 해당 인스턴스가 실행되는 호스트의 이름을 가져오는 Spring 환경 속성, service-discovery를 사용하여 애플리케이션 인스턴스를 식별하는데 사용
  • {spring.application.instance_id:{random.value}}: 인스턴스의 고유 ID 생성
profile
기록을 통해 성장합니다.

0개의 댓글