Eureka 서버 ( 서비스 검색 및 등록 라이브러리 )

Sprout·2023년 10월 16일
0

MSA

목록 보기
6/8

Eureka?
Spring Cloud Discovery라는 개념을 활용하기 위한 라이브러리로 사용
Health Check, 로드 밸런싱을 하기 위해서 사용하는 서버
MSA에서 서비스의 등록, 발견 및 관리를 위한 Discovery Service

MS를 Eureka에 미리 등록하여 사용 → 게이트웨이는 Eureka에 문의만 하면 된다.




주요 특징

  1. 서비스 등록

    • 개별 MS가 시작될 때, Eureka 서버에 자신의 위치 정보 등록

    → 다른 서비스나 클라이언트가 해당 서비스를 찾을 수 있음.

  2. 서비스 감지

    • Eureka 서버 라이브러리를 사용하여 서비스를 찾고 해당 서비스의 메타데이터를 가져옵니다.

    → 동적으로 서비스의 위치를 파악할 수 있습니다.

  3. 서비스 상태 감지 (Helath Check 모니터링)

    • Eureka는 주기적으로 등록된 서비스의 상태를 확인

    → 장애가 발생한 서비스를 감지하고 다른 서비스로 요청을 라우팅

  4. 동적 서비스 변경

    • 새로운 서비스 인스턴스가 추가되거나 기존의 인스턴스가 제거되어도 Eureka는 이를 감지하고 서비스 목록 업데이트

  5. 클라이언트 사이드 로드 밸런싱

    • Eureka 서버는 여러 인스턴스 중 하나를 선택하여 서비스로 요청

    → 부하 분산

작동 원리

  1. Eureka Server(Discovery Server) 구동 ↔ Discovery Client (= MS)

    • 프로젝트에서 사용할 Eureka 서버를 실행 ← Service Discovery 중심 역할을 한다.

  2. 서비스 등록

    • MS가 시작될 때, 해당 서비스는 Eureka 서버에 자신의 서버 등록

    (위 정보에는 서비스 이름, IP주소, 포트 번호 포함)

  3. 서비스 감지

    • 다른 MS나 클라이언트가 특정 서비스를 호출하려면

    • Eureka 클라이언트 라이브러리를 사용하여 Eureka서버에서 해당 서비스의 인스턴스를 찾습니다.

  4. 서비스 사용

    • 클라이언트는 Eureka로부터 받은 서비스 인스턴스 목록 중 하나를 선택하여 요청을 보냄.

    → 클라이언트 사이드 로드 밸런싱을 통해 부하 분산

  5. 서비스 상태 감시 : 30초에 3번씩 요청 보냄

    • Eureka 서버는 주기적으로 등록된 서비스 상태 확인 → 응답하지 않으면 다른 인스턴스로 대체

  6. 동적 서비스 변경

    • 새로운 서비스 인스턴스가 추가되거나 기존 인스턴스 삭제시, Eureka가 이를 감지하고 서비스 목록 업데이트


실습

Eureka Server 생성

  1. Eureka Server 의존성 등록 후 프로젝트 생성



  1. yml에서 유레카 서버 설정 등록

    ```yaml
    server:
      port: 8761  # 포트번호 겹치지 않는 선에서 맘대로
    spring:
      application:
        name: discovery-server
    eureka:
      client:
        register-with-eureka: false # 해당 서버를 유레카에 등록할 것인가? (클라이언트한테는 true를 줘야 함)
        fetch-registry: false # 해당 서버가 다른 서비스의 endpoints에 대한 정보를 다운로드하기 위해 Eureka 서버에 연결을 시도할지 여부를 제어
    # ( = 유레카에 등록되는 서비스들의 정보를 갱신하기 위한 용도 )
    ```



  2. main에 @EnableEurekaServer 어노테이션을 추가해야 유레카 서버가 감시 시작

    @EnableEurekaServer	// 유레카 대시보드에서 감시 시작
    @SpringBootApplication
    public class DiscoveryServerApplication {
    
    	public static void main(String[] args) {
    		SpringApplication.run(DiscoveryServerApplication.class, args);
    	}
    
    }



  3. 등록했던 포트 번호로 유레카 서버 동작 확인 가능

    - 유레카 서버를 한 번 등록하면
        이후 클라이언트를 추가할 때는 유레카 서버를 건들일 필요가 없다
        → 유지보수에 용이



Discovery Client (MS) 등록하기

  1. Client로 등록할 MS는 Eureka Discovery Client 의존성 부여 해야 함


  2. yml에서 클라이언트 설정 등르고

    server:
      port: 8003
    spring:
      application:
        name: discovery-client
    eureka:
      client:
        register-with-eureka: true  # 유레카 서버에 등록
        fetch-registry: true  # 유레카 서버에서 서버 상태 지속적 감시 허락
        service-url:
          defaultZone: http://192.168.67.1:8761/eureka # 유레카 서버의 주소

  3. main에 @EnableDiscoveryClient 어노테이션을 추가하여 클라이언트로 등록

    @EnableDiscoveryClient
    @SpringBootApplication
    public class DiscoveryClientApplication {
    
    	public static void main(String[] args) {
    		SpringApplication.run(DiscoveryClientApplication.class, args);
    	}
    
    }

  4. Eureka 서버에 Client가 등록된 모습을 확인할 수 있음



