Silky微服务框架在线文档Silky微服务框架在线文档
首页
文档
配置
源码解析
博文
github
gitee
首页
文档
配置
源码解析
博文
github
gitee
  • 启动时

    • 主机的构建
    • 服务引擎
    • 模块
    • 服务与服务条目的解析
    • Silky服务主机
    • 依赖注入约定
    • RPC 服务代理
  • 运行时

    • 终结点与路由
    • 执行器与调度
    • 本地执行器与服务端过滤器
    • 远程执行器与 RPC 调用
    • RPC 服务端消息处理
    • 服务治理
    • 缓存拦截器
    • 分布式事务(TCC)
    • HTTP 网关请求管道
    • 过滤器执行管道
    • Polly 弹性策略管道
    • 端点健康监控

概述

当一个服务条目被判定为本地执行(IsLocal = true)时,框架通过 本地执行器(ILocalExecutor) 完成实际的业务方法调用。本地执行的核心特点是:

  • 在调用业务方法之前和之后,执行服务端过滤器管道(Server Filter Pipeline)
  • 过滤器支持异步和同步两种接口,框架通过状态机驱动管道执行,与 ASP.NET Core 的 ActionFilter 机制高度相似
  • 支持身份认证过滤、异常过滤、结果过滤等多种类型

DefaultLocalExecutor — 本地执行入口

DefaultLocalExecutor 是 ILocalExecutor 的默认实现:

public class DefaultLocalExecutor : ILocalExecutor
{
    private readonly IServerLocalInvokerFactory _serverLocalInvokerFactory;

    public async Task<object> Execute(ServiceEntry serviceEntry, object[] parameters, string? serviceKey = null)
    {
        // 1. 根据 serviceKey 解析服务实现类实例(支持多实现路由)
        var instance = EngineContext.Current.ResolveServiceInstance(serviceKey, serviceEntry.ServiceType);

        // 2. 构建 ServiceEntryContext(封装 ServiceEntry、参数、实现实例)
        // 3. 通过工厂创建 LocalInvoker(含过滤器链)
        var localInvoker =
            _serverLocalInvokerFactory.CreateInvoker(
                new ServiceEntryContext(serviceEntry, parameters, serviceKey, instance));

        // 4. 执行过滤器管道 + 业务方法
        await localInvoker.InvokeAsync().ConfigureAwait(false);

        // 5. 返回执行结果
        return localInvoker.Result;
    }
}

关键步骤解析:

  1. 多实现路由(ServiceKey):通过 ResolveServiceInstance(serviceKey, serviceType) 根据 serviceKey 从 IoC 容器中解析对应的实现类实例。当同一接口有多个实现时,不同的实现通过 ServiceKey 区分。
  2. ServiceEntryContext:这是贯穿整个本地调用过程的上下文对象,包含服务条目元数据、解析后的参数数组、目标实现类实例。
  3. LocalInvoker 工厂:由 IServerLocalInvokerFactory 负责创建 LocalInvoker,工厂在创建时会扫描并排序所有适用的服务端过滤器。

ServiceEntryContext — 调用上下文

ServiceEntryContext 是本地调用的"会话"对象,在整个过滤器管道中流转:

属性类型说明
ServiceEntryServiceEntry当前服务条目元数据(包含路由、参数描述符、治理参数等)
Parametersobject[]已解析的参数数组(与方法签名顺序一致)
ServiceKeystring?本次调用使用的服务键(用于多实现路由)
Instanceobject业务实现类的实例
Resultobject调用完成后的返回值

IServiceEntryContextAccessor 是线程安全的上下文访问器(基于 AsyncLocal<T>),允许过滤器或业务代码在任意位置访问当前调用的上下文。


服务端过滤器类型

silky 服务端过滤器体系与 ASP.NET Core 的 ActionFilter 设计保持一致,提供以下几种过滤器类型:

1. 身份认证过滤器(Authorization Filter)

