공부하고 기록하는, 경제학과 출신 개발자의 노트

학습일지/Service Mesh

2024 당근테크 - 네트워크 통신 불가를 해결하기 위한 여정 (feat. istio)

inspirit941 2024. 11. 24. 20:57
반응형

https://youtu.be/Hh9zcth4UcI?si=vCq-pKTm6xxopnDP

 

스크린샷 2024-11-21 오후 2 29 56

 
당근페이에서 발생했던 여러 문제들을 어떻게 해결했는지.
 
 

스크린샷 2024-11-21 오후 3 28 33스크린샷 2024-11-21 오후 3 28 50

 
당근서비스와 함께 잘 성장하던 당근페이.
 
 
 

스크린샷 2024-11-21 오후 3 29 03스크린샷 2024-11-21 오후 3 29 10

 
Redis에서 timeout 에러 발생 - redis 명령어 실행에 1500ms 이상 걸림.
Redis Java client인 Lettuce에서 확인해보니, 에러 발생 시점에 command명령어 지연이 발생함.
 
 
 

스크린샷 2024-11-21 오후 3 31 18

 
근데 Redis 서버에는 문제가 없음
 
 

스크린샷 2024-11-21 오후 3 31 43스크린샷 2024-11-21 오후 3 31 52

 
JDBC에서 DB Connection 맺을 때도 timeout 발생. (8초 정도 걸림)
 
 

Deep Dive

스크린샷 2024-11-21 오후 3 32 58

 
마이페이지 상단에 '당근페이' 영역이 있다.

  • 당근페이는 가입하지 않은 사용자에게도 송금이 가능함.
  • 송금을 받았다면, '받지 않은 금액이 있다'는 정보를 표시해줌.

스크린샷 2024-11-21 오후 3 35 20

 
이걸 Traffic flow로 살펴보자면

  • 당근페이 미가입 사용자의 '받지 않은 송금액 조회' HTTP 요청 -> Redis에 캐시된 정보 조회.
  • Redis에 캐시된 게 없을 경우 DB 조회해서 가져온다.

스크린샷 2024-11-21 오후 3 37 18

 
당근페이 가입자의 경우에도 마찬가지. 호출하는 서비스는 다르지만 결국 Redis 조회 / Redis에 없을 경우 DB 조회하는 flow를 거친다.

스크린샷 2024-11-21 오후 3 38 09

 
에러 발생 시점: 서버에서 외부로 나가는 모든 outbound 통신이 실패함.

수많은 추정 원인 / Action Item

스크린샷 2024-11-21 오후 3 38 43

 

1. internal Service Segregation

스크린샷 2024-11-21 오후 3 39 47스크린샷 2024-11-21 오후 3 40 00

 
microservice 분리.

  • 기존에는 하나의 서버에서 모바일 앱, 웹 FE, 서버 간 요청을 전부 처리하고 있었음.
  • 서버 리소스의 점유 비중에서 가장 큰 부분을 차지하는 하늘색, 핑크색, 노란색은 전부 서버 간 통신. 사용자의 직접적인 요청이 아니다.
    • 이런 구조는 부하가 심한 상황에서 성능병목, 신뢰성 하락으로 이어질 수 있음

스크린샷 2024-11-21 오후 3 44 22스크린샷 2024-11-21 오후 3 44 10

 
서버 간 통신을 담당하는 서비스를 별도로 분리 -> 사용자용 서버에 발생하는 부하를 낮췄음.

2. Event Streaming Pattern

스크린샷 2024-11-21 오후 3 45 28

 
원래는 서버에서 직접 Redis / Kafka 등의 리소스에도 접근.

  • 결함을 예측하고 대처하는 시스템을 만들기 위해 apache flink기반 event streaming 구조 적용
  • -> 웹 서버의 안정성 개선

3. ZGC 적용

스크린샷 2024-11-21 오후 3 57 59

 

  • spiky traffic으로 DB에서 조회한 객체 로딩이 많아지면 GC가 자주 발생 -> Pause Time 증가.
  • JVM heap 메모리 & GC time 최적화를 위해 ZGC 적용.
  • ZGC 도입만으로도 GC time 최적화가 상당부분 이루어짐. JDK 21 쓰고있다면 도입 고려해도 좋을 거라 생각함

4. SQL Query Optimization

스크린샷 2024-11-21 오후 3 59 40

 
애플리케이션 메모리 사용 / DB부하 개선을 위한 Query Tuning

  • 장표 사진은 AWS의 RDS Performance insight 이미지.
  • 현재 DB 부하상태와, 부하에 영향을 주는 여러 쿼리를 보여준다. DBA 도움 없이도 개발자가 대응할 수 있음

 

