caffeine-library / release-everything

'Release의 모든 것'을 읽는 스터디
3 stars 0 forks source link

[keyword] 2장 - 사례 연구: 항공사를 멈추게 한 예외 #4

Closed binchoo closed 9 months ago

binchoo commented 9 months ago

주제

'2장 - 사례 연구: 항공사를 멈추게 한 예외'을 읽고 내용을 요약하거나,
중요✨ 하다고 생각하는 키워드 및 관련 설명을 코멘트로 달아주세요

연관 챕터

2


@caffeine-library/readers-release-everything

binchoo commented 9 months ago

책이 공유한 이슈 사례를 코멘트 해 보며 읽었습니다.

[이슈 내용]

  • 공항 키오스크와 IVR 서비스 마비
  • 항공 예약, 발권, 수속 지연으로 SLA 위반 뿐 아니라 공항 업무 부담 증가, 탑승객 불편, 항공기 착륙 지연 등으로 확산되어 신뢰도, 금전, 시간 손해를 끼친 사례

[이슈 원인] 💬 DB 전환 중 생기는 Dangling 커넥션의 생명주기를 설계하지 않았기 때문입니다.

💬 저는 개발자가 아니라 확언은 못 하지만, 개발 작업 중에는 테스트 통과를 위한 기능 요구사항에 치중하다 보니, SW와 인프라를 독립적으로 생각하게 되거나, 이쪽은 시야가 깜깜한 상태로 작업을 하게 될 것 같아요. 자바=이식성=플랫폼 독립 같은 비즈니스 용어에 노출되다 보면, 응용이 올라갈 텃밭이 어쩐 상태인가 상관없다 싶을 수도.

  • 키오스크, IVR이 의존하는 CF(핵심기능) 서비스 내 DB 커넥션 풀 관리 미비
    • 모든 JDBC 커넥션 점유로 DB 쿼리를 수행 불가 상태로 전 스레드 블럭 상태.
    • 커넥션 생성 시점과 반환 시점 사이에 Active DB가 전환되어 conn.close()가 정상 처리되지 않음. finally 구문이 가져온 환각 효과.
  • 상황 당시 HTTP 헬스 체크는 정상 동작.
    • 응용 관점에서 DB 텔레메트리가 미비된 상태로 서비스 관제 중이었다는 뜻.

💬 품질이 깨지면 기능이 깨진다는 격언에 입각해 보면

[추신] 💬 관련 사례를 보니 최근 컴포넌트 개발 건이 떠오릅니다. SA로 인프라 구축할 때는 AWS가 제공하는 SLA와 관제 기능들을 신뢰하는 편인데요. (강한 확신을 갖고 밀어줘야 하는 입장이기도 하죠). 해당 롤을 벗어나서 가끔 개발 공수가면 책임 소재는 저한테 있으니, 스프링이 제공하는 횡단성 모듈들을 참고하며 신뢰성을 챙기기 위한 도움을 받았습니다. 로깅, 재시도 로직, 구성 변경, 의존성 주입 등 패턴을 구현하거나, 실패 시나리오에 따른 대응 매뉴얼을 고민하게 되더라구요

💬 상황까지 두 시간이 어떤 상태였을지 궁금하네요. 장애 인지가 없던 시간인지, 실제 장애가 없던 건지. 하나라도 정상 메서드가 있었다면 점차 DB2 커넥션이 생겼을 터라, 해당 연결을 할당받은 경우 쿼리는 간간히 돌아갔을 겁니다. 아마 커넥션 풀이 꽉 차고, 스레드 점유까지 도달하는 2시간이었으리라. 같은 의견이실까요? 모니터링 못한 게 와닿지는 않네요. QA부재인가.

💬 제가 스프링 배울 때 퓨어 JDBC 사용 vs. JPA Repository 스닛펫 비교 코드를 많이 봤었는 데 conn.close() 부분 예외 처리는 없었던 것 같아요. 책 예제가 다중화 DB를 고려하지 않기 때문이겠지요?