public interface IAsyncServerAuthorizationFilter : IServerFilterMetadata
{
    Task OnAuthorizationAsync(ServerAuthorizationFilterContext context);
}

public interface IServerAuthorizationFilter : IServerFilterMetadata
{
    void OnAuthorization(ServerAuthorizationFilterContext context);
}
  • 最先执行(在 Action 过滤器和结果过滤器之前)
  • 如果鉴权失败,将 context.Result 设置为非空值可短路后续执行
  • silky 框架内置了基于 [Authorize] 特性的身份认证过滤器

2. Action 过滤器(Server Filter)

public interface IAsyncServerFilter : IServerFilterMetadata
{
    Task OnActionExecutionAsync(ServerInvokeExecutingContext context, ServerExecutionDelegate next);
}

public interface IServerFilter : IServerFilterMetadata
{
    void OnActionExecuting(ServerInvokeExecutingContext context);
    void OnActionExecuted(ServerInvokeExecutedContext context);
}
  • 在业务方法执行前后各触发一次
  • OnActionExecuting(或异步的 OnActionExecutionAsync 中 await next() 之前):可修改参数、执行前置逻辑
  • OnActionExecuted(或 await next() 之后):可访问返回值、处理异常
  • 在 OnActionExecuting 中设置 context.Result 可短路后续过滤器和业务方法

3. 异常过滤器(Exception Filter)

public interface IAsyncServerExceptionFilter : IServerFilterMetadata
{
    Task OnExceptionAsync(ServerInvokeExceptionContext context);
}

public interface IServerExceptionFilter : IServerFilterMetadata
{
    void OnException(ServerInvokeExceptionContext context);
}
  • 当业务方法或后续过滤器抛出未处理异常时执行
  • 可通过将 context.ExceptionHandled = true 标记异常已被处理,阻止异常继续传播
  • silky 内置的参数验证(ValidationException)、UserFriendlyException 等友好异常的格式化均通过异常过滤器实现

4. 结果过滤器(Result Filter)

public interface IAsyncServerResultFilter : IServerFilterMetadata
{
    Task OnResultExecutionAsync(ServerResultExecutingContext context, ServerResultExecutionDelegate next);
}

// 始终运行(即使发生短路)的结果过滤器
public interface IAsyncAlwaysRunServerResultFilter : IAsyncServerResultFilter { }
  • 在业务方法执行成功后、结果写入响应之前触发
  • IAsyncAlwaysRunServerResultFilter 即使 Action 过滤器或身份认证过滤器发生短路,也会执行
  • 常用于响应格式转换、结果后处理

过滤器执行状态机

LocalInvokerBase 采用**状态机(State Machine)**驱动整个过滤器管道,这是对 ASP.NET Core 源码模式的复用。状态机通过 State 枚举逐步推进:

State.ActionBegin
    │  参数绑定(BindArgumentsAsync)
    ▼
State.AuthorizationBegin
    │  依次执行身份认证过滤器
    │  任意过滤器设置 context.Result → 短路至 State.AuthorizationShortCircuit
    ▼
State.ActionBegin(实际执行过滤器链)
    │
    ├─ State.ActionExecutionFilter(每个 Server Filter)
    │      OnActionExecuting → 设置 context.Result 则短路
    │      await next() → 执行下一个过滤器或业务方法
    │      OnActionExecuted
    │
    ▼
State.ActionInside(执行业务方法)
    │  调用 ObjectMethodExecutor.ExecuteAsync(instance, parameters)
    │  将结果存入 context.Result
    ▼
State.ResultBegin(执行结果过滤器)
    │
    ├─ State.ResultExecutionFilter(每个 Result Filter)
    │      OnResultExecuting → await next() → OnResultExecuted
    │
    ▼
State.InvokeEnd
    │  将最终 result 写回 localInvoker.Result 供调用方获取

短路机制

