paint-brush
실패는 필수이므로 이를 수용하세요: 소프트웨어의 오류 방지 및 오류 방지 전략 이해~에 의해@shai.almog
614 판독값
614 판독값

실패는 필수이므로 이를 수용하세요: 소프트웨어의 오류 방지 및 오류 방지 전략 이해

~에 의해 Shai Almog7m2024/05/07
Read on Terminal Reader

너무 오래; 읽다

오류를 수용하면 앱 품질이 향상되어 조기 오류 감지, 강력한 오류 처리 및 전반적인 안정성이 향상되는 방법을 알아보세요.
featured image - 실패는 필수이므로 이를 수용하세요: 소프트웨어의 오류 방지 및 오류 방지 전략 이해
Shai Almog HackerNoon profile picture
0-item

소프트웨어 시스템의 오류는 불가피합니다. 이러한 오류를 처리하는 방법은 시스템 성능, 안정성 및 비즈니스 수익에 큰 영향을 미칠 수 있습니다. 이번 포스팅에서는 실패의 장점에 대해 이야기해보고 싶습니다. 실패를 추구해야 하는 이유, 실패가 좋은 이유, 실패를 피하면 애플리케이션의 안정성이 저하될 수 있는 이유. 빠른 실패와 안전한 실패에 대한 논의부터 시작하겠습니다. 이는 일반적인 실패에 대한 두 번째 논의로 이어집니다.

참고로, 이 게시물과 이 시리즈의 다른 게시물의 내용이 마음에 드신다면 제 블로그를 확인해 보세요. 디버깅 책 , 그의 주제를 다루고 있습니다. 코딩을 배우는 친구가 있다면 제 책을 참고해 주시면 감사하겠습니다.자바 기초 책. 잠시 후에 Java로 돌아가고 싶다면 다음을 확인하세요. 자바 8~21권 .

빠른 실패

페일패스트 시스템은 예상치 못한 상황이 발생하면 즉시 작동을 멈추도록 설계되었습니다. 이러한 즉각적인 실패는 오류를 조기에 포착하는 데 도움이 되므로 디버깅이 더욱 간단해집니다.


빠른 실패 접근 방식을 사용하면 오류를 즉시 포착할 수 있습니다. 예를 들어, 프로그래밍 언어 세계에서 Java는 null 값이 발견될 때 즉시 NullPointerException 을 생성하고 시스템을 중지하며 오류를 명확하게 하여 이러한 접근 방식을 구현합니다. 이러한 즉각적인 대응은 개발자가 문제를 신속하게 식별하고 해결하여 문제가 더 심각해지는 것을 방지하는 데 도움이 됩니다.


오류를 조기에 포착하고 중지함으로써 빠른 실패 시스템은 하나의 오류가 다른 오류로 이어지는 계단식 오류의 위험을 줄입니다. 이를 통해 문제가 시스템 전체에 확산되기 전에 더 쉽게 억제하고 해결할 수 있어 전반적인 안정성이 유지됩니다.


빠른 실패 시스템을 위한 단위 및 통합 테스트를 작성하는 것은 쉽습니다. 이러한 이점은 테스트 실패를 이해해야 할 때 더욱 두드러집니다. Fail-fast 시스템은 일반적으로 오류 스택 추적의 문제를 직접 가리킵니다.


그러나 빠른 실패 시스템은 특히 프로덕션 환경에서 자체적인 위험을 안고 있습니다.


  • 생산 중단: 버그가 생산에 도달하면 즉각적이고 심각한 중단을 초래할 수 있으며 잠재적으로 시스템 성능과 비즈니스 운영 모두에 영향을 미칠 수 있습니다.
  • 위험 선호도: 빠른 실패 시스템에는 엔지니어와 경영진 모두의 위험 허용 수준이 필요합니다. 장애를 신속하게 처리하고 처리할 준비가 되어 있어야 하며, 종종 장애와 잠재적인 비즈니스 영향의 균형을 맞춰야 합니다.

