Spring Cloud로 개발하는 마이크로서비스 애플리케이션(MSA)
Spring Cloud Netflix Eureka
Service Discovery
- 마이크로서비스의 정보(위치 등)를 등록할 수 있음
- 외부의 요청이나 서비스가 마이크로서비스의 정보를 검색하기 위해 사용됨
Eureka의 구성 요소
- Service Discovery : 외부에서 마이크로서비스를 찾아주는 기능
- Service Registry : 각각의 서비스가 자신의 위치 정보를 특정 서버에 등록하는 작업
Eureka Service Discovery - 프로젝트 생성
강의에선 Maven으로 진행했지만 나는 Gradle을 선택했다.
Dependencies에서 Spring Cloud Discovery > Eureka Server를 선택한다.
참고로 강의에서는 Spring boot 버전이 2.4.2이다. 나는 2.7.8을 선택했다.
application.properties → application.yml 수정
server:
port: 8761
spring:
application:
name: discoveryservice
eureka:
client:
register-with-eureka: false
fetch-registry: false
- register-with-eureka (디폴트 true)
- 레지스트리에 자신을 등록할 건지에 대한 여부
- fetch-registry (디폴트 true)
- 레지스트리에 있는 정보를 가지고 올건지에 대한 여부
- true 설정 시 검색할 때마다 Eureka server를 호출하는 대신 레지스트리가 로컬로 캐싱됨
DiscoveryserviceApplication.java 수정
@SpringBootApplication
@EnableEurekaServer // 어노테이션에 의해 이 프로젝트가 EurekaServer가 된다.
public class DiscoveryserviceApplication {
public static void main(String[] args) {
SpringApplication.run(DiscoveryserviceApplication.class, args);
}
}
서버 실행 후 크롬에서 127.0.0.1:8761로 접속하면 Eureka의 대시보드를 확인할 수 있다.
User Service - 프로젝트 생성
강의에서는 Maven을 사용했고, 나는 Gradle을 사용했다.
강의에선 Spring boot 2.4.2 버전을 선택했고, 나는 2.7.8 버전을 선택했다.
그리고 Dependencies도 강의에는 4개만 추가했다.
- Spring Boot DevTools
- Lombok
- Spring Web
- Eureka Discovery Client
나는 혹시 몰라 3개를 더 추가했다.
- Spring HATEOAS
- Spring Data JPA
- H2 Database
UserServiceApplication.java 수정
@SpringBootApplication
@EnableDiscoveryClient
public class UserServiceApplication {
public static void main(String[] args) {
SpringApplication.run(UserServiceApplication.class, args);
}
}
@EnableDiscoveryClient를 추가해 주면 된다. @EnableDiscoveryClient외에 @EnableEurekaClient 어노테이션도 존재하는데 두 어노테이션 다 현재 프로젝트를 DiscoveryClient로 만들어주는 건 똑같다. 차이점은 @EnableDiscoveryClient가 Eureka 외 다른 Discovery Server에서 사용할 수 있고, 더 많은 기능(zookeeper 등)을 지원한다. 그리고 @EnableDiscoveryClient는 spring-cloud-common을 기반으로 두고 있고 @EnableEurekaClient는 spring-cloud-netfliex를 기반으로 한다.
application.properties → application.yml로 수정
# 현재 프로젝트의 포트 번호 지정
server:
port: 9001
# 현재 프로젝트의 이름 지정
spring:
application:
name: user-service
# 현재 프로젝트의 eureka 설정
eureka:
client:
register-with-eureka: true # eureka 등록 여부
fetch-registry: true # Eureka 서버로부터 인스턴스들의 정보를 주기적으로 가져올 것인지 설정하는 속성
service-url:
defaultZone: http://127.0.0.1:8761/eureka # 이 곳에 마이크로서비스 정보를 등록하겠다는 의미
서버 실행 후 eureka 대시보드 확인하려고 했는데 discoveryservice 프로젝트를 꺼버려서 다시 켜야 했다.
근데 키는 도중에 에러가 발생
이미 8761 포트를 사용하고 있다는 에러가 발생했다. 프로젝트 분명히 잘 껐는데 뭐지........ 할 수 없이 8761 포트를 사용하고 있는 프로세스를 터미널에서 k i l l 해줬다.
두 개의 프로젝트 모두 실행 후 eureka 대시보드로 접속한다.
그러면 방금 만든 프로젝트의 정보가 보인다.
User Service - 등록
User Service 동시에 여러 개 실행하기 - Edit Configurations 설정 방법
일단 User Service의 서버가 실행되고 있는 상태에서 진행한다.
우측 상단에 Edit Configurations... 클릭
UserServiceApplication을 클릭한 상태에서 복사 아이콘을 클릭
이름을 깔끔하게 -2로 수정
우측 상단에 UserServiceApplication-2를 선택하면 플레이버튼이 활성화되는 걸 볼 수 있다.
서버를 실행하면 오류가 발생한다.
아까 봤었던 오류이다; 9001 포트를 이미 사용 중이라고 뜨는데 UserServiceApplication과 UserServiceApplication-2가 동일한 포트를 사용하고 있기 때문이다. 그래서 UserServiceApplication-2 포트를 변경해줘야 한다.
application.yml 파일의 port 번호를 변경하는 건 현재 프로젝트의 모든 포트를 동일하게 바꾸는 것이기 때문에 의미가 없다. 그래서 Edit Configurations...에 들어가서 변경해 주자.
주황색 박스 안에 '-Dserver.port=9002'를 적어주면 된다. 그러면 UserServiceApplication-2를 실행할 땐 9002 포트로 실행된다.
-D는 자바 클래스를 실행함에 있어서 부가적인 파라미터 옵션을 부여할 때 쓰는 방법이다.
OK 후 서버 재실행하면 에러가 발생하지 않고 서버가 잘 켜지는 것을 볼 수 있다.
Eureka 대시보드로 접속한다. User Service 관련 두 개의 정보가 보인다.
User Service 동시에 여러 개 실행하기 - Gradle 사용 방법
참고로 강의는 Maven을 사용한다.
터미널에서 아래 명령어를 입력한다.
./gradlew bootrun --args ' --server.port=9003'
중요한 건 ' --server.port=9003'의 앞쪽 공백을 꼭 넣어주어야 한다.
Eureka 대시보드 확인
User Service 동시에 여러 개 실행하기 - Jar 파일 이용 방법
인텔리제이 우측에 Gradle > Tasks > build > build 더블클릭 후 터미널 실행
저 경로에 저 jar 파일이 있으면 된다.
경로 주의!! user-service 폴더에서 입력해야 함
java -jar -Dserver.port=9004 build/libs/user-service-0.0.1-SNAPSHOT.jar
Eureka 대시보드 확인
모든 인스턴스(user-service) 종료 후 Eureka 대시보드 확인
User Service - Load Balancer
매번 인스턴스를 여러 개 실행할 때마다 위에처럼 적용해야 하는 건 상당히 불편한 작업이다. 이런 불편함을 해소할 수 있도록 Spring에서 지원해 주는 기능이 있는데 바로 Random Port 기능이다.
- application.yml
# 현재 프로젝트의 포트 번호 지정
server:
port: 0
port 번호를 0으로 주면 실행할 때마다 무작위로 port 번호를 지정해 준다.
서버를 실행하기 전에 쓸모 없어진 UserServiceApplication-2를 삭제해 주자. UserServiceApplication-2 클릭 후 '-' 아이콘을 누르면 삭제된다.
서버를 실행하고 console에 port를 검색하면 랜덤으로 배정받은 port 번호가 나온다.
이번엔 Eureka 대시보드를 확인해 보자.
port 번호가 51694가 아니라 0으로 보인다.
마우스를 192.168.0.200:user-service:0 링크에 올려놓으면 좌측 하단에 port 번호가 보인다.
확인차 인텔리제이 내에 있는 터미널에서 프로젝트를 실행시켜 보자. 아까 복잡했던 argument를 설정해 줄 필요 없이 아래와 같이 간단하게 입력하면 된다.
./gradlew bootrun
Eureka 대시보드 확인
내가 실행한 인스턴스는 두 개인데, 한 개의 인스턴스 정보 밖에 보이지 않는다.
왜 이런 현상이 생겼냐면 동적으로 할당된 port 번호를 인식하는 것이 아니라, application.yml 파일에 작성된 port 정보를 가져와서 저 링크를 생성하기 때문이다. 그래서 application.yml에 추가적인 설정을 해줘야 한다.
- application.yml
eureka:
instance:
instance-id: ${spring.cloud.client.hostname}:${spring.application.instance_id:${random.value}}
설정 후 프로젝트 두 개를 실행하고 Eureka 대시보드를 확인하자.
- 출처 : 인프런 Spring Cloud로 개발하는 마이크로서비스 애플리케이션(MSA) 강의