gateway를 통해서 service를 구동하는 방법을 이전 포스트까지 진행했다. 그럼 이전에 사용했던 Eureka를 사용하여 Gateway와 service, Eureka를 모두 연결해서 사용해보자!
전체적인 흐름
사용자의 요청 -> Gateway -> Eureka로부터 서비스의 위치 정보 가져옴 -> Gateway에서 서비스 호출 -> 서비스 로직 실행
기존의 gateway와 service들의 yml 설정에서 false로 막아뒀던
eureka: #eureka 세팅은 현재 사용 안함
client:
fetch-registry: true
register-with-eureka: true
service-url:
defaultZone: http://127.0.0.1:8761/eureka
ureka 등록 설정을 true로 변경해주고 서비스를 모두 실행시켜보자
정상적으로 모두 등록되는 것을 확인할 수 있다.
그런데 여기서 한가지 설정이 빠져있는데. Eureka를 사용하여 Load Balance를 사용하기 위한 설정이 빠져있다.
server:
port: 8000
eureka: #eureka 세팅은 현재 사용 안함
client:
fetch-registry: true
register-with-eureka: true
service-url:
defaultZone: http://127.0.0.1:8761/eureka
spring:
application: #gateway service 이름
name: apigateway-service
cloud:
gateway: #gateway 설정
default-filters:
- name : GlobalFilter #Global Filter로 지정된 java 파일 이름
args:
baseMessage: Spring Cloud Gateway Global Filter
preLogger: true
postLogger: true
routes:
- id: first-service #gateway로 연결될 서비스 이름
uri: lb://FIRST-SERVICE #gateway로 연결될 서비스 uri
predicates: #gateway로 연결될 서비스의 url 매핑
- Path=/first-service/**
filters:
# - AddRequestHeader=first-request, first-request-header2
# - AddResponseHeader=first-response, first-response-header2
- CustomFilter
- id: second-service
uri: lb://SECOND-SERVICE
predicates:
- Path=/second-service/**
filters:
# - AddRequestHeader=second-request, second-request-header2
# - AddResponseHeader=second-response, second-response-header2
- name: CustomFilter
- name: LoggingFilter
args:
baseMessage: Hi, Logging Filter.
preLogger: true
postLogger: true
기존의 yml설정과 비교해보면 변경된 점은 각 서비스들의 uri를 http 프로토콜을 사용하여 직접 포트에 연결시키는 것이 아니라 lb://서비스명
을 통해서 Eureka에 등록되어지는 이름을 통해 호출하도록 변경한 것이다.
Eureka로 호출을 변경했어도 정상적으로 각 서비스들을 불러오는 것을 확인할 수 있다.
서비스1,2를 각각 실행시키고 터미널을 열어서
mvn spring-boot:run -Dspring-boot.run.jvmArguments='-Dserver.port=9001'
mvn spring-boot:run -Dspring-boot.run.jvmArguments='-Dserver.port=9002'
로 각 9001과 9002 포트를 사용하여 추가로 1개씩 더 열어보자!
다음과 같이 Eureka에서 각 서비스들이 1개씩 추가되어 총 2개씩 등록되어져 있는 것을 확인할 수 있다. lb장비를 따로 설정하지 않아도 프로젝트 자체에서 이렇게 쉽게 사용할 수 있고 Eureka를 통해서 포트가 아닌 서비스의 이름으로 Load Balancer를 수행할 수 있다.
server:
port: 0
spring:
application:
name: first-service
eureka:
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://127.0.0.1:8761/eureka
instance:
instance-id: ${spring.application.name}:${spring.application.instance_id:${random.value}}
서비스들을 랜덤포트로 열기 위해 port를 0으로 설정해주고 Eureka에서 서비스의 포트 이름이 중복으로 처리되어 열린 서비스를 구분할 수 없어서 instance-id값을 설정해주기 위해 가장 마지막 라인의 설정을 추가해주었다. 가장 밑의 설정으로 application name : 랜덤 번호
로 설정되어 Eureka에 노출되어진다.
다시 2개씩 실행해보자!
위 포트번호로 설정해서 실행하던 명령어를
mvn spring-boot:run
명령어로만 실행해도 된다!
이제 우리는 서비스를 포트를 일일히 지정해줄 필요도 없고 실행할때 포트를 신경쓰지 않아도 자동으로 서비스를 여러개로 실행하여 관리할 수 있게되었다.
Eureka에서 모두 확인은 가능하지만 실제로 Load Balancer가 정상적으로 작동하고 있는지 확인하고 싶어졌다. 그래서 Controller에서 port번호 정보를 전달하여 특정 url에서 port번호를 반환하도록 해보자!
@RestController
@RequestMapping("/first-service")
@Slf4j
@RequiredArgsConstructor
public class HelloController {
private final Environment env;
...
@GetMapping("/check")
public String check(HttpServletRequest request){
log.info("server port = {}",request.getServerPort());
return String.format("Hi, there. This is a message from first Service Port = %s", env.getProperty("local.server.port"));
}
}
포트번호가 각각 다르게 표시되고 log도 다른 서비스에서 찍히고 있는 것을 확인하며 로드 밸런서가 정상적으로 잘 작동한다는 것도 확인할 수 있다!