C# Academy · 강의

기한, 취소와 인터셉터

기한으로 제한 시간을 적용하고 CancellationToken을 전달하며 gRPC 인터셉터로 공통 관심사를 추가합니다.

레슨 4/412개 단계

기한, 취소와 인터셉터은(는) CoddyKit의 무료 C# Academy 강의입니다. 이것은 4개 중 4번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 C# Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. C# Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

gRPC의 안정성: 기한 및 취소

프로덕션 gRPC 서비스는 두 가지 중요한 안정성 문제를 처리해야 합니다. 기한(client가 얼마나 오래 기다릴지)과 취소(작업을 조기에 중지하는 것)입니다. 이 둘을 함께 사용하면 리소스 고갈과 연쇄 장애를 방지할 수 있습니다.

호출에 기한 설정하기

기한은 호출이 완료되어야 하는 절대적인 시점입니다. CallOptions로 설정하십시오. 기한을 초과하면 서버는 취소를 받고 client는 StatusCode.DeadlineExceeded를 받습니다.

var deadline = DateTime.UtcNow.AddSeconds(5);

var reply = await client.GetOrderAsync(
    new GetOrderRequest { Id = 42 },
    deadline: deadline);

// Or via CallOptions:
var options = new CallOptions(deadline: deadline);
var reply2 = await client.GetOrderAsync(
    new GetOrderRequest { Id = 42 }, options);

Client에서 DeadlineExceeded 처리하기

RpcException을 catch하고 상태 코드를 확인하여 기한 만료를 다른 오류와 구분하십시오.

try
{
    var reply = await client.GetOrderAsync(
        new GetOrderRequest { Id = 42 },
        deadline: DateTime.UtcNow.AddSeconds(3));
}
catch (RpcException ex) when (ex.StatusCode == StatusCode.DeadlineExceeded)
{
    Console.WriteLine("Call timed out");
}
catch (RpcException ex)
{
    Console.WriteLine($"gRPC error: {ex.Status.Detail}");
}

서버에서 기한 준수하기

서버는 장시간 작업 중에 context.CancellationToken을 확인해야 합니다. 기한이 지나면 이 토큰은 자동으로 취소됩니다.

public override async Task<ReportResponse> GenerateReport(
    ReportRequest request,
    ServerCallContext context)
{
    var ct = context.CancellationToken;

    // Pass ct to every async call — work stops when deadline hits
    var data = await _db.FetchLargeDatasetAsync(request.Filters, ct);
    var report = await _reportEngine.BuildAsync(data, ct);

    ct.ThrowIfCancellationRequested(); // explicit check before CPU work
    return MapToResponse(report);
}

CancellationToken 전파

서버의 취소 토큰을 모든 async 호출 체인을 통해 항상 전파하십시오. 이를 무시하면 취소된 호출이 불필요하게 계속 리소스를 소비합니다.

// GOOD: token flows through the call chain
await _db.Products.AsNoTracking()
    .Where(p => p.IsActive)
    .ToListAsync(context.CancellationToken); // cancels if client disconnects

// BAD: ignores cancellation
await _db.Products.ToListAsync(); // keeps running after deadline

gRPC 인터셉터: 개념

인터셉터는 gRPC에서 ASP.NET Core 미들웨어에 해당합니다. RPC 호출 전후에 실행되며 요청, 응답 및 예외를 검사하거나 수정할 수 있습니다. 로그 기록, 인증 및 재시도 로직에 적합합니다.

서버 측 인터셉터 만들기

Interceptor에서 상속하고 가로챌 메서드 형식을 재정의하십시오. 실제 handler로 진행하려면 continuation을 호출하십시오.

using Grpc.Core.Interceptors;

public class LoggingInterceptor : Interceptor
{
    private readonly ILogger<LoggingInterceptor> _logger;
    public LoggingInterceptor(ILogger<LoggingInterceptor> l) => _logger = l;

    public override async Task<TResponse> UnaryServerHandler<TRequest, TResponse>(
        TRequest request,
        ServerCallContext context,
        UnaryServerMethod<TRequest, TResponse> continuation)
    {
        _logger.LogInformation("gRPC call: {Method}", context.Method);
        var sw = System.Diagnostics.Stopwatch.StartNew();
        var response = await continuation(request, context);
        _logger.LogInformation("Completed in {Ms}ms", sw.ElapsedMilliseconds);
        return response;
    }
}