안전 장치

오류 방지 시스템은 예상치 못한 상황에도 불구하고 복구하고 지속하는 것을 목표로 하는 다른 접근 방식을 취합니다. 따라서 불확실하거나 불안정한 환경에 특히 적합합니다.

마이크로서비스는 아키텍처를 통해 탄력성을 수용하는 오류 방지 시스템의 대표적인 예입니다. 물리적 및 소프트웨어 기반 회로 차단기는 연결 끊김 실패 기능을 통해 연쇄 오류를 방지하고 시스템이 계속 작동하도록 돕습니다.


오류 방지 시스템은 시스템이 열악한 생산 환경에서도 살아남을 수 있도록 보장하여 치명적인 오류의 위험을 줄입니다. 따라서 오류로부터의 원활한 복구가 중요한 하드웨어 장치나 항공우주 시스템과 같은 미션 크리티컬 애플리케이션에 특히 적합합니다.


그러나 안전 장치 시스템에는 다음과 같은 단점이 있습니다.


  • 숨겨진 오류: 오류 복구를 시도함으로써 오류 방지 시스템은 문제 감지를 지연시켜 문제를 추적하기 어렵게 만들고 잠재적으로 더 심각한 계단식 오류로 이어질 수 있습니다.
  • 디버깅 과제: 이러한 지연된 오류 특성으로 인해 디버깅이 복잡해질 수 있으며 문제를 찾아 해결하는 데 더 많은 시간과 노력이 필요합니다.

Fail-Fast와 Fail-Safe 중에서 선택하기

둘 다 장점이 있기 때문에 어느 접근 방식이 더 나은지 결정하는 것은 어렵습니다. 오류 방지 시스템은 즉각적인 디버깅, 연쇄 오류 위험 감소, 보다 빠른 버그 감지 및 해결 기능을 제공합니다. 이렇게 하면 문제를 조기에 파악하고 수정하여 확산을 방지할 수 있습니다.

오류 방지 시스템은 오류를 적절하게 처리하므로 치명적인 오류가 치명적일 수 있는 미션 크리티컬 시스템과 불안정한 환경에 더 적합합니다.

둘 다 균형 맞추기

각 접근 방식의 장점을 활용하려면 균형 잡힌 전략이 효과적일 수 있습니다.


  • 로컬 서비스에 대한 Fail-Fast: 데이터베이스와 같은 로컬 서비스를 호출할 때 Fail-Fast는 오류를 조기에 포착하여 연속적인 오류를 방지할 수 있습니다.
  • 원격 리소스에 대한 오류 방지: 외부 웹 서비스와 같은 원격 리소스에 의존하는 경우 오류 방지 기능을 통해 외부 오류로 인한 중단을 방지할 수 있습니다.

또한 균형 잡힌 접근 방식을 위해서는 코딩, 검토, 툴링 및 테스트 프로세스 전반에 걸쳐 명확하고 일관된 구현이 필요하며 원활하게 통합되도록 해야 합니다. Fail-fast는 오케스트레이션 및 관찰 가능성과 잘 통합될 수 있습니다. 효과적으로 이는 안전 장치 측면을 개발자 계층이 아닌 OPS의 다른 계층으로 이동시킵니다.

일관된 레이어 동작

여기서 상황이 흥미로워집니다. 안전한 실패와 빠른 실패 중에서 선택하는 것이 아닙니다. 그것은 그들에게 적합한 레이어를 선택하는 것입니다. 예를 들어, 오류가 안전 장치 접근 방식을 사용하여 심층 계층에서 처리되면 해당 오류는 발견되지 않습니다. 이는 괜찮을 수 있지만 해당 오류가 부정적인 영향(성능, 가비지 데이터, 손상, 보안 등)을 갖는 경우 나중에 문제가 발생하고 단서가 없습니다.

