[Toss Slash 21] 토스 서비스를 구성하는 서버 기술

📌 시작하기 앞서

누적 사용자 1,800명 이상, 매달 천 만명

📌 토스 서비스를 구성하는 서버 기술 소개

[데이터 센터 이중화] active-active로 서비스 운영중, AWS의 일부 서비스 이용
[쿠버네티스] MSA 구성 → 많은 서비스를 관리하고 효율적인 인프라 활용을 위해 쿠버네티스를 container orchestration으로 도입
[Ceph] 민감자료 저장 용도로 Ceph를 이용해 내부 스토리지 서비스를 제공
[Redis] Memcached를 캐시로 많이 사용했지만, 데이터 보존 문제와 optimistic lock 구현 편이성 때문에 Redis cluster를 캐시로 많이 이용하고 있음
[Kafka] 로그 데이터 파이프라인으로 사용하는 로그용 클러스터와 서비스에서 메시지 큐로 사용하는 클러스터 하나를 운영 중
[로깅과 모니터링] elk + filebeat, thanos, grafana를 사용 중
[Spring & Kotlin] 은행과 연동되는 송금 외에 많은 서비스가 있음 → 스프링 계열 프로젝트를 선택해 개발하고 있음, 최근 개발되는 언어는 Kotlin을 이용
[AWS] DNS 설정, 이미지 검수, static 파일을 서빙하는 기능 등으로 사용 중

📌 데이터 센터 트래픽 조절

평상시에는 트래픽이 50:50 그러나 한쪽이 100%가 되는 트래픽을 옮기는 작업을 자주함
트래픽을 한쪽으로 옮기는 이유는 장애가 났을 때 이 문제를 해결해야 복구가 된다면 장애 시간이 오래 걸릴 수 밖에 없다. (복구 중심 대응) → 장애가 나지 않은 반대편 데이터 센터로 트래픽을 옮겨 장애시간을 줄일 수 있는 효과가 있었음
새로운 시스템 도입, 쿠버네티스 설정 변경 → 테스트하고 예상되는 문제를 확인하지만 문제 발생 확률이 0%는 아니다. 그래서 장애 여파를 줄이기 위해 트래픽의 1%정도를 원복하여 적은 트래픽으로 문제가 없다면 점진적으로 늘려, 문제 발생시 트래픽을 제거한다. (카나리 배포를 적용했다고 보면 된다)

📌 K8S + Istio (DC/OS → K8S로 마이그레이션)

vamp service discovery 비효율과 한계
데이터 센터별로 DC/OS, K8S를 동시 운영 후 마이그레이션
쿠버네티스 도입 할 때 Istio도 같이 도입 → service mesh의 장점이 크다고 판단
MSA로 넘어가면서 서버 간에 network 처리가 필요 → circuit breaker, retry, fallback 등을 애플리케이션에서 처리
istio가 모든 네트워크를 proxy → 애플리케이션에서 하는 일을 대신할 수 있다.

api-gateway

트래픽 증가로 인해 고성능 요구가 커짐 → 신규 gateway 도입
1.
zuul
2.
kong
3.
spring cloud gateway
WebFlux를 도입하면서 reactor에 대한 운영 자신감, 성능이 검증되면서 선택
api-gateway는 트래픽은 여러 필터를 통해 처리됨 (커스텀 필터를 만듬)
암/복호화 필터
auth / oauth 필터
static / dynamic routing
reactor와 coooroutine으로 구현
Netflix에서는 공통로직을 어떻게 처리할지 고민이 많았음
우리는 모듈화해서 사용
많은 서비스가 MVC로 되어 있지만, I/O가 많은 프로젝트는 WebFlux를 이용 중
Reactor는 러닝커브가 크다. → coroutine 도입 (direct style로 가능)

📌 Monitoring

log 중앙집중화가 필요 → logback & filebeat을 통해 애플리케이션 로그를 Kafka로 보냄 → kibana에서 검색해서 볼 수 있음
로그는 컨테이너ID와 서비스ID로 어느 데이터센터, 어떤 컨테이너가 로그를 남겼는지 확인이 가능 (배포ID는 신규 배포, 이전 배포에서 문제가 생겼는지 확인 가능)

📌 Kafka

하나의 클러스터로 두 개 데이터센터를 묶을 것인가, 다른 클러스터로 구성해서 replication을 걸지 고민 (우버에서는 두 개의 클러스터로 운영)
하나의 클러스터로 운영 시 데이터 센터급 장애가 발생하면 다른 센터에 있는 일부 장애가 발생할 수 있다.
두 개의 클러스터로 운영하면 어느 지점부터 consume해야 하는지 모르기 때문에 두 개의 Kafka offset을 sync 해주는 애플리케이션이 필요했음 (wakuwaku라는 것을 개발)

📌 Redis

장기보관이 필요 없는 단발성 데이터 저장과 캐시로 사용 중
메모리 확장이 필요한데 그때마다 slot rebalance로 대응 중

📌 알아봐야 할 것들

카나리 배포
optimistic lock
istio
WebFlux
slot rebalance

📌 참고 자료

TOP