본문 바로가기

개발스터디/MSA 스터디 (22년)

Java MSA를 위한 Spring Cloud 환경 구축하기(Eureka)

  Spring Cloud란? 

포스팅 참고 하시길 바랍니다.

https://themapisto.tistory.com/186

 JAVA Micro-Service 실습 환경 구축

기초적인 Microservices 구조를 구현하기 위해서 총 3가지의 프로젝트를구현했고  개발환경은 다음과 같습니다.

 

 

  Spring Cloud Eureka란? 

MSA의 개요와 Spring Cloud의 주요 라이브리들의 이해가 선행되어야 실제 개발하는데 수월하기에 혹시 해당 내용에 대하여 처음 들어보시는 분들은 선행학습 을 해주시길 바랍니다.

 

Eureka 서버에 대해서 알아보도록 하겠습니다.

  • Eureka는 마이크로 서비스에서 주소록 역할을 합니다.
  • 기존 레가시 어플리케이션에서는 한개의 서버에서 거대한 모놀리스 어플리케이션을 구동하기 때문에 마이크로 서비스의 주소록 역할을 하는 Eureka 같은 추가적인 서버가 필요하지 않았습니다.
  • 하지만, 컨테이너 및 쿠버네티스에서 서비스를 운영하게 되면 서버의 IP가 수시적으로 변경되기 때문에 이러한 Service Discovery 역할을 하는 Eureka 서버가 필요합니다.

예제를 통해서 조금 더 자세히 알아보도록 하겠습니다.


 

  Spring Cloud Eureka 서버 

 

1-1 .  Spring initialzr 를 통해 gradle 빌드 파일을 다운로드 받는다.

 

  • 우선 처음 빌드할 프로젝트는 Eureka 서버입니다. 
  • Spring Initalzr는 스프링 프로젝트를 간편하게 빌드할수 있고 빌드 관련 gradle,maven의 환경설정을 자동으로 만들어줍니다.
  •  다음과 같이 선택하여 배포하면 zip 파일로 프로젝트를 받을수 있습니다.

 

 

1- 2. application.yml과 Application.java 쪽 Bean등록

- Bean등록과 어노테이션을 통해 쉽게 Eureka 서버를 세팅할수 있다.

- application.yaml에는 포트와 여러 환경설정들을 설정해줄수 있다. 처음 프로젝트를 만들면 application.properties라는 파일이 있는데 이것은 지우고 application.yaml로  환경설정을 세팅 하겠습니다. 

## DemoApplication.java
package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@SpringBootApplication
@EnableEurekaServer
public class DemoApplication {

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

}
## application.yml
server:
  port: 8761

spring:
  application:
    name: service-discovery

eureka:
  client:
    register-with-eureka: false # 유레카 서비스에 (자신을) 등록 여부
    fetch-registry: false  # (유레카 클라이언트 기반) 다른 서비스들의 정보를 fetch 유무
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/ # 설정을 하지 않으면 기본 http://localhost:8761/ 로 연동된다.

  server:
    wait-time-in-ms-when-sync-empty: 5  # 서버가 요청을 받기 전 대기할 초기 시간(ms) : 거의 대기 없음 (default 5분 : 상용에서는 모든 서비스가 등록 되길 기다리기 위해 5분 후 정보를 공유)

management:
  endpoints:
    web:
      exposure:
        include: "*"

 

1-3. Application 구동 (유레카 서버)

 

여기까지 하면 Eureka 서버를 띠운것이다.

위에서도 설명 했듯이 유레카 서버는 msa 서비스들의 주소록과 같은 Service Discovery이다. 

 kubernetes를 사용하게 되면 이와 같은 서비스 Discovery를 쿠버네티스에서 대신 해줄수 있지만 

그게 아니라면 반드시 msa에 필요한 요소라고 할수 있다. kubernetes와 Spring Cloud의 비교 자료를 첨부한다.

 

 

 

  Spring Cloud Eureka Client 서버 

  • Client 서버라는 이름에서 알수 있듯이, 주소록에 기록될 Client 서버들을 배포하는 방법이다.
  • 아시다시피 spring initializer은 Spring Boot 프로젝트를 빠르게 빌드해줄수 있게 패키징 되어 있는 어플리케이션을 배포하는 툴이다. 이니셜 라이저로 프로젝트를 빌드하게 되면 Dependencies도 함께 선택하여 생성할 수 있기 때문에 초반 세팅에 귀찮은 작업들에 시간낭비를 줄일수 있다.
  • https://start.spring.io/  에 접속하여 다음과 같이 세팅하자.
Adopt JDK 11버전을 받았기 때문에 Java는 꼭 11버전으로 선택 하여 주어야 한다.

 

2-1. 빌드

2-2. 환경설정 

  • Application.yml을 설정합니다.
server:
  port: 8011

spring:
  application:
    name: service1

eureka:
  instance:
    prefer-ip-address: true
  client:
    register-with-eureka: true # 유레카 서비스에 (자신을) 등록 여부
    fetch-registry: true
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/

management:
  endpoints:
    web:
      exposure:
        include: "*"

 

Application 가동 클래스에 해당 Bean을 주입합니다.

@EnableDiscoveryClient

# Eurkea 서버에서 Discovery 될 Client가 되겠다 라는 Annotation

2-3. Annotation을 통한 Client 등록

# Service1Application.java

package com.example.service1;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@SpringBootApplication
@EnableDiscoveryClient
public class Service1Application {

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

}

2-4. 테스트용 API를 생성

# Controller 클래스 
# Dcontroller.java
package com.example.service1;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
public class DController {
    @Autowired
    DService discoveryService;

    @GetMapping(value = "/services")
    public List<String> services() {
        return discoveryService.getServices();
    }

}


# Service 클래스
# DService.java
package com.example.service1;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
public class DService {
    @Autowired
    private DiscoveryClient discoveryClient;

    public List getServices(){
        List<String> services = new ArrayList<String>();

        /** 람다스트림 표현 */
        discoveryClient.getServices().forEach(serviceName -> {
            discoveryClient.getInstances(serviceName).forEach(instance->{
                services.add( String.format("%s:%s",serviceName,instance.getUri()));
            });
        });
        return services;
    }

}