Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

11 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

MSA

Monolith vs Microservice Architecture

Monolith

  • ๋ชจ๋“  ์—…๋ฌด ๋กœ์ง์ด ํ•˜๋‚˜์˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ํ˜•ํƒœ๋กœ ํŒจํ‚ค์ง€๋˜์–ด ์„œ๋น„์Šค
  • ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ํ•œ ๊ณณ์— ๋ชจ์—ฌ ์ฐธ์กฐ๋˜์–ด ์„œ๋น„์Šค๋˜๋Š” ํ˜•ํƒœ

Untitled

Microservice Architecture

  • ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์˜ ์„œ๋น„์Šค๋“ค์ด ๋ถ„๋ฆฌ๋˜์–ด ์กด์žฌ
  • ๋…๋ฆฝ์ ์œผ๋กœ ๋ฐฐํฌ ๊ฐ€๋Šฅ
  • CI/CD๊ฐ€ ์ค‘์š”!!

MSA ํ‘œ์ค€ ๊ตฌ์„ฑ์š”์†Œ

Untitled

Service Mesh Capabilities

Untitled

  • MSA ์ธํ”„๋ผ โ†’ ๋ฏธ๋“ค์›จ์–ด
    • ํ”„๋ก์‹œ ์—ญํ• , ์ธ์ฆ, ๊ถŒํ•œ ๋ถ€์—ฌ, ์•”ํ˜ธํ™”, ์„œ๋น„์Šค ๊ฒ€์ƒ‰, ์š”์ฒญ ๋ผ์šฐํŒ…, ๋กœ๋“œ ๋ฐธ๋Ÿฐ์‹ฑ
    • ์ž๊ฐ€ ์น˜์œ  ๋ณต๊ตฌ ์„œ๋น„์Šค
  • ์„œ๋น„์Šค๊ฐ„์˜ ํ†ต์‹ ๊ณผ ๊ด€๋ จ๋œ ๊ธฐ๋Šฅ์„ ์ž๋™ํ™”

MSA ํ‘œ์ค€ ๊ตฌ์„ฑ์š”์†Œ

  • CNCF (Cloud Native Computing Foundation)
    • Cloud Native Interactive Landscape

Spring Cloud

  • ํ™˜๊ฒฝ ์„ค์ •์„ ์œ„ํ•ด Spring Cloud Config Server ํ•„์š”
    • ์™ธ๋ถ€ ์ €์žฅ์†Œ์— ํ•œ๋ฒˆ์— ํ™˜๊ฒฝ์„ค์ • ๋ชจ์•„๋‘ 
    • ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ์‰ฌ์›Œ์ง„๋‹ค.
  • ์„œ๋น„์Šค ๋“ฑ๋ก๊ณผ ์œ„์น˜ ์ •๋ณด ํ™•์ธ์„ ์œ„ํ•ด Naming Server (Eureka)
  • Load Distribution (Load balancing) ์„ ์œ„ํ•ด Ribbon (Client Side), Spring Cloud Gateway ์‚ฌ์šฉ
    • ์™ธ๋ถ€์˜ ํด๋ผ์ด์–ธํŠธ๋‚˜ ์„œ๋น„์Šค ์ •๋ณด๊ฐ€ ๊ฒŒ์ดํŠธ์›จ์ด๋ฅผ ํ†ต๊ณผํ•ด์„œ Micro Service๋กœ ์ด๋™
  • ๊ฐ๊ฐ์˜ Micro Service ๊ฐ„์˜ ํ†ต์‹ ์„ ์œ„ํ•ด FeignCliend ์ด์šฉ
  • ์‹œ๊ฐํ™”๋‚˜ ๋ชจ๋‹ˆํ„ฐ๋ง ์„œ๋น„์Šค๋ฅผ ์œ„ํ•ด Zipkin Distributed Tracing, Netflix API gateway ์ด์šฉ
    • ๋กœ๊ทธ ํ™•์ธ ๋“ฑ
  • ์žฅ์•  ๋ฐœ์ƒํ–ˆ์„ ๋•Œ ํšŒ๋ณต์„ฑ ํŒจํ„ด์„ ์œ„ํ•ด Hystrix ์ด์šฉ

Service Discovery

  • ์™ธ๋ถ€์—์„œ ๋‹ค๋ฅธ ์„œ๋น„์Šค๋“ค์ด ๋‹ค๋ฅธ micro service๋ฅผ ๊ฒ€์ƒ‰ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•˜๋Š” ๊ฐœ๋…
    • ์ผ์ข…์˜ ์ „ํ™”๋ฒˆํ˜ธ๋ถ€ ์ฑ…
    • key์™€ value๊ฐ€ ์ €์žฅ๋˜์–ด ์žˆ์Œ
    • ์–ด๋–ค ์„œ๋น„์Šค๊ฐ€ ์–ด๋”” ์œ„์น˜์— ์žˆ๋Š”์ง€ ์•Œ ์ˆ˜ ์žˆ์Œ
    • ๋“ฑ๋ก, ๊ฒ€์ƒ‰์˜ ๊ธฐ๋Šฅ ์ œ๊ณต

