目录
1. Orleans 序列化机制
1.1 序列化架构概述
Orleans 采用多层次的序列化架构,支持多种序列化方式:
1.2 核心序列化接口
IFieldCodec 接口
public interface IFieldCodec<T> : IFieldCodec
{
// 写入字段到缓冲区
void WriteField<TBufferWriter>(ref Writer<TBufferWriter> writer,
uint fieldIdDelta, Type expectedType, T value)
where TBufferWriter : IBufferWriter<byte>;
// 从缓冲区读取值
new T ReadValue<TInput>(ref Reader<TInput> reader, Field field);
}
关键特性:
- 泛型设计:每个类型都有专门的编解码器
- 缓冲区优化:使用
IBufferWriter<byte>进行高效的内存操作 - 字段标识:通过
fieldIdDelta进行字段标识和版本控制
1.3 序列化方式对比
| 序列化方式 | 性能 | 内存效率 | 可读性 | 配置复杂度 | 适用场景 |
|---|---|---|---|---|---|
| 默认序列化 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐ | ⭐⭐⭐ | 高性能要求 |
| System.Text.Json | ⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | 跨系统交互 |
| Newtonsoft.Json | ⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | 复杂JSON需求 |
| 自定义编解码器 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐ | ⭐ | 特殊需求 |
1.4 序列化流程
1.5 序列化配置示例
默认序列化配置
[GenerateSerializer]
public class ChatMessage
{
[Id(0)] public string Content { get; set; }
[Id(1)] public DateTime Timestamp { get; set; }
[Id(2)] public string SenderId { get; set; }
}
JSON 序列化配置
builder.Services.AddSerializer(serializerBuilder =>
{
serializerBuilder.AddJsonSerializer(
isSupported: type => type.Namespace?.StartsWith("MyApp.Models") == true,
jsonSerializerOptions: new JsonSerializerOptions
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
WriteIndented = true
});
});
2. Actor Placement 策略
2.1 Placement 架构概述
Orleans 的 Placement 系统负责决定 Grain 实例在哪个 Silo 上激活:
2.2 核心 Placement 接口
PlacementStrategy 基类
public abstract class PlacementStrategy
{
// 是否使用 Grain Directory
public virtual bool IsUsingGrainDirectory => true;
// 初始化策略
public virtual void Initialize(GrainProperties properties) { }
// 填充 Grain 属性
public virtual void PopulateGrainProperties(IServiceProvider services,
Type grainClass, GrainType grainType, Dictionary<string, string> properties)
{
properties[WellKnownGrainTypeProperties.PlacementStrategy] = this.GetType().Name;
}
}
IPlacementDirector 接口
public interface IPlacementDirector
{
Task<SiloAddress> OnAddActivation(PlacementStrategy strategy,
PlacementTarget target, IPlacementContext context);
}
2.3 主要 Placement 策略
2.3.1 RandomPlacement(随机放置)
public class RandomPlacement : PlacementStrategy
{
public static RandomPlacement Singleton { get; } = new();
public override bool IsUsingGrainDirectory => false;
}
特点:
- 随机选择 Silo
- 不使用 Grain Directory
- 适用于无状态或可重复创建的 Grain
2.3.2 HashBasedPlacement(基于哈希放置)
public class HashBasedPlacement : PlacementStrategy
{
public static HashBasedPlacement Singleton { get; } = new();
}
特点:
- 基于 Grain ID 的哈希值选择 Silo
- 相同 Grain ID 总是路由到同一个 Silo
- 适用于有状态的 Grain
2.3.3 PreferLocalPlacement(优先本地放置)
public class PreferLocalPlacement : PlacementStrategy
{
public static PreferLocalPlacement Singleton { get; } = new();
}
特点:
- 优先选择本地 Silo
- 如果本地 Silo 不可用,则选择其他 Silo
- 减少网络延迟
2.3.4 ResourceOptimizedPlacement(资源优化放置)
public class ResourceOptimizedPlacement : PlacementStrategy
{
public ResourceOptimizedPlacementOptions Options { get; set; }
}
特点:
- 基于 Silo 的资源使用情况选择
- 考虑 CPU、内存等资源指标
- 实现负载均衡
2.4 Placement 流程
2.5 Placement 配置示例
// 使用特性配置 Placement 策略
[HashBasedPlacement]
public class UserGrain : Grain, IUserGrain
{
// Grain 实现
}
[PreferLocalPlacement]
public class CacheGrain : Grain, ICacheGrain
{
// Grain 实现
}
// 通过配置配置 Placement 策略
builder.Configure<GrainTypeOptions>(options =>
{
options.ConfigureGrainType<UserGrain>(grainType =>
{
grainType.PlacementStrategy = HashBasedPlacement.Singleton;
});
});
3. Actor 调用机制
3.1 Actor 调用架构
Orleans 的 Actor 调用采用异步消息传递模式:
3.2 核心调用接口
IGrainReferenceRuntime 接口
public interface IGrainReferenceRuntime
{
// 异步调用方法
ValueTask<T> InvokeMethodAsync<T>(GrainReference reference,
IInvokable request, InvokeMethodOptions options);
// 异步调用无返回值方法
ValueTask InvokeMethodAsync(GrainReference reference,
IInvokable request, InvokeMethodOptions options);
// 单向调用
void InvokeMethod(GrainReference reference,
IInvokable request, InvokeMethodOptions options);
}
IInvokable 接口
public interface IInvokable
{
// 设置目标 Grain
void SetTarget(IGrainContext target);
// 执行调用
Task<Response> Invoke();
// 获取方法信息
MethodInfo GetMethod();
string GetInterfaceName();
string GetMethodName();
}
3.3 调用流程详解
3.3.1 客户端调用流程
// 1. 创建 Grain 引用
var userGrain = grainFactory.GetGrain<IUserGrain>(userId);
// 2. 调用方法
var result = await userGrain.GetUserInfo();
3.3.2 服务端调用处理
public class GrainMethodInvoker : IIncomingGrainCallContext
{
public async Task Invoke()
{
// 1. 执行系统级过滤器
for (int i = 0; i < filters.Count; i++)
{
await filters[i].Invoke(this);
}
// 2. 执行 Grain 级过滤器
if (Grain is IIncomingGrainCallFilter grainFilter)
{
await grainFilter.Invoke(this);
}
// 3. 执行实际方法
Response = await request.Invoke();
// 4. 复制响应
Response = responseCopier.Copy(Response);
}
}
3.4 调用过滤器链
Orleans 支持多层过滤器链:
过滤器接口
public interface IIncomingGrainCallFilter
{
Task Invoke(IIncomingGrainCallContext context);
}
public interface IOutgoingGrainCallFilter
{
Task Invoke(IOutgoingGrainCallContext context);
}
3.5 调用配置示例
配置调用过滤器
// 系统级过滤器
builder.AddIncomingGrainCallFilter<LoggingFilter>();
builder.AddIncomingGrainCallFilter<AuthenticationFilter>();
// Grain 级过滤器
public class UserGrain : Grain, IUserGrain, IIncomingGrainCallFilter
{
public async Task Invoke(IIncomingGrainCallContext context)
{
// 前置处理
Console.WriteLine($"调用方法: {context.MethodName}");
// 继续调用链
await context.Invoke();
// 后置处理
Console.WriteLine($"方法调用完成");
}
}
4. 综合架构分析
4.1 整体架构图
4.2 关键设计模式
4.2.1 策略模式(Placement)
- 不同的 Placement 策略可以灵活切换
- 支持自定义 Placement 策略
4.2.2 责任链模式(调用过滤器)
- 多层过滤器链处理调用
- 支持横切关注点(日志、认证、监控等)
4.2.3 工厂模式(序列化器)
- 根据类型选择合适的序列化器
- 支持多种序列化方式
4.3 性能优化策略
4.3.1 序列化优化
- 编译时生成序列化代码
- 使用缓冲区减少内存分配
- 支持零拷贝操作
4.3.2 Placement 优化
- 缓存 Grain 位置信息
- 支持本地优先策略
- 基于资源的智能放置
4.3.3 调用优化
- 异步非阻塞调用
- 批量消息处理
- 连接池和复用
4.4 扩展性设计
4.4.1 序列化扩展
// 自定义编解码器
[RegisterSerializer]
public class CustomCodec : IFieldCodec<MyType>
{
public void WriteField<TBufferWriter>(ref Writer<TBufferWriter> writer,
uint fieldIdDelta, Type expectedType, MyType value)
where TBufferWriter : IBufferWriter<byte>
{
// 自定义序列化逻辑
}
public MyType ReadValue<TInput>(ref Reader<TInput> reader, Field field)
{
// 自定义反序列化逻辑
}
}
4.4.2 Placement 扩展
// 自定义 Placement 策略
public class CustomPlacementStrategy : PlacementStrategy
{
public override void PopulateGrainProperties(IServiceProvider services,
Type grainClass, GrainType grainType, Dictionary<string, string> properties)
{
properties[WellKnownGrainTypeProperties.PlacementStrategy] = "Custom";
}
}
// 自定义 Placement Director
public class CustomPlacementDirector : IPlacementDirector
{
public Task<SiloAddress> OnAddActivation(PlacementStrategy strategy,
PlacementTarget target, IPlacementContext context)
{
// 自定义放置逻辑
}
}
4.5 最佳实践
4.5.1 序列化最佳实践
- 优先使用默认序列化:性能最优
- 合理使用 JSON 序列化:跨系统交互
- 避免循环引用:使用
[Id]特性 - 版本兼容性:考虑序列化版本控制
4.5.2 Placement 最佳实践
- 选择合适的策略:根据 Grain 特性选择
- 避免过度使用 PreferLocal:可能导致负载不均
- 监控 Placement 效果:使用指标监控
- 考虑故障转移:设计容错机制
4.5.3 调用最佳实践
- 使用异步调用:避免阻塞
- 合理使用过滤器:避免过度使用
- 错误处理:完善的异常处理机制
- 超时控制:设置合理的超时时间
总结
Orleans 的序列化、Placement 和 Actor 调用机制构成了一个完整的分布式 Actor 系统:
- 序列化机制:提供高性能、多格式的数据序列化能力
- Placement 策略:智能决定 Actor 实例的放置位置
- 调用机制:支持异步、过滤的 Actor 方法调用
这三个机制协同工作,为 Orleans 提供了高性能、可扩展、易用的分布式 Actor 编程模型。通过合理的配置和使用,可以构建出高性能的分布式应用程序。


被折叠的 条评论
为什么被折叠?



