요청 컨텍스트
RequestContext은(는) 추적 ID와 같은 애플리케이션 메타데이터가 요청과 함께 흐를 수 있도록 하는 Orleans 기능입니다. 애플리케이션 메타데이터는 클라이언트에 추가될 수 있습니다. Orleans 요청과 함께 수신하는 조직으로 흐릅니다. 기능은 Orleans 네임스페이스에서 공용 정적 클래스 RequestContext
에 의해 구현됩니다. 이 클래스는 두 가지 간단한 메서드를 노출합니다.
void Set(string key, object value)
이전 API는 요청 컨텍스트에 값을 저장하는 데 사용됩니다. 값은 직렬화 가능한 모든 형식일 수 있습니다.
object Get(string key)
이전 API는 현재 요청 컨텍스트에서 값을 검색하는 데 사용됩니다.
RequestContext
백업 스토리지는 비동기 로컬입니다. 호출자(클라이언트 쪽 또는 Orleans 내부)가 요청을 보내면 호출자의 RequestContext
내용이 요청의 Orleans 메시지에 포함됩니다. 조직 코드가 요청을 수신하면 로컬 RequestContext
의 해당 메타데이터에 액세스할 수 있습니다. 조직 코드가 RequestContext
를 수정하지 않으면 요청하는 모든 조직이 동일한 메타데이터를 수신하는 등의 작업을 수행합니다.
또한 애플리케이션 메타데이터는 StartNew 또는 ContinueWith를 사용하여 향후 계산을 예약할 때 유지 관리됩니다. 두 경우 모두 계산이 예약된 순간에 스케줄링 코드가 가지고 있던 것과 동일한 메타데이터로 계속이 실행됩니다(즉, 시스템에서 현재 메타데이터의 복사본을 만들어 연속으로 전달하므로 StartNew
또는 ContinueWith
호출 후 변경 내용이 연속으로 표시되지 않음).
Important
애플리케이션 메타데이터는 응답과 함께 다시 흐르지 않습니다. 즉, 응답이 수신된 결과로 실행되는 코드는 ContinueWith
연속 내에서 또는 Task.Wait()나 GetValue
호출 후에 원래 요청에 의해 설정된 현재 컨텍스트 내에서 계속 실행됩니다.
예를 들어 클라이언트의 추적 ID를 새 Guid
ID로 설정하려면 다음을 호출합니다.
RequestContext.Set("TraceId", Guid.NewGuid());
예를 들어 로그를 작성할 때 조직 코드 안(또는 스케줄러 스레드에서 Orleans 안에서 실행되는 다른 코드)에서 원래 클라이언트 요청의 추적 ID를 사용할 수 있습니다.
Logger.LogInformation(
"Currently processing external request {TraceId}",
RequestContext.Get("TraceId"));
직렬화 가능 object
개체는 애플리케이션 메타데이터로 전송될 수 있지만, 크거나 복잡한 개체는 메시지 serialization 시간에 눈에 띄는 오버헤드를 추가할 수 있음을 언급할 가치가 있습니다. 이러한 이유로 단순 형식(문자열, GUID 또는 숫자 형식)을 사용하는 것이 좋습니다.
예제 곡물 코드
요청 컨텍스트의 사용을 설명하는 데 도움이 되도록 다음 예제 곡물 코드를 고려하세요.
using GrainInterfaces;
using Microsoft.Extensions.Logging;
namespace Grains;
public class HelloGrain(ILogger<HelloGrain> logger) : Grain, IHelloGrain
{
ValueTask<string> IHelloGrain.SayHello(string greeting)
{
_logger.LogInformation("""
SayHello message received: greeting = "{Greeting}"
""",
greeting);
var traceId = RequestContext.Get("TraceId") as string
?? "No trace ID";
return ValueTask.FromResult($"""
TraceID: {traceId}
Client said: "{greeting}", so HelloGrain says: Hello!
""");
}
}
public interface IHelloGrain : IGrainWithStringKey
{
ValueTask<string> SayHello(string greeting);
}
메서드는 SayHello
들어오는 greeting
매개 변수를 기록한 다음 요청 컨텍스트에서 추적 ID를 검색합니다. 추적 ID가 없으면 그레인은 "추적 ID 없음"을 기록합니다.
예제 클라이언트 코드
클라이언트에서 메서드를 호출하기 전에 요청 컨텍스트에서 추적 ID를 SayHello
설정할 수 있습니다 HelloGrain
. 다음 클라이언트 코드는 요청 컨텍스트에서 추적 ID를 설정하고 다음에서 메서드HelloGrain
를 호출하는 SayHello
방법을 보여 줍니다.
using GrainInterfaces;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using var host = Host.CreateDefaultBuilder(args)
.UseOrleansClient(clientBuilder =>
clientBuilder.UseLocalhostClustering())
.Build();
await host.StartAsync();
var client = host.Services.GetRequiredService<IClusterClient>();
var grain = client.GetGrain<IHelloGrain>("friend");
var id = "example-id-set-by-client";
RequestContext.Set("TraceId", id);
var message = await friend.SayHello("Good morning!");
Console.WriteLine(message);
// Output:
// TraceID: example-id-set-by-client
// Client said: "Good morning!", so HelloGrain says: Hello!
이 예제에서 클라이언트는 메서드를 호출 SayHello
HelloGrain
하기 전에 추적 ID를 "example-id-set-by-client"로 설정합니다. 그레인은 요청 컨텍스트에서 추적 ID를 검색하고 기록합니다.
.NET