Spring Cloud Gateway 프로젝트 생성
- dependencies: Lombok, Gateway, Eureka Discovery Client
application.yml
server:
port: 8000
eureka:
client:
register-with-eureka: false
fetch-registry: false
service-url:
defaultZone: http;//localhost:8761/eureka
spring:
application:
name: apigateway-service
cloud:
gateway:
routes:
- id: first-service
uri: http://localhost:8081/
predicates: # 조건절
- Path=/first-service/** # Path가 이렇게 오면 uri(8081)를 실행하겠다.
- id: second-service
uri: http://localhost:8082/
predicates:
- Path=/second-service/**
서버 실행
서버를 실행하면 콘솔에 Netty started on port 8000 문자를 확인할 수 있다.
지금까지는 Tomcat으로 이용하여 서버를 띄웠는데 이번에는 비동기인 Netty 내장 서버를 이용하여 띄웠다.
Tomcat으로 서버를 띄우는건 동기 방식이고, Spring Cloud Gateway를 이용해 서버를 띄우면 비동기 방식인 Netty로 서버를 띄운다.
❗ 문제) 서버가 Netty가 아닌 Tomcat으로 실행된다면?
pom.xml
인텔리제이로 gateway를 추가하면 starter gateway가 아닌 starter gateway mvc가 추가된다.
starter gateway mvc는 비동기 Netty가 아닌 동기인 Tomcat으로 서버를 실행한다.
따라서 자동으로 추가된 starter gateway mvc은 주석처리하거나 삭제하고
starter gateway를 따로 검색하여 의존성을 추가해야 한다.
https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-gateway/4.0.7
<!--starter-gateway-mvc 삭제 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway-mvc</artifactId>
</dependency>
<!-- starter-gateway 추가 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
<version>4.0.7</version>
</dependency>
페이지 확인
404 에러가 뜬다.
왜 404 에러가 뜨는가?
위에 application.yml에 설정해둔 routes를 확인해보면
predicates의 Path가 uri에 붙어 포워딩 되는데 이대로 URL을 만들면
http://127.0.0.1:8081/first-service/welcome
http://127.0.0.1:8082/second-service/welcome
이렇게 만들어진다.
그럼 문제가 뭐냐면 first-service의 컨트롤러를 들어가보면
@RequestMappring을 "/"으로 설정해뒀기 때문에 "http://localhost:8081/welcom"으로 클라이언트에서 요청해야지만 정상적인 페이지가 뜬다. 고로 @RequestMapping 값을 변경해주면된다.
@RestController
@RequestMapping("/")
public class FirstServiceController {
@GetMapping("/welcome")
public String welcome() {
return "Welcome to the First service";
}
}
Controller 수정
controller 수정 후 프로젝트 재실행하고 크롭에서 확인
//first-service
@RestController
@RequestMapping("/first-service")
public class FirstServiceController { ... }
//second-service
@RestController
@RequestMapping("/second-service")
public class SecondServiceController { ... }
성공~
혼잣말
@RequestMapping을 설정하는게 아니라 gateway에서 path값을 이렇게 지워버리면 되지 않나..?
라고 잠깐 생각했지만, 이러면 url이 구별이 안가서 안된다는 걸 깨달았다...ㅎ