스크린샷 2024-11-21 오후 4 01 46

 
예컨대 잔액조회를 위해 ORM에서 생성한 SQL query를 sum(count) 로 변경.

  • 전체 송금 record 조회하는 방식 -> 전체 송금액 조회하는 방식.
  • RPS가 높을 땐, 이런 query 최적화가 큰 개선이 됨.

5. API Performance Optimization

스크린샷 2024-11-21 오후 4 03 31스크린샷 2024-11-21 오후 4 04 18스크린샷 2024-11-21 오후 4 04 41

 
istio의 traffic topology 예시. 혹시 불필요한 서비스가 호출되지는 않는지 파악할 수 있음.

  • 불필요한 api호출 정리한 결과 api latency가 15ms -> 3ms로 약 82% 감소
  • DB QPS도 84%, CPU 사용량도 80% 감소.

 

6. Connection / Read Timeout 조정

스크린샷 2024-11-21 오후 4 29 40

 

  • 외부요청을 보내기 전 Connection timeout
  • 데이터 수신을 얼마나 기다릴 건지 결정하는 Read timeout.

너무 길면 불필요한 리소스 점유 + 사용자 경험에 안좋다.
TCP connection time 생각해서 connection timeout은 3초.

Read timeout의 경우 단순조회는 500ms 미만, 나머지는 컴포넌트 특성과 중요도에 따라 구분.

진짜 문제

스크린샷 2024-11-21 오후 4 32 31

 
당근은 microService 간 통신 제어를 위해 istio를 사용함.

  • xDS 통해 서비스 호출을 위한 Endpoint 상태 전파.
  • 배포 발생하면, 새로운 pod가 올라오므로 service discovery + 전파를 위해 push Metric이 급증.

스크린샷 2024-11-21 오후 4 41 13스크린샷 2024-11-21 오후 4 41 32

 
istio는 application에 Sidecar 형태로 Envoy proxy를 주입하고, 애플리케이션으로 들고나는 트래픽을 관리함.

  • envoy proxy의 Configuration 정보는 istiod에서 주입
  • sidecar로 배포된 envoy proxy에 문제가 생기면, 애플리케이션 입장에서는 모든 네트워크 트래픽이 동작 안하는 것처럼 인식될 수 있음.

스크린샷 2024-11-21 오후 4 44 43스크린샷 2024-11-21 오후 4 44 58스크린샷 2024-11-21 오후 4 45 12

 
istio proxy에서 CPU Throttle이 발생.

  • k8s 환경에서는 cpu limit을 걸어두면 cpu가 여유로운 상황에서도 throttle이 간혹 발생할 수 있다.

 

테스트 시작

스크린샷 2024-11-21 오후 4 48 00

 
CPU limit 때문에 Throttle이 발생했다.

  • cpu 사용량이 높아서 throttle 발생 -> 네트워크 오류가 발생하는가?
  • throttle 있는 상황에서 배포 진행 -> 네트워크 오류가 발생하는가?
  • CPU limit 해제하면 처리 가능한 HTTP 요청이 증가하는가?

스크린샷 2024-11-21 오후 4 49 35

 
k6로 테스트 진행. 대시보드는 application, istio sidecar의 리소스 사용량.
 
 

스크린샷 2024-11-21 오후 4 49 42스크린샷 2024-11-21 오후 4 51 25

 
테스트 결과, istio proxy의 cpu 사용량과 throttle 패턴이 동일함
HTTP latency도 증가함
 
 

스크린샷 2024-11-21 오후 4 51 42스크린샷 2024-11-21 오후 4 51 54스크린샷 2024-11-21 오후 4 52 58

 

해결

스크린샷 2024-11-21 오후 4 53 13스크린샷 2024-11-21 오후 4 53 19

 
istio proxy에서 CPU limit 삭제하자, 문제 해결됨. 서비스 적용

다른 문제 발견

스크린샷 2024-11-21 오후 4 53 30

 
cpu 사용량이 지속적으로 늘어난다.

스크린샷 2024-11-21 오후 4 55 35스크린샷 2024-11-21 오후 4 55 53

 
메모리 사용량도 계속 늘어난다.

느낀점

스크린샷 2024-11-21 오후 4 58 07

 
서비스의 load parameter (부하 파라미터): 시스템의 가용범위를 의미하는 수치.

  • 웹서버의 RPS / DB의 read, write비율, cache hit 등...
  • system metric이나 부하테스트로 관측 가능.

스크린샷 2024-11-21 오후 4 58 34

 
visibility 확보를 위해 "예측가능한 동작 보장"이 필요함.

  • 당근페이는 코틀린, virtual thread 활용한 비동기 non-blocking 적극 활용중.
  • 정상일 경우 / 부하일 경우의 상태파악이 중요함.
반응형