Spring에서 MSA를 사용하는 경우
서버는 고가용성을 가질 필요가 있고, 하나의 서버가 터졌을 때
다른 서비스까지 되지 않는 로직은 사이트의 규모가 커질수록 경제적 손해가 큽니다.
Netflix에서 개발된 서비스 디스커버리 툴이 공개되고 나서 Eureka는 다음과 같은 장점을 가집니다.
1. 서비스 디스커버리 - 수십, 수백개의 서버의 url을 모두 외워서 적용시키는 것은 개발적 loss가 큽니다. 따라서 서버이름을 통해 lb:severname을 통해 맵핑을 시킨다면 해당 서버의 위치를 조회할 수 있습니다.
2. 로드 벨런싱 - eureka서버는 상태를 주기적으로 체크합니다. 응답하지 않는 서비스에 있어서 장애 서비스에 요청을 보내는 것을 방지할 수 있습니다.
3. 자동 장애 복구 - 서비스가 장애 상태일 경우 서비스에 응답을 자동으로 '사용할 수 없는 상태' 로 응답받아 전체 시스템의 안정성을 높일 수 있습니다.
저는 우선, spring cloud로 서버 배포 환경을 구축할 필요가 있어서 미리 서버를 kubnetes를 띄우기 전에 spring cloud로 띄워보았습니다.
plugins {
id 'java'
id 'org.springframework.boot' version '3.1.4'
id 'io.spring.dependency-management' version '1.1.3'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
java {
sourceCompatibility = '17'
}
repositories {
mavenCentral()
}
ext {
set('springCloudVersion', "2022.0.4")
}
dependencies {
implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-server'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
}
}
tasks.named('test') {
useJUnitPlatform()
}
유레카 서버의 gradle파일입니다. dependency와 cloud버전 선택을 통해 dependency를 설정해 주었습니다.
@EnableEurekaServer
@SpringBootApplication
public class EurekaApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaApplication.class, args);
}
}
어플리케이션 설정입니다. 이렇게 간단한 구축으로 유레카서버를 구현할 수 있습니다.
server:
port: 8761
spring:
application:
name: discovery-service
eureka:
client:
register-with-eureka: false
fetch-registry: false
application.yaml파일 입니다.
유레카를 구축 했으면 그것을 잰킨스를 통해 배포하고,
다음은 각각의 서비스에 api를 찾아주는 gateway를 만들어 보겠습니다.
plugins {
id 'java'
id 'org.springframework.boot' version '3.1.4'
id 'io.spring.dependency-management' version '1.1.3'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
java {
sourceCompatibility = '17'
}
repositories {
mavenCentral()
}
ext {
set('springCloudVersion', "2022.0.4")
}
dependencies {
implementation 'org.springframework.cloud:spring-cloud-starter-gateway'
implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
}
}
tasks.named('test') {
useJUnitPlatform()
}
gateway gradle파일입니다. gateway가 dependency에 추가 됩니다.
application은 eureka와 동일하게 만들어 줍니다.
그리고 application.yaml파일에 각각의 url을 연결합니다.
server:
port: 8000
spring:
application:
name: gateway-service
cloud:
gateway:
httpclient:
connect-timeout: 50000
response-timeout: 50000
default-filters:
- DedupeResponseHeader=Access-Control-Allow-Origin Access-Control-Allow-Credentials
globalcors:
cors-configurations:
'[/**]':
allowedOrigins:
- 'http://localhost:3000'
allow-credentials: true
allowedHeaders: '*'
allowedMethods:
- PUT
- GET
- POST
- DELETE
- PATCH
- OPTIONS
routes:
- id: user-service # server name
# uri: http://localhost:9000 # server ip
uri: lb://user-service
predicates:
- Path=/api/v1/users/** # root path after gateway path
- id: etc-service
# uri: http://localhost:9001
uri: lb://etc-service
predicates:
- Path=/api/v1/etc/**
- id: community-service
uri: lb://community-service
predicates:
- Path=/api/v1/community/**
- id: board-service
uri: lb://board-service
predicates:
- Path=/api/v1/board/**
eureka:
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://localhost:8761/eureka/ # all managed by eureka
uri를 통해서 받아오는 경우 실제 서비스를 통해 연결하게 된다면 서버가 다운되거나 url이 변경되는 경우 수동으로 변경을 해줘야합니다. 하지만 lb라는 기능을 사용하게 되면 해당 서버의 존재 여부를 판단하고 그 url로 연결 시켜주는 역할을 해줍니다. 그리고 path또한 url이 아닌 end-point로 분배할 수 있게 됩니다.
jenkins에 gateway도 배포를 하고,
server:
port: 0
spring:
profiles:
active: local
application:
name: USER-SERVICE // 이것이 gateway의 이름으로 연동된다.
eureka:
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://<유레카서버 컨테이너 이름>/eureka/
instance:
instance-id: ${spring.application.name}:${spring.application.instance_id:${random.value}}
위와 같이 user라는 서버에서 application.yaml에서 name을 user-service값을 넣어서 맵핑해줍니다.
그리고 service-url에 고정 url로 만든 유레카 서버를 맵핑하면 됩니다.
이렇게 구성을 하면 간단하게 msa환경을 경험할 수 있는 서버를 배포할 수 있게 됩니다.
server.port : 0 으로 하면 임의의 값으로 배포 됩니다. 그리고 port 포워딩 된 것은 eureka에 등록되서 mapping되게 됩니다.
http://<server>:8761에 들어가서 확인해보면 연결된 서버 개수와 맵핑된 서버명을 알수 있습니다.
이렇게 연결된 것을 확인할 수 있습니다.
'기술 스텍 > Spring' 카테고리의 다른 글
IntelliJ 단축키(mac) (0) | 2024.11.28 |
---|---|
JPA에서 IDENTITY상태일때, persist할 때 DBMS에 반영되는가? (0) | 2024.06.17 |
SpringBoot(1) DI (0) | 2023.01.24 |