서버 인터셉터 등록하기

Program.cs에서 인터셉터를 전역적으로(모든 서비스에) 또는 서비스별로 등록하십시오. DI 컨테이너가 생성자 종속성을 확인합니다.

// Globally for all gRPC services:
builder.Services.AddGrpc(opt =>
    opt.Interceptors.Add<LoggingInterceptor>());

// Or per service:
builder.Services.AddGrpc();
builder.Services.AddSingleton<LoggingInterceptor>();

app.MapGrpcService<OrderService>()
   .AddInterceptor<LoggingInterceptor>();

Client 측 인터셉터

Client 인터셉터는 나가는 호출을 감쌉니다. 각 호출 위치를 수정하지 않고도 인증 헤더, 재시도 로직 또는 상관관계 ID를 추가할 때 유용합니다.

public class AuthInterceptor : Interceptor
{
    private readonly ITokenProvider _tokens;
    public AuthInterceptor(ITokenProvider t) => _tokens = t;

    public override AsyncUnaryCall<TResponse> AsyncUnaryCall<TRequest, TResponse>(
        TRequest request,
        ClientInterceptorContext<TRequest, TResponse> context,
        AsyncUnaryCallContinuation<TRequest, TResponse> continuation)
    {
        var headers = context.Options.Headers ?? new Metadata();
        headers.Add("authorization", $"Bearer {_tokens.GetToken()}");
        var newContext = new ClientInterceptorContext<TRequest, TResponse>(
            context.Method, context.Host,
            context.Options.WithHeaders(headers));
        return continuation(request, newContext);
    }
}

// Attach to channel:
var invoker = channel.Intercept(new AuthInterceptor(tokenProvider));
var client = new OrderService.OrderServiceClient(invoker);

예외 인터셉터

서버 측 예외 인터셉터는 처리되지 않은 예외를 RpcExceptions로 변환하여 내부 세부 정보가 client로 유출되는 것을 방지합니다.

public class ExceptionInterceptor : Interceptor
{
    public override async Task<TResponse> UnaryServerHandler<TRequest, TResponse>(
        TRequest request,
        ServerCallContext context,
        UnaryServerMethod<TRequest, TResponse> continuation)
    {
        try
        {
            return await continuation(request, context);
        }
        catch (NotFoundException ex)
        {
            throw new RpcException(new Status(StatusCode.NotFound, ex.Message));
        }
        catch (Exception ex)
        {
            throw new RpcException(new Status(StatusCode.Internal, "Internal error"));
        }
    }
}

빠른 확인

gRPC 호출이 deadline을 초과하면 어떻게 됩니까?

복습: 기한, 취소 및 인터셉터

핵심 요점:

  • 제한 없는 대기를 방지하려면 client 호출에 항상 기한을 설정합니다
  • 서버에서 context.CancellationToken을 확인하고 모든 async 호출에 전달합니다
  • 인터셉터는 서비스 코드를 복잡하게 만들지 않고 공통 관심사(로그 기록, 인증, 오류 매핑)를 처리합니다
  • 서버 인터셉터: 단항/스트림 handler 메서드를 재정의하고 continuation을 호출합니다
  • Client 인터셉터: channel 호출자 체인에 연결합니다
무료로 시작

AI 튜터와 함께 C#을(를) 배우세요 — 무료

브라우저에서 실제 코드를 작성하고 실행하며, 24/7 AI 튜터로부터 즉각적인 도움을 받고, 웹이나 앱에서 중단한 부분부터 계속 학습하세요.

코스
93
레슨
346

자주 묻는 질문

“기한, 취소와 인터셉터” 강의는 무료인가요?

네 — “기한, 취소와 인터셉터” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 C# Academy 강의 전체를 잠금 해제할 수 있습니다. C# Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

“기한, 취소와 인터셉터”에서 뭘 배우나요?

기한으로 제한 시간을 적용하고 CancellationToken을 전달하며 gRPC 인터셉터로 공통 관심사를 추가합니다. 브라우저에서 직접 실행하는 실습 코드로 C# Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

C# Academy을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 C# Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 4번째 강의입니다.

“기한, 취소와 인터셉터” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 C# Academy 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 C# Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. gRPC와 Protobuf 기초
  2. 단항 및 서버 스트리밍 RPC
  3. 클라이언트와 양방향 스트리밍
  4. 기한, 취소와 인터셉터
← C# Academy(으)로 돌아가기