โ‡’ Spring Cloud Netflix Eureka ์‚ฌ์šฉํ•ด์„œ ๊ตฌํ˜„

  1. ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์ž์‹ ์ด ์ด์šฉํ•˜๊ณ  ์‹ถ์€ ์„œ๋น„์Šค์— ๋Œ€ํ•œ ์š”์ฒญ ์ •๋ณด๋ฅผ Load Balancer, Gateway API์—๊ฒŒ ์ „๋‹ฌ
  2. ๊ทธ ์š”์ฒญ ์ •๋ณด๊ฐ€ Service Discovery์— ์ „๋‹ฌ๋˜์–ด ๋‚ด๊ฐ€ ํ•„์š”ํ•œ ์ •๋ณด๊ฐ€ ์–ด๋”” ์žˆ๋ƒ ๋ฌผ์–ด๋ด„
  3. ๊ทธ ์„œ๋น„์Šค๋Š” ๋ช‡๋ฒˆ ์„œ๋ฒ„๋กœ ๊ฐ€์„ธ์š”~ ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
  4. ๊ทธ๋Ÿผ ๋‹ค์‹œ Load Balancer๊ฐ€ ์•Œ๋งž๋Š” ์„œ๋ฒ„์— ์š”์ฒญ๊ฐ’ ์ „์†ก, ๋ฐ˜ํ™˜๊ฐ’ ๋ฐ›๋Š”๋‹ค.
server:
  port: 8761

spring:
  application:
    name: discoveryservice

eureka:
  client:
    register-with-eureka: false
    fetch-registry: false
  • register-with-eureka: ์ž์‹ ์˜ ์ •๋ณด๋ฅผ ์ž์‹ ์—๊ฒŒ ๋“ฑ๋กํ•˜๋Š” ์ž‘์—….. ์˜๋ฏธ ์—†๊ธฐ ๋•Œ๋ฌธ์— false๋กœ.. ๊ทธ๋ƒฅ ์„œ๋ฒ„๋กœ๋งŒ ๊ธฐ๋™๋˜๋ฉด ๋จ
  • fetch-registry: ์ด ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๋‹ค๋ฅธ ์„œ๋น„์Šค์˜ endpoints์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ๋‹ค์šด๋กœ๋“œํ•˜๊ธฐ ์œ„ํ•ด ์œ ๋ ˆ์นด ์„œ๋ฒ„์— ์—ฐ๊ฒฐ์„ ์‹œ๋„ํ• ์ง€ ์—ฌ๋ถ€
    • ์œ ๋ ˆ์นด์— ๋“ฑ๋ก๋˜๋Š” ์„œ๋น„์Šค๋“ค์˜ ์ •๋ณด๋ฅผ ๊ฐฑ์‹ ํ•˜๊ธฐ ์œ„ํ•œ ์šฉ๋„!

https://github.com/spring-cloud/spring-cloud-release/wiki/Supported-Versions

Spring boot์™€ Eureka ๋ฒ„์ „ ๋งž์ถ”๊ธฐ!


Service Discovery

Eureka ์„œ๋ฒ„

  • ecommerce ํ”„๋กœ์ ํŠธ - EcommerceApplication.java
@SpringBootApplication
@EnableEurekaServer
public class EcommerceApplication {

    public static void main(String[] args) {
        SpringApplication.run(EcommerceApplication.class, args);
    }

}

user-service

  • user-service ํ”„๋กœ์ ํŠธ - UserServiceApplcation.java
@SpringBootApplication
@EnableDiscoveryClient
public class UserServiceApplication {

	public static void main(String[] args) {
		SpringApplication.run(UserServiceApplication.class, args);
	}

}

user-service ํ”„๋กœ์ ํŠธ๋ฅผ Eureka์— ๋“ฑ๋ก

  • user-service ํ”„๋กœ์ ํŠธ
server:
  port: 9001
spring:
  application:
    name: user-service
eureka:
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      defaultZone: http://127.0.0.1:8761/eureka

Untitled

user-service ํ”„๋กœ์ ํŠธ์˜ run - edit configurations

Untitled

Untitled

Untitled

Untitled

  • -D : ์˜ต์…˜ ์ถ”๊ฐ€ํ•˜๊ฒ ๋‹ค

-D : ์˜ต์…˜ ์ถ”๊ฐ€ํ•˜๊ฒ ๋‹ค

