[MSA] Spring Cloud Gateway (1) - 프로젝트 생성
https://born2bedeveloper.tistory.com/57
***이전 포스팅에 Spring Cloud Gateway참고
개발 환경 : InteliJ (Ultimate Mode) / Maven / Java11
Spring Cloud Gateway 프로젝트 생성
inteliJ에서 File > New > Project... 클릭하여 새 프로젝트를 생성하자.
멈춰!
나는 inteliJ Ultimate 모드가 아닌데..?
하는 분들은 Spring initializr에서 직접 프로젝트를 만들어 열어야 한다!
이 링크를 타고 들어가 아래의 설정과 같게 만들어주면 된다!
Maven, Java11설정 외에 나머지는 자유롭게 설정하자 (프로젝트 명, 파일 위치 등)
Lombok과 Spring Cloud Routing에 있는 Gateway, Eureka Discovery Client 세 가지를 등록하자.
프로젝트가 생성되면 기존 설정파일 확장자를 yml로 바꿔준다 (취향차이므로 패스해도 무관하다. 다만 이후에 양식을 properties에 맞춰 바꿔 써야할것임)
설정파일에 해당 어플리케이션 포트를 8000번으로 지정한다.
또한 차후에 추가할 service discovery 구현을 위해 미리 eureka server 설정을 기입해둔다. (현재는 쓰이지 않음)
다음은 Spring Cloud Gateway 설정 내용이다.
- id : 고유한 route의 이름
- uri : 해당하는 정보를 어디에 포워딩 시켜줄지에 대한 위치정보 기입
- predicates : 조건→ 클라이언트가 first-service/로 시작하는 요청을 하면 지정한 uri (localhost:8081/)로 가겠다.
first, second 서비스를 두 개 만든 후 조건에 따른 Path설정에 따라 각각 지정한 uri로 포워딩을 시켜줄 것이다.
해당하는 서비스를 구동시킬 프로젝트를 만들어 보자.
Service 프로젝트 생성 - first & second service
해당 dependency들을 추가하여 각각 first-service, second-service 프로젝트를 만들자.
설정파일을 yml로 바꿔주고 각각 컨트롤러를 생성한다. (패키지를 만들어서 넣어도 되지만 별다른 일을 하지 않아서 Application 컨트롤러랑 같은 위치에 넣었다.)
이름은 뭐.. 각각 First, Second를 넣어 대충 지으면 된다.
url 요청을 /welcome이라고 했을 때 해당 문자열을 반환하도록 작성하였다. SecondController에도 구분할 수 있도록 작성하자.
(SecondController는 다른 프로젝트에서 만들어야 한다.! 총 first-service, second-service 프로젝트 2개를 만들어야 한다는 소리임! 헷갈리지 말 것)
각각 두 프로젝트의 설정 파일이다.
프로젝트 구동
한번 구동해보자.
fist, second service 각각 프로젝트를 실행하고, 맨 처음 만든 apigate용 프로젝트도 돌려보자.
이 때 Apigateway 포르젝트의 마지막줄 쪽을 확인하면 다음과 같은 부분을 발견할 수 있다.
기존에는 Tomcat 서버였는데 뜬금없는 Netty가 등장하였다 (천사소녀?ㅎ)
그 이유는 Spring Cloud Gateway서비스는 비동기방식을 지원하기 때문에 동기 방식인 Tomcat 대신 Netty서비스가 작동이 되는 것이다.
이제 우리가 기대하는 동작 과정은 다음과 같을 것이다.
- http://localhost:8000/first-service/welcome 과 http://localhost:8000/second-service/welcome를 각각 실행한다.
- 8000번 포트의 apiGateway프로젝트에서 설정파일로 인해 각각 해당하는 uri로 보내줄 것이다.
- 우리가 설정해둔 컨트롤러에 따라 Welcom to the ... 메세지가 뜬다.
한번 실행해보자
응? 외않되?
다시 설정파일을 보자
predicates 블럭의 조건에 따라 /first-service/** 부분이 호출되면 localhost:8081/ URI로 보낸다고 설정되어있다.
문제는 넘어가는 uri의 형태에 있다.
넘어갈 때 uri에 predicates의 Path가 같이 붙어서 넘어간다. 즉,
http://localhost:8081/first-service/**와 같은 형태로 넘어가버리는 것이다!
다시 컨트롤러로 돌아가 확인하면, first-service의 컨트롤러 매핑은
http://localhost:8081/welcome 으로 받는다고 설정해놨는데, http://localhost:8081/first-service/welcome 으로 보내니 당연히 404(해당 경로에 대한 페이지나 응답이 없음)오류가 뜨는 것이다.
,
즉, Api gateway에 요청이 "/first-service"가 붙어야만 localhost:8081로 보내주기 때문에
first-service 컨트롤러 입장에선 http://localhost:8081/first-service/welcome 로 넘어가게 된다.
애초에 요청을 그렇게 했으니까...
따라서 컨트롤러에서 매핑을 다음과 같이 설정해줘야 한다.
그 후 다시 검색하면?
짜잔!
분명 localhost:8000 경로로 호출했는데
8001, 8002포트에 연결된 first, second 어플리케이션에서 응답받은 것을 확인할 수 있다.
신기하지 않은가? 😎
앞으로 Spring Cloud Gateway 서버를 생성할 때, 설정파일에 있는 predicates 조건을 잘 기억해두자.
Path에 설정된 /first-service 등과 같은 패턴이 우리가 설정한 uri에 그래도 붙어간다는 점!
따라서 8081포트의 서비스로 넘어갈 때는 http://localhost:8081/first-service/** 방식으로 넘어가니
해당 컨트롤러에서 매핑할 때 유의해야 한다!
다음은 Filter를 적용해보도록 하겠다.
[참고 레퍼런스]