올바른 솔루션은 단일 레이어에서 모든 오류를 처리하는 것입니다. 최신 시스템에서는 최상위 레이어가 OPS 레이어이며 이것이 가장 합리적입니다. 오류를 처리할 수 있는 가장 적합한 엔지니어에게 오류를 보고할 수 있습니다. 그러나 서비스 다시 시작, 추가 리소스 할당, 버전 되돌리기 등 즉각적인 완화 기능도 제공할 수 있습니다.

재시도는 안전하지 않습니다

최근 저는 발표자들이 업데이트된 클라우드 아키텍처를 나열하는 강의에 참석했습니다. 그들은 실패 시 재시도할 수 있는 프레임워크를 사용하여 마이크로서비스로 가는 지름길을 선택했습니다. 불행하게도 실패는 우리가 원하는 대로 행동하지 않습니다. 테스트만으로는 완전히 제거할 수 없습니다. 재시도는 안전하지 않습니다. 실제로 이는 재앙을 의미할 수도 있습니다.


그들은 시스템을 테스트했고 심지어 프로덕션 환경에서도 "작동합니다". 그러나 치명적인 상황이 발생한다고 가정하면 재시도 메커니즘이 자체 서버에 대한 서비스 거부 공격으로 작동할 수 있습니다. 이와 같은 임시 아키텍처가 실패할 수 있는 방법의 수는 놀라울 정도입니다.


이는 실패를 재정의할 때 특히 중요합니다.

실패의 재정의

소프트웨어 시스템의 오류는 단순히 충돌에 관한 것이 아닙니다. 충돌은 단순하고 즉각적인 실패로 볼 수 있지만 고려해야 할 더 복잡한 문제가 있습니다. 사실 컨테이너 시대의 충돌은 아마도 최고의 실패일 것입니다. 중단이 거의 없이 시스템이 원활하게 다시 시작됩니다.

데이터 손상

데이터 손상은 충돌보다 훨씬 더 심각하고 교활합니다. 이는 장기적인 결과를 가져옵니다. 손상된 데이터는 해결하기 어려운 보안 및 안정성 문제로 이어질 수 있으며, 광범위한 재작업이 필요하고 잠재적으로 복구할 수 없는 데이터가 필요할 수 있습니다.


클라우드 컴퓨팅은 회로 차단기 및 재시도와 같은 방어 프로그래밍 기술로 이어져 오류를 적절하게 포착하고 처리하기 위한 포괄적인 테스트 및 로깅을 강조합니다. 어떤 면에서는 이러한 환경이 품질 측면에서 우리를 되돌려 보냈습니다.


데이터 수준의 빠른 실패 방지 시스템은 이러한 일이 발생하는 것을 막을 수 있습니다. 버그를 해결하는 것은 단순한 수정 그 이상입니다. 근본 원인을 이해하고 재발을 방지하며 포괄적인 로깅, 테스트 및 프로세스 개선으로 확장해야 합니다. 이렇게 하면 버그가 완전히 해결되어 재발 가능성이 줄어듭니다.

버그를 수정하지 마세요

프로덕션의 버그인 경우 프로덕션을 즉시 되돌릴 수 없다면 되돌려야 할 것입니다. 이는 항상 가능해야 하며, 그렇지 않은 경우에도 노력해야 합니다.


수정을 수행하기 전에 오류를 완전히 이해해야 합니다. 내 회사에서는 용서할 수 있는 작은 스타트업에서 압박감 때문에 종종 그 단계를 건너뛰었습니다. 대기업에서는 근본 원인을 이해해야 합니다. 버그 및 생산 문제에 대한 보고 문화는 필수적입니다. 수정 사항에는 유사한 문제가 프로덕션에 도달하지 않도록 방지하는 프로세스 완화도 포함되어야 합니다.

디버깅 실패

Fail-fast 시스템은 디버그하기가 훨씬 쉽습니다. 본질적으로 단순한 아키텍처를 갖고 있어 특정 영역의 문제를 찾아내기가 더 쉽습니다. 사소한 위반(예: 유효성 검사)의 경우에도 예외를 발생시키는 것이 중요합니다. 이는 느슨한 시스템에서 만연하는 연쇄적인 유형의 버그를 방지합니다.