当任一过滤器决定短路(设置 context.Result 不调用 next())时:

  • Action 过滤器管道停止继续推进
  • 仍然执行已进入过滤器链中 OnActionExecuted(已执行过 OnActionExecuting 的过滤器)
  • IAsyncAlwaysRunServerResultFilter 无论短路与否都会运行

过滤器的注册与排序

全局注册

在模块的 ConfigureServices 中通过 AddServerFilter<T>() 注册全局服务端过滤器:

services.AddServerFilter<MyGlobalFilter>();

特性方式注册(方法级)

在服务接口方法上标注派生自 ServerFilterAttribute 的特性,实现方法级过滤器:

public interface IOrderAppService
{
    [MyServerFilter]  // 只对这个方法生效
    Task<OrderDto> CreateAsync(CreateOrderInput input);
}

排序规则

过滤器按 Order 属性从小到大排序(默认 Order = 0)。同 Order 时,全局过滤器先于方法特性过滤器执行。

[AttributeUsage(AttributeTargets.Method)]
public class MyServerFilter : ServerFilterAttribute, IAsyncServerFilter
{
    public override int Order => -100; // 越小越先执行
    
    public async Task OnActionExecutionAsync(ServerInvokeExecutingContext context, ServerExecutionDelegate next)
    {
        // Before
        await next();
        // After
    }
}

ObjectMethodExecutor — 业务方法执行

ServiceEntry 内部持有一个 ObjectMethodExecutor(来自 Silky.Core.MethodExecutor),它封装了对业务方法的高效反射调用,并特别针对以下返回类型做了处理:

返回类型处理方式
Task<T>await executor.ExecuteAsync() 取 Result
ValueTask<T>解包为 Task<T> 后 await
Taskawait 后返回 null
同步方法包装为 Task.FromResult() 统一处理

这样业务方法无论是同步还是异步,对过滤器管道都表现出统一的异步接口。


缓存拦截器(CachingInterceptor)

silky 支持在服务条目上声明分布式缓存拦截,通过 [GetCachingIntercept]、[UpdateCachingIntercept]、[RemoveCachingIntercept] 等特性实现:

public interface IOrderAppService
{
    [GetCachingIntercept("order:{id}")]
    Task<OrderDto> GetByIdAsync(long id);
    
    [UpdateCachingIntercept("order:{id}")]
    Task<OrderDto> UpdateAsync(long id, UpdateOrderInput input);
    
    [RemoveCachingIntercept("order:{id}")]
    Task DeleteAsync(long id);
}

缓存拦截通过 Silky.Rpc.CachingInterceptor 包实现,在本地执行之前先查缓存;命中则直接返回,不进入过滤器管道和业务方法。缓存的 key 模板支持参数占位符(如 {id}),框架在运行时从参数中动态提取值。


完整执行序列图

本地调用请求
    │
    ▼
DefaultLocalExecutor
    │  ResolveServiceInstance(serviceKey)
    │
    ▼
ServiceEntryContext 创建
    │
    ▼
LocalInvoker(服务端过滤器链)
    │
    ├── [Auth Filter 1] OnAuthorizationAsync
    ├── [Auth Filter N] OnAuthorizationAsync
    │
    ├── [Server Filter 1] OnActionExecutingAsync ──────────┐
    ├── [Server Filter N] OnActionExecutingAsync ─────┐    │
    │                                                 │    │
    │   ObjectMethodExecutor.ExecuteAsync()           │    │
    │   (执行业务实现类方法)                          │    │
    │                                                 │    │
    ├── [Server Filter N] OnActionExecutedAsync  ─────┘    │
    ├── [Server Filter 1] OnActionExecutedAsync ───────────┘
    │
    ├── [Result Filter 1] OnResultExecutingAsync
    │   ......
    ├── [Result Filter N] OnResultExecutedAsync
    │
    ▼
LocalInvoker.Result(返回给调用方)
编辑当前页
Prev
执行器与调度
Next
远程执行器与 RPC 调用