-D : ์˜ต์…˜ ์ถ”๊ฐ€ํ•˜๊ฒ ๋‹ค

Untitled

๋˜๋Š”, ํ„ฐ๋ฏธ๋„์—์„œ

./gradlew bootRun --args='--server.port=9003'

maven์ด ์•„๋‹ˆ๋ผ gradle๋กœ ์ง„ํ–‰์ค‘์ด์‹  ๋ถ„๋“ค - ์ธํ”„๋Ÿฐ | ์งˆ๋ฌธ & ๋‹ต๋ณ€

Untitled

user-service 3๊ฐœ๊ฐ€ ์‹คํ–‰ ์ค‘!!!

ํ•˜๋‚˜ ๋”โ€ฆ

Untitled

./gradlew clean build
./gradlew build
./gradlew bootRun --args='--server.port=9004'

Untitled

user-service 4๊ฐœ ์‹คํ–‰ ์ค‘!!


๊ทผ๋ฐ ์ด๋ ‡๊ฒŒ ๊ณ„์† ํฌํŠธ ๋ฐ”๊ฟ”์ฃผ๋Š” ๊ฑฐ ๊ท€์ฐฎ์Œ..

server:
  port: 0
spring:
  application:
    name: user-service
eureka:
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      defaultZone: http://127.0.0.1:8761/eureka

port: 0๋ฒˆ โ†’ ๋žœ๋ค์œผ๋กœ

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๋ช‡๊ฐœ๋ฅผ ์‹คํ–‰ํ•ด์„œ ์ฃ„๋‹ค ๋žœ๋คํฌํŠธ๊ฐ€ ๋ถ€์—ฌ๋ผ์„œ ์‹คํ–‰๋˜๋”๋ผ๋„ 0๋ฒˆ ํฌํŠธ๋ฐ–์— ์•ˆ๋œธ (์œ ๋ ˆ์นด์—)

server:
  port: 0
spring:
  application:
    name: user-service
eureka:
  instance:
    instance-id: ${spring.cloud.client.hostname}:${spring.application.instance_id:${random.value}}
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      defaultZone: http://127.0.0.1:8761/eureka

Untitled

์ €๋ ‡๊ฒŒ yml ์ˆ˜์ •ํ•ด์ฃผ๋ฉด ์ธ์Šคํ„ด์Šค ์•„์ด๋”” ์ถ”๊ฐ€๋ผ์„œ ๋ถ„๋ฆฌ๋ผ์„œ ๋‚˜์˜ด!!

scaling ์ž‘์—… ํ•ด์ฃผ๊ธฐ ์œ„ํ•ด ์—ฌ๋Ÿฌ ์ธ์Šคํ„ด์Šค ๋งŒ๋“ค๊ณ  ๊ฐ๊ฐ์˜ ์ธ์Šคํ„ด์Šค ์„œ๋น„์Šค๋Š” ์œ ๋ ˆ์นด์— ์ž˜ ๋“ฑ๋ก๋จ!

๋กœ๋“œ ๋ฐธ๋Ÿฐ์Šค!!!


API Gateway Service

์‚ฌ์šฉ์ž๊ฐ€ ์„ค์ •ํ•œ ๋ผ์šฐํŒ… ์„ค์ •์— ๋”ฐ๋ผ ๊ฐ๊ฐ ์—”๋“œํฌ์ธํŠธ๋กœ ํด๋ผ์ด์–ธํŠธ๋ฅผ ๋Œ€์‹ ํ•ด ์š”์ฒญํ•˜๊ณ  ์‘๋‹ต์„ ๋ฐ›์œผ๋ฉด ๋‹ค์‹œ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ์ „๋‹ฌํ•ด์ฃผ๋Š” ํ”„๋ก์‹œ ์—ญํ• ์„ ํ•จ

์‹œ์Šคํ…œ ๋‚ด๋ถ€ ๊ตฌ์กฐ๋Š” ์ˆจ๊ธฐ๊ณ  ์™ธ๋ถ€์— ์š”์ฒญ์— ๋Œ€ํ•ด ์ ์ ˆํžˆ ๊ฐ€๊ณตํ•ด ์‘๋‹ตํ•  ์ˆ˜ ์žˆ๋Š” ์žฅ์ ์ด ์žˆ๋‹ค.

Untitled

MS๊ฐ€ ๋…๋ฆฝ์ ์œผ๋กœ ๋นŒ๋“œ๊ฐ€ ๋˜๊ณ  ๋ฐฐํฌ๊ฐ€ ๋  ์ˆ˜ ์žˆ๋Š” ์žฅ์ .

ํ•˜์ง€๋งŒ Client side์—์„œ๋Š”โ€ฆ