이는 우리가 정의한 제한을 확인하고 적절한 예외가 발생하는지 확인하는 단위 테스트를 통해 추가로 시행되어야 합니다. 재시도는 디버깅을 매우 어렵게 만들고 적절한 위치는 OPS 계층에 있으므로 코드에서 재시도를 피해야 합니다. 이를 더욱 용이하게 하려면 기본적으로 시간 초과가 짧아야 합니다.

계단식 실패 방지

실패는 우리가 피하거나 예측하거나 완전히 테스트할 수 있는 것이 아닙니다. 우리가 할 수 있는 유일한 일은 실패가 발생했을 때 충격을 완화하는 것뿐입니다. 종종 이러한 "부드러움"은 애플리케이션의 약점을 찾는 목표로 극단적인 조건을 최대한 재현하기 위한 장기 실행 테스트를 사용하여 달성됩니다. 이것은 거의 충분하지 않습니다. 견고한 시스템은 실제 생산 실패를 기반으로 이러한 테스트를 수정해야 하는 경우가 많습니다.

안전 장치의 좋은 예는 서비스가 중단된 경우에도 작업을 계속할 수 있게 해주는 REST 응답 캐시입니다. 불행하게도 이는 캐시 중독이나 캐시로 인해 금지된 사용자가 여전히 액세스할 수 있는 상황과 같은 복잡한 틈새 문제로 이어질 수 있습니다.

생산의 하이브리드

오류 방지는 프로덕션/스테이징 및 OPS 계층에만 적용하는 것이 가장 좋습니다. 이렇게 하면 프로덕션과 개발 간의 변경 사항이 줄어들고, 가능한 한 유사해지기를 원하지만 여전히 프로덕션에 부정적인 영향을 미칠 수 있는 변경입니다. 그러나 관찰을 통해 시스템 오류를 명확하게 파악할 수 있으므로 이점은 엄청납니다.


여기에서의 논의는 관찰 가능한 클라우드 아키텍처를 구축한 최근 경험에 따라 약간 달라졌습니다. 그러나 내장형이든 클라우드이든 모든 유형의 소프트웨어에는 동일한 원칙이 적용됩니다. 이러한 경우 우리는 종종 코드에 오류 방지 기능을 구현하도록 선택합니다. 이 경우 특정 계층에서 일관되고 의식적으로 구현하는 것이 좋습니다.


이러한 상황에서 일관되지 않고 잘못 문서화된 동작을 제공하는 라이브러리/프레임워크의 특별한 경우도 있습니다. 나 자신도 내 작업 중 일부에서 그러한 불일치로 인해 유죄입니다. 저지르기 쉬운 실수입니다.

마지막 말

이것은 디버깅에 관한 책/강좌의 일부인 디버깅 이론 시리즈의 마지막 게시물입니다. 우리는 종종 디버깅을 무언가 실패할 때 취하는 조치로 생각합니다. 그렇지 않습니다. 디버깅은 코드의 첫 줄을 작성하는 순간부터 시작됩니다. 우리는 코딩하면서 디버깅 프로세스에 영향을 미치는 결정을 내리는데, 실패할 때까지 이러한 결정을 인식하지 못하는 경우가 많습니다.


이 게시물과 시리즈가 미지의 상황에 대비한 코드를 작성하는 데 도움이 되기를 바랍니다. 디버깅은 본질적으로 예상치 못한 일을 처리합니다. 테스트는 도움이 될 수 없습니다. 하지만 이전 게시물에서 설명했듯이 준비를 더 쉽게 만들어 줄 수 있는 간단한 방법이 많이 있습니다. 이는 일회성 프로세스가 아니라 실패에 직면했을 때 내린 결정을 재평가해야 하는 반복적인 프로세스입니다.