7. 동기 다운스트림 호출의 연쇄 장애 (타임아웃·차단기·격벽 부재)
난이도 상 해설 보기 →
결함을 모두 찾고 원인·수정안·더 나은 설계를 제시하라. 마커
(A)(B) 는 주목 위치 힌트다.
결함 코드 · C#
// 시나리오: 게이트웨이(또는 게임 서버)가 매 요청마다 인증 서비스를 동기 RPC 로 호출한다.
// 인증 서비스는 별도 프로세스/머신이며, 평소엔 1~2ms 로 응답한다.
// 장애 상황: 인증 서비스가 느려지거나(GC 폭주/DB 락) 응답을 멈추면, 호출은 오래 걸리거나 끝나지 않는다.
// 게이트웨이의 요청 처리는 제한된 워커(스레드풀) 위에서 돈다.
//
// 요구사항:
// - 다운스트림(인증) 한 곳의 지연이 게이트웨이 "전체"를 마비시키면 안 된다(장애 격리/전파 차단).
// - 인증과 무관한 처리(핑/헬스체크 등)는 인증이 느려도 계속 응답해야 한다.
//
// 과제: (A)(B) 를 중심으로, 인증 서비스가 느려졌을 때 그 영향이 게이트웨이 전체로 어떻게
// 번지는지(자원 관점에서) 분석하고, 그 수정안을 제시하라.
public interface IAuthClient { AuthResult Validate(string token); } // 네트워크 블로킹 호출
public readonly struct AuthResult { public readonly bool Ok; public AuthResult(bool ok) { Ok = ok; } }
public struct PlayerRequest { public string Token; }
public enum PlayerResponse { Ok, Denied, Unavailable }
public sealed class Gateway
{
private readonly IAuthClient _auth;
public Gateway(IAuthClient auth) => _auth = auth;
// 워커 스레드(스레드풀)에서 호출된다.
public PlayerResponse HandleRequest(PlayerRequest req)
{
var result = _auth.Validate(req.Token); // (A) 동기 RPC — 타임아웃/취소 없음
if (!result.Ok)
return PlayerResponse.Denied;
return Process(req); // (B) 보호장치 없이 항상 같은 경로
}
private PlayerResponse Process(PlayerRequest req) => PlayerResponse.Ok;
} 결함 코드 · C++
// 시나리오: 게이트웨이(또는 게임 서버)가 매 요청마다 인증 서비스를 동기 RPC 로 호출한다.
// 인증 서비스는 별도 프로세스/머신이며, 평소엔 1~2ms 로 응답한다.
// 장애 상황: 인증 서비스가 느려지거나 응답을 멈추면, 호출은 오래 걸리거나 끝나지 않는다.
// 게이트웨이의 요청 처리는 제한된 워커 스레드 풀 위에서 돈다.
//
// 요구사항:
// - 다운스트림(인증) 한 곳의 지연이 게이트웨이 "전체"를 마비시키면 안 된다(장애 격리/전파 차단).
// - 인증과 무관한 처리(핑/헬스체크 등)는 인증이 느려도 계속 응답해야 한다.
//
// 과제: (A)(B) 를 중심으로, 인증 서비스가 느려졌을 때 그 영향이 게이트웨이 전체로 어떻게
// 번지는지(자원 관점에서) 분석하고, 그 수정안을 제시하라.
#include <string>
struct AuthResult { bool ok; };
class IAuthClient {
public:
virtual ~IAuthClient() = default;
virtual AuthResult validate(const std::string& token) = 0; // 네트워크 블로킹 호출
};
struct PlayerRequest { std::string token; };
enum class PlayerResponse { Ok, Denied, Unavailable };
class Gateway {
public:
explicit Gateway(IAuthClient& auth) : auth_(auth) {}
// 워커 스레드(스레드풀)에서 호출된다.
PlayerResponse handle_request(const PlayerRequest& req) {
AuthResult r = auth_.validate(req.token); // (A) 동기 RPC — 타임아웃 없음
if (!r.ok) return PlayerResponse::Denied;
return process(req); // (B) 보호장치 없이 항상 같은 경로
}
private:
PlayerResponse process(const PlayerRequest&) { return PlayerResponse::Ok; }
IAuthClient& auth_;
};
int main() { return 0; } 내 리뷰 · C#
내 답안 · 자동 저장
작성 후 위 해설 보기에서 모범 해설과 대조하세요.
내 리뷰 · C++
내 답안 · 자동 저장
작성 후 위 해설 보기에서 모범 해설과 대조하세요.