💬굉장히 머리 띵한게 DB 커넥션 소진과 HTTP 헬스 체크가 무관하다는 점이네요. HTTP 쪽과 DB 연결 쪽 텔레메트리를 구분하여 수집해야 할 텐데 현업에서 이렇게들 하고 계실까요?

JasonYoo1995 commented 9 months ago

서론

2.1 변경 시간대

2.2 작동 중단

2.3 장애의 영향

2.4 사후 분석

2.5 단서 수색

2.6 결정적 단서

2.7 외양간 고치기?

kth990303 commented 9 months ago

이슈 소개

이 시스템은 J2EE 애플리케이션 서버의 클러스터에서 작동했으며 여분의 복구용 오라클 9i 데이터베이스를 가지고 있었다. (p.43) 부분을 보며, 해당 사례가 2000년대 초중반에 발생하지 않았을까 추측할 수 있어 보입니다.

뒤에 나오지만, EJB 메서드를 이용하는 것도 하나의 시대적 배경을 추측할 수 있는 단서로 보여요. 하이버네이트와 ORM이 발달한 요즘이라면 Spring AOP @Transactional 및 HibernateTransactionManager 라이브러리 내에서 connection 관리가 이루어져 개발자는 이러한 문제에서 벗어날 수 있지 않을까 추측해봅니다. (커넥션 유지보수는 스프링 및 하이버네이트가, 개발자는 비즈니스 로직에 집중할 수 있으리라 생각했습니다.)

이슈 해결과정

시체가 사라지고 없기 때문에 장애 사후 분석은 살인 사건을 해결하는 것보다 더 어려울 수 있다. 서버가 다시 가동되어 실행 중이기 때문에 부검할 사체가 없다. (p.50)

이슈를 본격적으로 해결하기 전에 나온 문장인데, 나름 와닿아서 적어봤어요. 용량 부족으로 인해 로그를 지울 때도 있고, 원인 분석보다는 문제 해결이 비교적 우선순위가 높기 때문에 인스턴스를 재가동하거나 스펙을 변경하는 과정에서 인스턴스가 삭제돼 원인 분석이 어려울 수도 있고요. 실제로 최근 팀 내 DB DML latency가 급증하여 문제 원인 분석을 DBA 분들께 요청드렸는데요, 두 번의 스펙 변경으로 인해 writer 인스턴스가 삭제되면서 원인 분석까지는 어렵다는 답변을 받은 적이 있어요. 이 문구가 생각이 나더라고요 ㅎㅎ

스레드 덤프만 있다면 애플리케이션은 펼쳐진 책과 같다 (p.51) Q. 저는 아직 스레드 덤프를 실무에서 분석해본 적이 없는데요. 사이드프로젝트에서 kill -3 명령어로 스레드 덤프를 떠보는 것을 시도해본 경험은 있습니다. 참고한 문서를 첨부합니다. jmap으로 스레드 덤프를 뜨는 것이 가장 유명한 방법이던데, 이 방법은 리눅스 버전 충돌(?) 로 인해 안되더라고요. 아무튼, 책의 사례에서도 locked, waiting 상태인 스레드들이 소켓의 read함수로 인해 blocking 되어 결국 장애가 발생한 것을 알 수 있었는데요. 실제로 여러분들의 스레드 덤프 분석 사례가 있다면 공유받고 싶어요.

QA 부족?

테스트를 더 많이 했다면 버그를 예방할 수 있었을까? (p.58) 확률은 줄일 수 있겠지만, QA로 100% 모든 걸 해결할 수 있다고 생각하진 않아서 QA 부족이라 보이진 않는 거 같아요. 실제로 개발자들도 코드가 완벽하리라 생각하고 운영배포를 하지만, 운영 환경에서 장애가 발생할 수 있는것처럼요. 결국은 한 시스템의 버그가 다른 시스템에 영향을 미치지 않게 하는 것이 중요한 것이라 생각됩니다. 그러기 위해 강결합도 줄이고, 트랜잭션으로 외부 API를 묶지 않고 별도로 분리하기도 하는 등의 패턴(?)이나 행동들이 등장하는 것처럼.

binchoo commented 9 months ago

