Software Architecture/MSA

[MSA ๊ตฌ์ถ•ํ•˜๊ธฐ] 7. Spring Cloud Gateway๋ฅผ ํ™œ์šฉํ•œ ๊ฒฝ๋กœ ์ˆ˜์ • (API Gateway)

bu119 2024. 3. 20. 09:00
728x90
๋ฐ˜์‘ํ˜•

๐Ÿ”Š ์šฐ๋ฆฌ๋Š” Spring Cloud๋ฅผ ํ™œ์šฉํ•˜์—ฌ MSA๋ฅผ ๊ตฌ์ถ•ํ•œ๋‹ค.

๐Ÿ”Š ์•ž์„œ, API Gateway์˜ ๋ผ์šฐํŒ…์„ ์„ค์ •ํ–ˆ๋Š”๋ฐ ์‹คํ–‰ํ–ˆ์„ ๋•Œ ๊ฒฐ๊ณผ ๊ฐ’์ด ๋‹ค๋ฅด๊ฒŒ ๋‚˜ํƒ€๋‚ฌ๋‹ค. ๊ทธ ์ด์œ ์— ๋Œ€ํ•ด ์•Œ์•„๋ณด์ž.

 

API Gateway ํŒŒํŠธ 3

 

์šฐ์„ , ์ž‘์„ฑํ•œ ์ฝ”๋“œ๋ฅผ ์‚ดํŽด๋ณด์ž.

1. user-service์˜ UserController.java  ํŒŒ์ผ

// user-service: UserController.java (8081 ํฌํŠธ ์‚ฌ์šฉ)

package com.caffeinedoctor.userservice.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class UserController {

    @GetMapping("/")
    public String getServiceName(){
        return "user-service";
    }
}

 

user- service ์„œ๋ฒ„ ์‹คํ–‰

http://localhost:8081/

 

2. apigateway-service์˜ application.yml ํŒŒ์ผ

# apigateway-service: application.yml

server:
  port: 8000

spring:
  application:
    name: apigateway-service
  cloud:
    gateway:
      routes:
        - id: user-service
          uri: http://localhost:8081/
          predicates:
            - Path=/user-service/**
        - id: beverage-service
          uri: http://localhost:8082/
          predicates:
            - Path=/beverage-service/**
        - id: community-service
          uri: http://localhost:8083/
          predicates:
            - path=/community-service/**

 

apigateway-service ์„œ๋ฒ„ ์‹คํ–‰

http://localhost:8000/user-service/

  • 404 ์—๋Ÿฌ ๋ฐœ์ƒ

 

 

โ“๋ผ์šฐํŒ… ์—ฐ๊ฒฐ์„ ํ–ˆ๋Š”๋ฐ ๋‘ ์ฃผ์†Œ์˜ ๊ฒฐ๊ณผ๊ฐ€ ๋‹ค๋ฅด๊ฒŒ ๋‚˜ํƒ€๋‚œ๋‹ค. ๋‹ค์‹œ ๋งํ•ด, API Gateway service์˜ ๋ผ์šฐํŒ… ์„ค์ •์„ ๋งˆ์ณค๋Š”๋ฐ ๊ฐ ์„œ๋น„์Šค๋กœ ์—ฐ๊ฒฐ์ด ๋˜์ง€ ์•Š๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค. apigateway-service์˜ yml ํŒŒ์ผ์— ์„ค์ •์„ ํ–ˆ๋Š”๋ฐ 8000๋ฒˆ ํฌํŠธ์—์„œ 8081, 8082, 8083 ํฌํŠธ๋กœ ์—ฐ๊ฒฐ์ด ์•ˆ ๋œ๋‹ค.๐Ÿ˜จ

  • http://localhost:8000/user-service/์—์„œ http://localhost:8081/๋กœ ์—ฐ๊ฒฐ์ด ์•ˆ๋œ๋‹ค.
  • http://localhost:8000/beverage-service/์—์„œ http://localhost:8082/๋กœ ์—ฐ๊ฒฐ์ด ์•ˆ๋œ๋‹ค.
  • http://localhost:8000/community-service/์—์„œ http://localhost:8083/์œผ๋กœ ์—ฐ๊ฒฐ์ด ์•ˆ๋œ๋‹ค.

์™œ ๊ทธ๋Ÿด๊นŒ? ๊ทธ ์ด์œ ๋ฅผ ์ฐพ๊ธฐ ์œ„ํ•ด ๋˜ ์—ด์‹ฌํžˆ ๊ตฌ๊ธ€ ๊ฒ€์ƒ‰์„ ํ–ˆ๋‹ค.

๊ฒฐ๋ก ์ ์œผ๋กœ, ์ด ๋ฌธ์ œ๋Š” Gateway ์„ค์ • ๊ฒฝ๋กœ์™€ ์‹ค์ œ ์„œ๋น„์Šค ์ฝ”๋“œ ๊ฐ„์˜ API ํ†ต์‹  ๊ฒฝ๋กœ ๋ถˆ์ผ์น˜๋กœ ์ธํ•ด ๋ฐœ์ƒํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ์•„๋ƒˆ๋‹ค. ์œ„์˜ ์ฝ”๋“œ ์„ค์ •์— ๋”ฐ๋ฅด๋ฉด http://localhost:8000/user-service/๋กœ ๋“ค์–ด์˜ค๋Š” ์š”์ฒญ์ด http://localhost:8081/๋กœํ”„๋ฝ์‹œ๋˜๋Š” ๊ฒƒ์„ ์˜ˆ์ƒํ–ˆ์œผ๋‚˜ ์‹ค์ œ๋กœ๋Š” http://localhost:8081/user-service/๋กœ ์ „๋‹ฌ๋˜๋Š” ๊ฒƒ์ด์—ˆ๋‹ค.

 

์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ๋‘ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์„ ์ฐพ์•˜๋‹ค.

  1. ์ฒซ ๋ฒˆ์งธ ๋ฐฉ๋ฒ•์€ ๊ฐ„๋‹จํžˆ ๊ฒฝ๋กœ๋ฅผ ์ˆ˜์ •ํ•˜์—ฌ ์„œ๋น„์Šค ์ฝ”๋“œ์™€ ์ผ์น˜์‹œํ‚ค๋Š” ๊ฒƒ์ด๋‹ค.
  2. ๋‘ ๋ฒˆ์งธ ๋ฐฉ๋ฒ•์€ Spring Cloud Gateway์—์„œ URI ๊ฒฝ๋กœ๋ฅผ ์žฌ์ž‘์„ฑํ•˜๋Š” ํ•„ํ„ฐ๋ฅผ ์ ์šฉํ•˜๋Š” ๊ฒƒ์ด๋‹ค. Gateway๋Š” ์ด๋Ÿฌํ•œ ํ•„ํ„ฐ๋ฅผ ํ†ตํ•ด ๋“ค์–ด์˜ค๋Š” ์š”์ฒญ๊ณผ ๋‚˜๊ฐ€๋Š” ์‘๋‹ต์„ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ด๋ฅผ ํ†ตํ•ด Gateway์™€ ์„œ๋น„์Šค ๊ฐ„์˜ ์ผ๊ด€์„ฑ์„ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค.

โญAPI Gateway์—์„œ ๋งˆ์ดํฌ๋กœ์„œ๋น„์Šค๋กœ ๋ผ์šฐํŒ… ์—ฐ๊ฒฐ์ด ์ œ๋Œ€๋กœ ๋˜์ง€ ์•Š์€ ์ด์œ ?

๊ฒฐ๋ก ๋ถ€ํ„ฐ ๋งํ•˜์ž๋ฉด,

Gateway ๊ตฌ์„ฑ์—์„œ ์ •์˜๋œ ๊ฒฝ๋กœ ๋ฐ ํ”„๋ฝ์‹œ ์„ค์ •๊ณผ ์‹ค์ œ ์„œ๋น„์Šค ์ฝ”๋“œ ๊ฐ„์˜ ๋ถˆ์ผ์น˜ ๋•Œ๋ฌธ์— ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค.

  • Gateway ์„ค์ • ๊ฒฝ๋กœ
    • http://localhost:8000/user-service/** ์œผ๋กœ ์š”์ฒญํ•˜๋ฉด
    • http://localhost:8081/user-service/** ์œผ๋กœ ์š”์ฒญ์ด ๋„˜์–ด๊ฐ„๋‹ค.
  • user-service ์„œ๋น„์Šค ๊ฒฝ๋กœ
    • user-service ์„œ๋น„์Šค API @GetMapping("/") ์œผ๋กœ ์„ค์ •๋˜์–ด์žˆ๋‹ค.
    • http://localhost:8081/ ์œผ๋กœ API ํ†ต์‹ ์„ ํ•˜๊ณ ์žˆ๋‹ค.
    • ์ฆ‰, http://localhost:8000/user-service/ ์— ๋Œ€ํ•ด์„œ๋Š” API๊ฐ€ ์„ค์ •๋˜์–ด ์žˆ์ง€ ์•Š์•„ 404์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

 

์ƒ์„ธํžˆ ์„ค๋ช…ํ•˜๋ฉด,

๋จผ์ €, Spring Cloud Gateway ์„ค์ •์„ ์‚ดํŽด๋ณด๋ฉด ๋ผ์šฐํ„ฐ ์„ค์ •์ด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

# apigateway-service: application.yml

spring:
  application:
    name: apigateway-service
  cloud:
    gateway:
      routes:
        - id: user-service
          # ์–ด๋””๋กœ ๊ฐˆ๊บผ๋‹ˆ?
          uri: http://localhost:8081/
          # ์กฐ๊ฑด์ ˆ
          predicates:
            - Path=/user-service/**

 

์ด ์„ค์ •์€ Gateway์— ๋“ค์–ด์˜ค๋Š” /user-service/๋กœ ์‹œ์ž‘ํ•˜๋Š” ์š”์ฒญ์„ http://localhost:8081/user-service/๋กœ ํ”„๋ก์‹œ ํ•˜๋ผ๋Š” ์˜๋ฏธ์ด๋‹ค. 

ํ˜„์žฌ Spring Cloud Gateway ์„ค์ •์€ http://localhost:8081/์— user-service/**๊ฐ€ ์ถ”๊ฐ€๋˜์–ด http://localhost:8081/user-service/**๋กœ ์š”์ฒญ๋œ๋‹ค.

  • http://localhost:8081/ + user-service/**

http://localhost:8000/user-service/** ์œผ๋กœ ์š”์ฒญํ•˜๋ฉด http://localhost:8081/user-service/** ์œผ๋กœ ์š”์ฒญ์ด ๋„˜์–ด๊ฐ„๋‹ค.

 

user-service์˜ ์ปจํŠธ๋กค๋Ÿฌ์˜ API ํ†ต์‹  ์ฝ”๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

// user-service: UserController.java (8081 ํฌํŠธ ์‚ฌ์šฉ)

@RestController
public class UserController {

    @GetMapping("/")
    public String getServiceName(){
        return "user-service";
    }
}

 

user-service์˜ ์ปจํŠธ๋กค๋Ÿฌ๋Š” "/" ๊ฒฝ๋กœ์— ๋Œ€ํ•ด์„œ๋งŒ ์‘๋‹ตํ•˜๊ณ  ์žˆ๋‹ค. ๋”ฐ๋ผ์„œ ์‹ค์ œ๋กœ๋Š” http://localhost:8081/์—์„œ ๋Œ€ํ•ด์„œ๋งŒ ๋™์ž‘ํ•œ๋‹ค. ํ•˜์ง€๋งŒ, Gateway๋Š” /user-service/๋กœ ์‹œ์ž‘ํ•˜๋Š” ์š”์ฒญ์„ ๊ธฐ๋Œ€ํ•˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜์ง€ ๋ชปํ•œ๋‹ค.

 

์ •๋ฆฌํ•˜์ž๋ฉด,

์ด ๋ฌธ์ œ๋Š” Gateway ์„ค์ • ๊ฒฝ๋กœ์™€ ์‹ค์ œ ์„œ๋น„์Šค ์ฝ”๋“œ ๊ฐ„์˜ API ํ†ต์‹  ๊ฒฝ๋กœ ๋ถˆ์ผ์น˜๋กœ ์ธํ•ด ๋ฐœ์ƒํ•œ๋‹ค.

  1. ํ˜„์žฌ ์„ค์ •์— ๋”ฐ๋ฅด๋ฉด, Gateway์—์„œ ์š”์ฒญ์ด http://localhost:8000/user-service/** ์œผ๋กœ ๋“ค์–ด์˜ค๋ฉด ์‹ค์ œ๋กœ๋Š” http://localhost:8081/user-service/** ์œผ๋กœ ์ „๋‹ฌ๋œ๋‹ค.
  2. ๊ทธ๋Ÿฌ๋‚˜ ์‹ค์ œ ์„œ๋น„์Šค ์ฝ”๋“œ์—์„œ๋Š” http://localhost:8081/user-service/๊ฐ€ ์•„๋‹Œ http://localhost:8081/์—์„œ๋งŒ API๊ฐ€ ์„ค์ •๋˜์–ด ์žˆ๋‹ค.
  3. ์ด ๋ถˆ์ผ์น˜๋กœ ์ธํ•ด ์š”์ฒญ์ด ์˜ฌ๋ฐ”๋ฅธ ์—”๋“œํฌ์ธํŠธ๋กœ ์ „๋‹ฌ๋˜์ง€ ์•Š๊ณ  ์„œ๋น„์Šค ์ฝ”๋“œ์˜ ๋‹ค๋ฅธ ๊ฒฝ๋กœ๋กœ ์ด๋™ํ•˜๊ฒŒ ๋˜์–ด 404์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

 

๋‹ค๋ฅธ API ์ฃผ์†Œ๋กœ ์˜ˆ๋ฅผ ๋“ค๋ฉด, 

@GetMapping("/welcome")  ์œผ๋กœ ๋˜์–ด์žˆ์„ ๋•Œ,

Gateway์—์„œ http://localhost:8000/user-service/welcome๋กœ ์š”์ฒญ์ด ์ „๋‹ฌ๋˜๋ฉด ์‹ค์ œ๋กœ๋Š” http://localhost:8081/user-service/welcome๋กœ ์ „๋‹ฌ๋˜์–ด์•ผ ํ•œ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์‹ค์ œ ์„œ๋น„์Šค ์ฝ”๋“œ์—์„œ๋Š” http://localhost:8081/welcome ๊ฒฝ๋กœ์— API๊ฐ€ ์„ค์ •๋˜์–ด ์žˆ๋‹ค.

 

๋ฐ˜์‘ํ˜•

 


1. API Gateway ๋ผ์šฐํŒ… ๊ฒฝ๋กœ ์ˆ˜์ •ํ•˜๊ธฐ

์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” user-service์˜ ์ปจํŠธ๋กค๋Ÿฌ๊ฐ€ /user-service/ ๊ฒฝ๋กœ์— ๋Œ€ํ•ด์„œ ์‘๋‹ตํ•˜๋„๋ก ์ˆ˜์ •ํ•ด์•ผ ํ•œ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด Gateway ์„ค์ •๊ณผ ์‹ค์ œ ์„œ๋น„์Šค์˜ ๊ฒฝ๋กœ๊ฐ€ ์ผ์น˜ํ•˜๊ฒŒ ๋˜์–ด ์š”์ฒญ์ด ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ํ”„๋ฝ์‹œ ๋  ๊ฒƒ์ด๋‹ค.

user-service์˜ UserController.java  ํŒŒ์ผ ์ˆ˜์ •

// user-service: UserController.java (8081 ํฌํŠธ ์‚ฌ์šฉ)

@RestController
@RequestMapping("/user-service")
public class UserController {

    @GetMapping("/")
    public String getServiceName(){
        return "user-service";
    }
}

ํด๋ผ์ด์–ธํŠธ๊ฐ€ http://localhost:8000/user-service/๋กœ ์š”์ฒญ์„ ๋ณด๋‚ด๋ฉด, API Gateway๋Š” ์ด ์š”์ฒญ์„ http://localhost:8081/user-service/๋กœ ํ”„๋ฝ์‹œํ•œ๋‹ค.

 

user- service ์„œ๋ฒ„ ์‹คํ–‰

user-service

 

apigateway-service ์„œ๋ฒ„ ์‹คํ–‰

apiateway-service

 

์ด ๊ฒฝ์šฐ๋Š” ํ•„ํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ , ๋‹จ์ˆœํžˆ ๊ฒฝ๋กœ๋ฅผ ๋ผ์šฐํŒ… ๋Œ€์ƒ์œผ๋กœ ์ „๋‹ฌํ•œ ๊ฒƒ์ด๋‹ค.

 

๊ฒฝ๋กœ ์˜ˆ์‹œ

http://localhost:8000/user-service/name  โžก๏ธ  http://localhost:8081/user-service/name
http://localhost:8000/beverage-service/10  โžก๏ธ  http://localhost:8082/beverage-service/10
http://localhost:8000/community-service/feed  โžก๏ธ  http://localhost:8083/community-service/feed

 


์ฐธ๊ณ ์ž๋ฃŒ

https://spring.io/blog/2022/08/26/creating-a-custom-spring-cloud-gateway-filter

728x90
๋ฐ˜์‘ํ˜•