동일 프로젝트로 서버 2개 이상 실행시키기

  1. Edit Configurations로 이동

  1. 서버 복사해서 사용

3. 실행하면 포트 충돌나는 것을 볼 수 있음.
  ➡️ APPLICATION FAILED TO START

  	Description: Web server failed to start. Port 8003 was already in use.

  	Action: Identify and stop the process that's listening on port 8003 or configure this application to listen on another port.

→ 포트 충돌 해결 방안

  1. 서버 실행 단계에서 포트 값을 새롭게 지정한다. (VM options 설정)
    1-1) Edit Configutration에 다시 들어가서 VM options을 추가한다.
    Edit Configutration에 다시 들어가서 VM options을 추가한다.

    1-2) 사용할 포트 번호를 지정한다. (-D = detach모드, 콘솔창을 수믹고 어플리케이션을 가동)

    1-3) 2개의 클라이언트가 등록된 것을 볼 수 있다.

  2. 각 서버 실행 시마다 랜덤포트를 실행하도록 만든다.

    → 점유 중이지 않은 포트번호를 랜덤하게 배정

    = 니가 안 쓰는 번호 알아서 찾아 들어가라

    server.port=0 ← 0번 포트는 존재하지 않음

    = 랜덤포트 배정

    명목 상 port번호를 0으로 배정했기 때문에 인스턴스가 1개만 켜진 것으로 나옴

    server:
      port: 0
    spring:
      application:
        name: discovery-client
    eureka:
      client:
        register-with-eureka: true  # 유레카 서버에 등록
        fetch-registry: true  # 유레카 서버에서 서버 상태 지속적 감시 허락
        service-url:
          defaultZone: http://192.168.67.1:8761/eureka # 유레카 서버의 주소
      instance: # 인스턴스 식별용 아이디 부여
    instance-id: ${spring.application.name}:${spring.application.instance_id:${random.value}}
    - 각 인스턴스별로 유레카에 보여주는 표기를 다르게 하기 위한 설정

    인스턴스 별로 가져오는 것을 볼 수 있다.

  • 완성된 프로젝트에 디스커버리 클라이언트 등록을 할 때
    ext {
        set('springCloudVersion', "2022.0.4")
    }
    dependencyManagement {
        imports {
            mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
        }
    }
    // https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-netflix-eureka-client
    implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
    
    - build.gradle에 의존성 주입을 해주면 된다.
    	위 프로젝트의 경우, Spring Boot 3.1.4버젼 / Eureka Client 4.0.3버젼으로 진행했다.
클라이언트 yml에서 설정한 Application name으로 설정된 것을 Eureka에서 볼 수 있다.

로드 밸런싱 적용

  1. 위의 예제를 기반으로 게이트웨이와 MS를 유레카에 등록했다.


  2. 이전에 게이트웨이에 직접 등록한 포트번호를 변경해야 한다.

    server:
      port: 8000  # 게이트웨이의 경우는 당장 랜덤 포트번호를 사용할 필요가 없다
    spring:
      application:
        name: apigateway-service
      cloud:
        gateway:
          default-filters:  # 전역필터 세팅
            - name: GlobalFilter
              args:
                message: Global Filter Default Message Test
                pre: true
                post: true
          routes:
            - id: first-service
              uri: lb://First-Service # Application name이 First-Service인 인스턴스들을 로드밸런싱
              predicates:
                - Path=/first-service/**
              filters:
                - CustomFilter
                - LogFilter
            - id: second-service
              uri: lb://Second-Service
              predicates:
                - Path=/second-service/**
              filters:
                - AddRequestHeader=s-req,s-req-v
                - AddResponseHeader=s-res,s-res-v
    eureka:
      client:
        register-with-eureka: true  # 유레카 서버에 등록
        fetch-registry: true  # 유레카 서버에서 서버 상태 지속적 감시 허락
        service-url:
          defaultZone: http://192.168.67.1:8761/eureka # 유레카 서버의 주소
      instance: # 인스턴스 식별용 아이디 부여
        instance-id: ${spring.application.name}:${spring.application.instance_id:${random.value}}

    lb://유레카에 등록한 Application명
    → 해당 Application name인 인스턴스들로 로드밸런싱하겠다.


  3. 제대로 로드밸런싱 되었는지 확인하기 위해 Controller를 통해 포트 번호 확인

    @RestController
    @RequestMapping("/first-service")
    @RequiredArgsConstructor
    public class FirstserviceController {
        private final Environment env;
        @RequestMapping(value="/port-check", method = RequestMethod.GET)
        public String portCheck(){
            return env.getProperty("local.server.port");
                // server.port로 쓰면 port번호가 0으로 나타난다.
    						// application.yml파일에 기입된 정보를 얻어와서 자바 자료로 만들어주기 때문
        }
    }


  4. 이름이 First-Service 인스턴스 2개 중 1개의 port번호로 제대로 로드밸런싱이 된다.

profile
취준생 필기노트

0개의 댓글