ํด๋ผ์ด์–ธํŠธ ์‚ฌ์ด๋“œ์—์„œ ๋งˆ์ดํฌ๋กœ์„œ๋น„์Šค์˜ ์ฃผ์†Œ๋ฅผ ์ง์ ‘ ์ด์šฉํ•ด์„œ, ์ด๊ฑธ ์—”๋“œํฌ์ธํŠธ. ์—”๋“œํฌ์ธํŠธ๋ฅผ ์ง์ ‘ ํ˜ธ์ถœ ํ–ˆ์„ ๊ฒฝ์šฐ client side์— ์žˆ๋Š” ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜๋„ ๊ฐ™์ด ์ˆ˜์ • ๋ฐฐํฌ๊ฐ€ ๋˜์–ด์•ผํ•จ

์ด๋Ÿฌ๋‹ค ๋ณด๋‹ˆ ๋‹จ์ผ ์ง„์ž…์ ์„ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ํ˜•ํƒœ๋กœ์จ ๊ฐœ๋ฐœํ•˜๋Š” ๊ฒŒ ํ•„์š”.

์„œ๋ฒ„๋‹จ(๋ฐฑ์—”๋“œ)์— ์ค‘๊ฐ„์— ๊ฒŒ์ดํŠธ์›จ์ด ์—ญํ• ์„ ํ•ด์ค„์ˆ˜์žˆ๋Š” ์ผ์ข…์˜ ์ง„์ž…๋กœ, ๊ฒŒ์ดํŠธ์›จ์ด๋ฅผ ๋‘๊ณ  ๊ฐ๊ฐ์˜ ms์— ์š”์ฒญ๋˜๋Š” ๋ชจ๋“  ์ •๋ณด์— ๋Œ€ํ•ด ์–˜๊ฐ€ ์ผ๊ด„์ ์œผ๋กœ ์ฒ˜๋ฆฌ

๋ชจ๋ฐ”์ผ์•ฑ๋„ ์ƒ๊ด€์—†์Œ.

Untitled

์ง์ ‘์ ์œผ๋กœ ms๋ฅผ ํ˜ธ์ถœํ•˜์ง€ ์•Š๊ณ  ํด๋ผ์ด์–ธํŠธ๋Š” ๊ฒŒ์ดํŠธ์›จ์ด๋งŒ ์ƒ๋Œ€ํ•จ.

๋”ฐ๋ผ์„œ ๊ฒŒ์ดํŠธ์›จ์ด์—์„œ ํ•„์š”๋กœ ํ•˜๋Š” ์ •๋ณด๋ฅผ ๋ณ€๊ฒฝํ•˜๊ณ  ๊ฐฑ์‹ ํ•˜๋Š” ์ž‘์—…์ด ์ˆ˜์›”ํ•˜๋‹น.

๋‹จ์ผ ์ง„์ž…์ ์—์„œ ์ฒ˜๋ฆฌ(๊ฒŒ์ดํŠธ์›จ์ด ์—ญํ• )

  • ์ธ์ฆ ๋ฐ ๊ถŒํ•œ ๋ถ€์—ฌ
  • ๋งˆ์ดํฌ๋กœ์„œ๋น„์Šค ๊ฒ€์ƒ‰ ํ†ตํ•ฉ
  • ์‘๋‹ต ์บ์‹ฑ
  • ์ •์ฑ…, ํšŒ๋กœ ์ฐจ๋‹จ๊ธฐ ๋ฐ QoS ๋‹ค์‹œ ์‹œ๋„
  • ์†๋„ ์ œํ•œ
  • ๋ถ€ํ•˜ ๋ถ„์‚ฐ
    • ms๊ฐ€ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ํ•˜๋‚˜์˜ ์„œ๋น„์Šค์˜ ๋‚ด์šฉ์„ ์„ธ๊ฐœ์˜ ์ธ์Šคํ„ด์Šค๊ฐ€ ๋‚˜๋ˆ ์„œ ์ž‘์—…ํ–ˆ๋‹ค๊ณ  ๊ฐ€์ •
    • ms1, ms2, ms3
    • ๊ทธ๋Ÿผ ์–ด๋””๋กœ ์š”์ฒญ ๋ณด๋‚ผ์ง€ ํŒ๋‹จ
  • ๋กœ๊น…(๊ฐ๊ฐ์˜ ms๊ฐ€ ํ•˜๋‚˜์˜ solution์„ ์ด์šฉํ•ด ๋กœ๊ทธ๋ฅผ ๋ชจ์•„๋†“์„์ˆ˜๋„์žˆ์Œ. ๋ฌผ๋ก  ๋กœ๊ทธ๋งŒ ์ „๋ฌธ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•ด์ค„์ˆ˜ ์ž‡๋Š” ์‹œ์Šคํ…œ (ex. ELK)์จ์„œ ์ฒ˜๋ฆฌํ•  ์ˆ˜๋„ ์žˆ๋‹ค.)
  • ์ถ”์ (์–ด๋–ค ms๊ฐ€ ๋ˆ„๊ตฌ์— ์˜ํ•ด ํ˜ธ์ถœ, ์ง„์ž…์ ์ด ๋ˆ„๊ตฌ, ์–ด๋””๋กœ ์ด๋™ ๋“ฑ๋“ฑ - ์ถ”์  ๊ด€๊ณ„ ์ค‘์š”ํ•จ!!)
  • ์ƒ๊ด€ ๊ด€๊ณ„
  • ํ—ค๋”, ์ฟผ๋ฆฌ ๋ฌธ์ž์—ด ๋ฐ ์ฒญ๊ตฌ ๋ณ€ํ™˜
  • IP ํ—ˆ์šฉ ๋ชฉ๋ก์— ์ถ”๊ฐ€
    • ๋ฐฉํ™”๋ฒฝ, ํ”„๋ก์‹œ ์—ญํ•  ํ•ด์ฃผ๋Š” ๊ฒŒ์ดํŠธ์›จ์ด!