과몰입 하면 제일 궁금한게 수차례 DB 전환 작업을 해 오다 왜 하필 이날 이슈가 발생했으며, 여태 이상 징후는 없었는가 입니다. (저자가 msg 치거나 감춰둔 내용이 있음을 감안해도)

JasonYoo1995 commented 9 months ago

@binchoo 님

💬 상황까지 두 시간이 어떤 상태였을지 궁금하네요. 장애 인지가 없던 시간인지, 실제 장애가 없던 건지. 하나라도 정상 메서드가 있었다면 점차 DB2 커넥션이 생겼을 터라, 해당 연결을 할당받은 경우 쿼리는 간간히 돌아갔을 겁니다. 아마 커넥션 풀이 꽉 차고, 스레드 점유까지 도달하는 2시간이었으리라. 같은 의견이실까요? 모니터링 못한 게 와닿지는 않네요. QA부재인가.

말장난 같지만 p.45를 자세히 보니 키오스크/IVR이 2시간 뒤에 빨간 불이 되었다고 했지 CF가 2시간 뒤에 빨간 불이 되었다는 문장은 없네요

개인적인 추측으로는 커넥션 풀 내 모든 커넥션 객체들은 커넥션 풀에 등록된 유일한 1개의 호스트(=DB1)를 공통으로 사용했을 것 같아서 CF는 DB 전환 후 즉시 먹통이 되었을 것 같고요

키오스크/IVRCF를 호출하지 않는 다른 요청에 대해선 초기에 정상 서비스를 제공했을 것이고 시간이 지나면서 CF를 호출하는 요청들에 의한 지연/병목의 영향이 점차 커지면서 2시간 이후 시점에 이르러서 키오스크/IVR의 모든 리소스가 소진되면서 빨간 불이 발생했을 수도 있을 것 같아요

💬 제가 스프링 배울 때 퓨어 JDBC 사용 vs. JPA Repository 스닛펫 비교 코드를 많이 봤었는 데 conn.close() 부분 예외 처리는 없었던 것 같아요. 책 예제가 다중화 DB를 고려하지 않기 때문이겠지요?

p.57의 문장처럼 특정 버전의 오라클 JDBC 드라이버만의 예외적인 행동일 수 있기 때문에 다른 버전/벤더였다면 예외처리가 필요 없을 수도 있을 것 같습니다

제일 궁금한게 수차례 DB 전환 작업을 해 오다 왜 하필 이날 이슈가 발생했으며, 여태 이상 징후는 없었는가 입니다

이것도 말장난 같지만, p.44를 보면 '베리타스를 사용해서 활성 DB의 호스트를 이관하는 활동'을 수십 번 수행했다고 했지 그 과거의 이관 활동에 대한 대상이 반드시 'CF'였다고 명시되진 않은 것 같습니다 CF에 대해서 이관하는 것은 이번이 처음이었어야 모든 게 맞아 떨어지고 생각하기 편한 것 같아요

책에 모든 정황에 대해 상세하게 명시되어 있지 않아서 같은 문장을 보고도 다양하게 해석할 수 있고 이에 따라 해석 가능한 경우의 수가 너무 많아져서 이게 맞다 저게 맞다 라고 확언하기가 어렵네요

binchoo commented 9 months ago

@JasonYoo1995 관점 공유 감사드립니다.

저자 분 링트인 보니 항공 도메인은 딱히 없어 봬는데 2003년 근방 Totality Corporation에서 전자상거래 MSP 업무 하신 것 같네요. 이슈 사례가 해당 기간 고객 항공사 일지도...

History

Totality was a provider of application & infrastructure management services for large-scale e-commerce sites.

저도 CF DB 이관이 첫 사례였고 그로 인해 사건이 발생했다고 보는 게 체증이 내려갑니다. MSP였으면 다른 고객사례에서도 베리타스 써서 관련 고가용성 구성을 했을테니 관련 경험이 많이 있었다 서술한 것 같네요.

물론, 저희가 저자 면담을 하지 않으면 속 시원하게 풀리진 않겠군요. 😞