반응형
API 게이트웨이
# build.gradle
implementation 'org.springframework.cloud:spring-cloud-starter-gateway:4.2.0'
# application.yml
spring:
application:
name: gateway
cloud:
gateway:
routes:
- id: 332-project-management-service
uri: http://127.0.0.1:8081
predicates:
- Path=/project-management/**
filters:
- StripPrefix=1
- id: 332-service-desk
uri: http://127.0.0.1:8082
predicates:
- Path=/service-desk/**
filters:
- StripPrefix=1
server:
port: 8080
- `Spring Cloud Gateway`를 사용했다.
- `uri`에 `localhost`를 입력할 경우 도메인을 인식 못하는 현상 발생
- `predicates` 키를 통해 경로 엔드포인트 설정
- `filters` 키의 `StripPrefix=1` 값을 통해 `predicates` 키에서 설정한 엔드포인트의 `/**`을 실제 API 요청 경로로 지정
- 가령 `http://localhost:8080/project-management/project`로 `POST` 따위의 요청이 들어오면 `API` 게이트웨이가 요청을 `http://localhost:8081/project`로 리다이렉트 한다.
- 왜 쓰는가?
- ⇒ `JWT` 따위의 인증 및 인가를 전담할 수 있다.
⇒ 너무 많은 요청을 보내는 클라이언트를 차단 및 제어 가능
⇒ `API` 버전 관리 가능
⇒ 서비스 별 상이한 `API` 계약을 표준화하여 외부에 제공
- ⇒ `JWT` 따위의 인증 및 인가를 전담할 수 있다.
ELK + Logback
# docker-compose.yml
services:
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:7.17.18
container_name: elasticsearch
environment:
- discovery.type=single-node
- ES_JAVA_OPTS=-Xms512m -Xmx512m
volumes:
- esdata:/usr/share/elasticsearch/data
ports:
- "9200:9200"
networks:
- efk
kibana:
image: docker.elastic.co/kibana/kibana:7.17.18
container_name: kibana
ports:
- "5601:5601"
environment:
- ELASTICSEARCH_HOSTS=http://elasticsearch:9200
depends_on:
- elasticsearch
networks:
- efk
logstash:
image: docker.elastic.co/logstash/logstash:7.17.18
container_name: logstash
volumes:
- ./logstash/config/logstash.yml:/usr/share/logstash/config/logstash.yml
- ./logstash/pipeline:/usr/share/logstash/pipeline
- ./sentinel-app/logs:/app/logs
ports:
- "5044:5044"
- "9600:9600"
depends_on:
- elasticsearch
networks:
- efk
gateway:
build:
context: ./sentinel-app
container_name: sentinel-app
ports:
- "8080:8080"
volumes:
- ./sentinel-app/logs:/app/logs
networks:
- efk
volumes:
esdata:
networks:
efk:
# logstash.yml
http.host: "0.0.0.0"
xpack.monitoring.enabled: false
# logstash.conf
input {
file {
path => "/app/logs/*.log"
start_position => "beginning"
sincedb_path => "/dev/null"
codec => json
}
}
filter {
mutate {
add_field => {
"log_message" => "%{message}"
"server_role" => "gateway"
}
remove_field => ["parsed", "host", "path", "message"]
}
}
output {
elasticsearch {
hosts => ["http://elasticsearch:9200"]
index => "sentinel-logs-%{+YYYY.MM.dd}"
}
stdout {
codec => rubydebug
}
}
# logback-spring.xml
<configuration>
<include resource="net/logstash/logback/logback.xml"/>
<property name="LOG_PATH" value="./logs"/>
<appender name="JSON_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_PATH}/app-%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder class="net.logstash.logback.encoder.LogstashEncoder">
<fieldNames>
<timestamp>@timestamp</timestamp>
<level>level</level>
<logger>logger</logger>
<thread>thread</thread>
<message>message</message>
</fieldNames>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="JSON_FILE"/>
</root>
</configuration>
- 우선 `Logback`을 사용하여 로그 파일을 생성한다.
- `<include resource="net/logstash/logback/logback.xml"/>` 라인을 통해 로그스태시에 맞는 `JSON` 형식의 로그 파일을 출력한다.
- `<encoder class="net.logstash.logback.encoder.LogstashEncoder"> ... </encoder>` 라인을 통해 로그의 각 항목을 나타낸다.
- 이 항목들은 엘라스틱서치에서 필터링 할 수 있는 메타데이터가 되는 것이다.
- `Logstash`는 로그 파일을 읽어 엘라스틱서치로 전달한다.
- `logstash.yml`의 `http.host` 키를 통해 타 서버에서도 로그를 전송할 수 있는데, `0.0.0.0`은 사실 보안 측면에서 조금 위험하다.
- `logstash.conf` 설정을 통해 가공 및 필터링하여 인덱스로 생성 및 데이터를 주입한다.
- 위 화면에서 로그 파일과 동일한 일자에 데이터가 존재하는 것을 확인할 수 있다.
- 위의 `logback-spring.xml`에서 `level`을 필드에 추가했기 때문에 엘라스틱서치 및 키바나에서 로그레벨 별로 필터링할 수 있게 되었다.
개선사항
- 기존 프로젝트 관리 서비스에서 제공하던 `JWT` 인증 로직 게이트웨이 서버로 옮기기
- 타 서비스의 로그 게이트웨이 서버로 전송하여 로그 통합 관리
이미지 출처
Contents
스프링 클라우드 게이트웨이 레퍼런스를 한글로 번역한 문서입니다. 버전은 3.0.2 기준입니다.
godekdls.github.io
[MDC/Filebeat/ELK stack] Webflux에서 로그에 UUID 표기 후 ELK stack으로 전송하기 (3)
Docker compose로 ELK stack + filebeat 연동&모니터링
medium.com
'개발 > 스프링' 카테고리의 다른 글
Redis 도입을 통한 데이터 캐싱 처리 (5) | 2025.04.06 |
---|---|
Websocket-STOMP 및 DB 통합 테스트해보자 (0) | 2025.04.05 |
[Trouble-shooting] 클라이언트에서 Websocket-STOMP 연결 요청 시 FALLBACK이 사용되는 현상 (2) | 2025.03.28 |
[Trouble-shooting] 중첩 클래스명 중복으로 Swagger가 고장났다 (2) | 2025.03.21 |
Faker가 만들어 주는 테스트 데이터, 또 나만 몰랐지 (3) | 2025.03.19 |