서비스가 커지면서 하나의 서버에 모든 애플리케이션 기능을 넣게 되면 유지보수도 어려워지고, 작은 기능의 장애가 전체의 장애로 이어질수도 있게된다.
따라서 하나의 큰 애플리케이션을 여러개의 작은 애플리케이션으로 나눠 개발하는 아키텍쳐를 MSA라 한다.
Spring에서는 msa를 위해 cloud 프레임워크를 제공하고 있는데, 해당 프레임워크를 통해 msa를 실습해보자!
msa를 적용하면 작은 기능을 가진 여러 서버를 가지고 있게 되는데, 여러 서버에 직접 접근하는 것이 아닌 하나의 전화번호부와 같은 서버에 접근하면 적절하게 분배해주어야한다.
이때 전화번호부 서버를 api gateway라 하고 우리는 Spring Eureka를 이용하여 구성해보도록 하자!
프로젝트 의존성
spring boot 3.1.6
spring cloud discovery -> eureka server
implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-server'
프로젝트를 생성하고 나면 해당 프로젝트를 유레카 서버로 사용하기 위해 Application파일에 @EnableEurekaServer를 추가해주자
application.yml 설정
//서버 포트번호 유레카 서버가 웹서버로서 역할을 할때 포트번호를 설정
server:
port: 8761
//마이크로 서비스를 담당하는 스프링 부트에서 마이크로 서비스의 고유한 아이디를 설정
spring:
application:
name: discoveryservice
//서버가 아닌 클라이언트가 필요한 이유는 유레카 라이브러리가 포함된채 스프링이 실행되면 클라이언트로서 어딘가에 등록하게 되는데, 그중 아래의 설정을 false로 하지 않으면 true로 기본값이 설정되어 자신의 값을 자신에게 등록하게 되게 되어 false로 설정, 서버로써 실행만 되면 됨
eureka:
client:
register-with-eureka: false
fetch-registry: false
http://localhost:8761
으로 실행하면 다음과 같이 실행되는 것을 확인할수 있다.
유레카 서버에 등록 할 샘플 프로젝트 생성해보자!
프로젝트 의존성
dependency : eureka discovery client, lombok, spring boot devtools, spring web
샘플 프로젝트의 Application파일에 @EnableEurekaClient를 추가하면 되는데, 해당 어노테이션은 @EnableDiscoveryClient를 구체화한것으로, 어느것을 사용해도 상관은 없지만, 규격에 해당하는 @EnableEurekaClient를 추가하자
application.yml 설정
server:
port: 9001
spring:
application:
name: user-service
eureka:
client:
register-with-eureka: true
# eureka서버로부터 인스턴스들의 정보를 주기적으로 가져올 것인지를 설정하는 속성으로, true로 설정하면, 갱신된 정보를 받겠다는 설정
fetch-registry: true
service-url:
# 현재 마이크로 서비스가 등록될 유레카 서버의 주소를 작성해준다.
defaultZone: http://127.0.0.1:8761/eureka
유레카 서버를 실행한 상태로 현재 프로젝트를 실행하면 유레카 서버에 등록된것을 확인할수 있다.
같은 코드의 실행파일의 설정을 포트(9002)만 다르게 하여 실행시켜준다
유레카 서비스 디렉토리 안에 서비스가 2개 등록된것을 확인할수 있다.
클라이언트가 마이크로 서비스로 요청을 보낸다면 디스커버리 서비스가 여러 인스턴스로 분산하여 요청을 처리하게 된다.
포트를 직접 설정하여 실행하는 것을 보았는데, 일일히 포트를 설정해주는것은 불편하기에 설정파일에서 포트를 0으로 설정하여 랜덤으로 포트번호를 할당해준다.
랜덤포트로 설정한후 두개의 user-service를 실행한후 eureka서버를 확인하니 하나만 실행된것을 볼수 있습니다.
이것의 원인은 이름표현 방식때문입니다. 따라서 동적으로 이름을 바꿔 실행되도록 설정해줍니다.
eureka:
instance:
instance-id: ${spring.cloud.client.hostname}:${spring.application.instance_id:${random.value}}
다음과 같이 변경되어 2개의 서버가 정상적으로 표시되는것이 보인다.
마이크로 서비스를 실행할때마다 자동으로 포트가 부여되고, 디스커버리 서버에 등록하는 과정을 살펴보았습니다.
디스커버리 서버는 클라이언트에서 요청이 들어올때마다 서로 다른 마이크로 서비스에 분산하여 요청을 처리할수 있게 되는 디스커버리 서버(eureka)의 장점을 알아볼수 있었습니다.