Netflix Ribbon

  • Spring Cloud์—์„œ์˜ MSA๊ฐ„ ํ†ต์‹ 

    1. RestTemplate

      • ํ•˜๋‚˜์˜ ์›น ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ๋‹ค๋ฅธ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ์ž์ฃผ ์‚ฌ์šฉ๋˜์—ˆ๋˜ API

      Untitled

    2. Feign Client

      • ์ถ”๊ฐ€์ ์œผ๋กœ ํ˜ธ์ถœํ•˜๊ณ  ์‹ถ์€ ์„œ๋น„์Šค @FeignClient๋กœ ๋“ฑ๋ก
        • ์ง์ ‘์ ์ธ ์„œ๋ฒ„ ์ฃผ์†Œ, ํฌํŠธ ๋ฒˆํ˜ธ ์—†์ด ms์ด๋ฆ„ ๊ฐ€์ง€๊ณ  ํ˜ธ์ถœ ๊ฐ€๋Šฅ

      Untitled

      • user๋ผ๋Š” ์„œ๋น„์Šค ์•ˆ์— stores๋ผ๋Š” ์„œ๋น„์Šค๊ฐ€ ์ž์‹ ์ด ๊ฐ€์ง€๊ณ  ์žˆ๋Š” API ์ฒ˜๋Ÿผ ์ž์œ ๋กญ๊ฒŒ ํ˜ธ์ถœํ•ด์„œ ์‚ฌ์šฉ ๊ฐ€๋Šฅ
  • Ribbon: Client side Load Balancer

    • ์ดˆ์ฐฝ๊ธฐ์—๋Š” ๋กœ๋“œ ๋ฐธ๋Ÿฐ์Šค๋ฅผ ํ•ด์ฃผ๊ธฐ ์œ„ํ•ด ๋ฆฌ๋ณธ์ด๋ผ๋Š” ์„œ๋น„์Šค ์ œ๊ณตํ•จ
    • ๋ฌธ์ œ: ๋ฆฌ๋ณธ์ด๋ผ๋Š” ์„œ๋น„์Šค ์ž์ฒด๋Š” ์ตœ๊ทผ์— Functional API(react java) - ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๊ฐ€ ์ž˜ ์•ˆ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์ตœ๊ทผ์— ์ž˜ ์‚ฌ์šฉx
    • ์„œ๋น„์Šค ์ด๋ฆ„์œผ๋กœ ํ˜ธ์ถœ
      • ํด๋ผ์ด์–ธํŠธ ์•ˆ์—์„œ ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ ํ˜ธ์ถœ
    • Health Check
      • ํ•ด๋‹น ์„œ๋น„์Šค ์ž˜ ์ž‘๋™ ์ค‘์ธ์ง€ ํ™•์ธ
    • service 3๊ฐœ ์žˆ๋‹ค๊ณ  ๊ฐ€์ •
      • ํด๋ผ์ด์–ธํŠธ ๋‚ด๋ถ€์— ribbon์„ ๋‘๊ณ  (์ด๋•Œ๋Š” api gateway ์‚ฌ์šฉx) ์ด๊ฑธ๋กœ ์ด๋™ํ•˜๊ณ ์žํ•˜๋Š” ms์„œ๋น„์Šค์˜ ์ฃผ์†Œ๊ฐ’ ๊ด€๋ฆฌ
      • Client Side์—์„œ!!!!!
      • ์žฅ์ : ์™ธ๋ถ€์— ์žˆ๋Š” ๋งˆ์ดํฌ๋กœ ์„œ๋น„์Šค๋ฅผ ํ˜ธ์ถœํ•˜๊ธฐ ์œ„ํ•ด ip์™€ ํฌํŠธ๋ฒˆํ˜ธ๋ฅผ ๋ช…์‹œํ•˜๋Š” ๊ฒŒ ์•„๋‹ˆ๋ผ, ms์˜ ์ด๋ฆ„๋งŒ ๊ฐ€์ง€๊ณ  ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์Œ
    • ์ตœ๊ทผ์—๋Š” ์‚ฌ์šฉX

Netflix Zuul ๊ตฌํ˜„

Untitled

  • ๊ตฌ์„ฑ
    • ํ…Œ์ŠคํŠธ
      • First Service
      • Second Service
        • Spring Boot: 2.3.8
    • Netflix Zuul โ†’ Gateway
      • ์—ญํ• 
        • Routing
        • API gateway
  • ์–˜๋„ ๋” ์ด์ƒ ์‚ฌ์šฉ X

Spring Cloud - Spring Boot ๋ฒ„์ „ ๋งž์ถ”๊ธฐ

Spring Cloud

server:
  port: 8000
spring:
  application:
    name: my-zuul-service
zuul:
  routes:
    first-service:
      path: /first-service/**
      url: http://localhost:8081
    second-service:
      path: /second-service/**
      url: http://localhost:8082

zuul์ด๋ผ๋Š” ์„œ๋น„์Šค๊ฐ€ 8000์œผ๋กœ first-service/**๋ผ๋Š” ์š”์ฒญ์ด ๋“ค์–ด์˜ค๋ฉด

8081๋กœ ํฌ์›Œ๋”ฉ ์‹œํ‚จ๋‹ค.

http://localhost:8000/first-service/welcome


Spring Cloud Gateway - ๊ธฐ๋ณธ

server:
  port: 8000
eureka:
  client:
    register-with-eureka: false
    fetch-registry: false
    service-url:
      defaultZone: http://localhost:8761/eureka

spring:
  application:
    name: gateway-service
  cloud:
    gateway:
      routes:
        - id: first-service
          uri: http://localhost:8081/
          predicates:
            - Path=/first-service/**
        - id: second-service
          uri: http://localhost:8082/
          predicates:
            - Path=/second-service/**
  • Zuul๊ณผ๋Š” ๋‹ค๋ฅด๊ฒŒ Controller์— ๋งตํ•‘์„ ํ•ด์ค˜์•ผ ํ•œ๋‹ค.
    • http://localhost:8081/first-service/** ์ด๋ ‡๊ฒŒ ๊ฐ€๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

Untitled

  • Zuul ๋Œ€์‹  Spring Cloud Gateway ์จ๋ณด์ž.
    • predicates: ์กฐ๊ฑด
      • first-service๋ผ๋Š” ์š”์ฒญ ๋“ค์–ด์˜ค๋ฉด 8081๋กœ ๊ฐ€๊ฒ ๋‹ค.

Zuul vs Spring Cloud Gateway

  • Spring Cloud Gateway: ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ ์ œ๊ณต

Spring Cloud Gateway - Filter

Untitled

  • .yml ๋ถ€๋ถ„๋Œ€์‹  FilterConfig.java ์‚ฌ์šฉํ•ด๋ณด๊ธฐ
server:
  port: 8000
eureka:
  client:
    register-with-eureka: false
    fetch-registry: false
    service-url:
      defaultZone: http://localhost:8761/eureka

spring:
  application:
    name: gateway-service
#  cloud:
#    gateway:
#      routes:
#        - id: first-service
#          uri: http://localhost:8081/
#          predicates:
#            - Path=/first-service/**
#        - id: second-service
#          uri: http://localhost:8082/
#          predicates:
#            - Path=/second-service/**
  • FilterConfig.java
public RouteLocator gateWayRoutes(RouteLocatorBuilder builder) {
        return builder.routes()
                .route(r -> r.path("/first-service/**") //์ด ์š”์ฒญ ๋“ค์–ด์˜ค๋ฉด
                        .filters(f-> f.addRequestHeader("first-request", "first-request-header")
                                .addResponseHeader("first-response", "first-response-header"))
                        .uri("http://localhost:8081/")) //์—ฌ๊ธฐ๋กœ ์ด๋™ํ•˜๊ฒ ๋‹ค
                .route(r -> r.path("/second-service/**")
                        .filters(f-> f.addRequestHeader("second-request", "second-request-header")
                                .addResponseHeader("second-response", "second-response-header"))
                        .uri("http://localhost:8082/"))
                .build();
    }

Untitled


๋‹ค๋ฅธ ๋ฐฉ๋ฒ•

  • ํ•„ํ„ฐ๋ฅผ yml์—์„œ ๋„ฃ๊ธฐ
server:
  port: 8000
eureka:
  client:
    register-with-eureka: false
    fetch-registry: false
    service-url:
      defaultZone: http://localhost:8761/eureka

spring:
  application:
    name: gateway-service
  cloud:
    gateway:
      routes:
        - id: first-service
          uri: http://localhost:8081/
          predicates:
            - Path=/first-service/**
          filters:
            - AddRequestHeader=first-request, first-request-header2
            - AddResponseHeader=first-response, first-response-header2
        - id: second-service
          uri: http://localhost:8082/
          predicates:
            - Path=/second-service/**
          filters:
            - AddRequestHeader=second-request, second-request-header2
            - AddResponseHeader=second-response, second-response-header2
  • FilterConfig.java ํŒŒ์ผ์— ์–ด๋…ธํ…Œ์ด์…˜ ๋‹ค ์ฃผ์„ ๊ฑธ์–ด์คŒ ์•ˆ์“ธ๋ ค๊ณ 

Untitled

  • .yml์— ์ถ”๊ฐ€ํ•œ key-value response ์ž˜ ํ™•์ธ๋œ๋‹น!!

Custom Filter ๋งŒ๋“ค๊ธฐ

@Component
@Slf4j
public class CustomFilter extends AbstractGatewayFilterFactory<CustomFilter.Config> { //์šฐ๋ฆฌ๊ฐ€ ์ง€๊ธˆ ๋งŒ๋“ค๊ณ  ์žˆ๋Š” CustomFilter์˜ Config
    public CustomFilter() {
        super(Config.class);
    }

    @Override
    public GatewayFilter apply(Config config) { //์šฐ๋ฆฌ๊ฐ€ ์ ์šฉํ•˜๊ณ  ์‹ถ์€ ๋‚ด์šฉ
        // Custom Pre Filter
        return (exchange, chain) -> {
            ServerHttpRequest request = exchange.getRequest(); //exchage๋กœ๋ถ€ํ„ฐ request ๋ฐ›์•„์˜ค๊ธฐ
            ServerHttpResponse response = exchange.getResponse(); //response ๋ฐ›์•„์˜ค๊ธฐ

            log.info("Custom PRE filter: request id -> {}", request.getId());

            // Custom Post Filter - ์ฒ˜๋ฆฌ ํ›„
            return chain.filter(exchange).then(Mono.fromRunnable(() -> { //chain์— ์—ฐ๊ฒฐ -> ํ•„ํ„ฐ ์ถ”๊ฐ€
                // Mono : ๋ฐ์ดํ„ฐ ํƒ€์ž… ํ•˜๋‚˜ ์ค„ ๊ฑฐ์ž„
                // ๋น„๋™๊ธฐ ๋ฐฉ์‹์—์„œ ๋‹จ์ผ๊ฐ’์ผ ๋•Œ ์‚ฌ์šฉ, response ํ•  ๋•Œ response status code๋ฅผ ์ถœ๋ ฅ
                log.info("Custom POST filter: response code -> {}", response.getStatusCode());
            }));
        };
    }

    public static class Config {
        // Put the configuration properties
    }
}

Untitled

  • CustomFilter ๋“ฑ๋ก

Untitled

GlobalFilter

  • ํ˜„์žฌ first-service, second-service์— ๋™์ผํ•œ CustomFilter ์ ์šฉ ์ค‘.
  • ์ด๋ ‡๊ฒŒ ๋ผ์šฐํŒ… ์ •๋ณด๋งˆ๋‹ค ๋“ฑ๋กํ•˜์ง€๋ง๊ณ 
  • ๊ณตํ†ต์ ์ธ ํ•„ํ„ฐ ์žˆ์œผ๋ฉด ํ•œ๋ฒˆ์— ๋“ฑ๋กํ•˜์ž
  • ์ „์ฒด ๋ผ์šฐํ„ฐ์— ์ ์šฉ!
    • ๊ฐ€์žฅ ๋จผ์ € ์‹คํ–‰๋˜๊ณ  ๊ฐ€์žฅ ๋‚˜์ค‘์— ์ข…๋ฃŒ๋จ.
	.
	.
	.
spring:
  application:
    name: gateway-service
  cloud:
    gateway:
      default-filters:
        - name: GlobalFilter
          args:
            baseMessage: Spring Cloud Gateway GlobalFilter
            preLogger: true
            postLogger: true
      routes:
        - id: first-service
          uri: http://localhost:8081/
          predicates:
            - Path=/first-service/**
          filters:
#            - AddRequestHeader=first-request, first-request-header2
#            - AddResponseHeader=first-response, first-response-header2
            - CustomFilter
     	.
	.
	.

Untitled

  • ๊ทผ๋ฐ ์ €๋ ‡๊ฒŒ yml์— ๊ฐ’์„ ์ง์ ‘ ํƒ€์ดํ•‘ ํ•˜๋ฉด ๊ท€์ฐฎ๋‹ค.
    • ์ถ”ํ›„์—โ€ฆ

LoggingFilter

  • ์ผ์ข…์˜ ์ปค์Šคํ…€ ํ•„ํ„ฐ

Untitled

Untitled


Spring Cloud Gateway - Eureka ์—ฐ๋™

Load Balancer

Untitled

์„œ๋ฒ„ โ†’ ๊ฒŒ์ดํŠธ์›จ์ด โ†’ my-first-service, my-second-service๋กœ ์—ฐ๊ฒฐ!!

1. ์„œ๋ฒ„ (DiscoveryService)

@SpringBootApplication
@EnableEurekaServer
public class DiscoveryServiceApplication {

    public static void main(String[] args) {
        SpringApplication.run(DiscoveryServiceApplication.class, args);
    }

}
  • @EnableEurekaServer ์ถ”๊ฐ€!! - ์„œ๋ฒ„๋กœ ๋“ฑ๋ก

2. ๊ฒŒ์ดํŠธ์›จ์ด(gateway-service)

@SpringBootApplication
@EnableEurekaClient
public class GatewayServiceApplication {

    public static void main(String[] args) {
        SpringApplication.run(GatewayServiceApplication.class, args);
    }

}
  • @EnableEurekaClient ์ถ”๊ฐ€!! - ํด๋ผ์ด์–ธํŠธ๋กœ ๋“ฑ๋ก
server:
  port: 8000
eureka:
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      defaultZone: http://localhost:8761/eureka
  • register-with-eureka: true โ†’ ์œ ๋ ˆ์นด์— ๋“ฑ๋ก

3. ์„œ๋ฒ„๋“คโ€ฆ (my-first-service, my-second-service)

  • ์œ„์— ๊ฒŒ์ดํŠธ์›จ์ด๋ž‘ ๋˜‘๊ฐ™์ด ์œ ๋ ˆ์นด ํด๋ผ์ด์–ธํŠธ๋กœ ๋“ฑ๋กํ•ด์คŒ

Untitled

์—ฌ๊ธฐ ์ค‘โ€ฆ

Untitled

์ด ์ด๋ฆ„!!!!

์ด์ œ uri ์•ˆ ์“ฐ๊ณ  ์ € Application ์ด๋ฆ„์œผ๋กœ ๋กœ๋“œ๋ฐธ๋Ÿฐ์‹ฑํ•  ๊ฒƒ์ž„

routes:
        - id: first-service
          uri: lb://MY-FIRST-SERVICE
          predicates:
            - Path=/first-service/**
          filters:
            - CustomFilter
        - id: second-service
          uri: lb://MY-SECOND-SERVICE
          predicates:
            - Path=/second-service/**
  • uri ๋ฐ”๊ฟ”์ฃผ๊ธฐ
    • uri: lb://MY-FIRST-SERVICE
    • uri: lb://MY-SECOND-SERVICE

Untitled

๋งŒ์•ฝ ์ด ์ƒํƒœ๋ผ๋ฉดโ€ฆ

๊ฒŒ์ดํŠธ์›จ์ด์—์„œ uri: lb://MY-FIRST-SERVICE ์ด ์š”์ฒญ์„ ๋ฐ›์•˜์„ ๋•Œ 8081 ๋˜๋Š” 9091 ์ด ์ค‘ ์•„๋ฌด ๊ณณ์ด๋‚˜ ๊ฐˆ ๊ฒƒ์ด๋‹ค.

โ‡’ ๊ทธ๋Ÿผ ์–ด๋””๋กœ ์š”์ฒญ ๊ฐ”๋Š” ์ง€ ์•Œ ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•!!

server:
  port: 0
spring:
  application:
    name: my-first-service

eureka:
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      defaultZone: http://localhost:8761/eureka
  instance:
    instance-id: ${spring.application.name}:${spring.application.instance_id:${random.value}}
  • ํฌํŠธ๋ฒˆํ˜ธ: 0
    • ๋žœ๋ค ํฌํŠธ๋ฒˆํ˜ธ ๋ถ€์—ฌ ์œ„ํ•ด
  • ์ธ์Šคํ„ด์Šค ์ถ”๊ฐ€
@GetMapping("/check")
    public String check(HttpServletRequest request) {
        log.info("Server port={}", request.getServerPort());
        return String.format("Hi, there. This is a mesasge from First Service on PORT %s", env.getProperty("local.server.port"));
    }
  1. request.getServerPort()
  2. env.getProperty("local.server.port")

Untitled

  • round-robin ๋ฐฉ์‹์œผ๋กœ ๋ฒˆ๊ฐˆ์•„๊ฐ€๋ฉด์„œ ํ˜ธ์ถœํ•ด์ค€๋‹น.

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages