主机
主机是封装应用资源的对象,用于托管应用和管理应用的生命周期。silky 框架提供了四种主机类型:
- 通用主机:用于托管只对内部提供 RPC 服务的业务微服务,不暴露 HTTP 端口,集群外部无法直接访问
- Web 主机:同时提供 HTTP 服务和 RPC 服务,可作为外部访问入口,也可作为 RPC 服务提供者
- WebSocket 主机:在通用主机基础上增加 WebSocket 服务能力,可向客户端推送消息
- 网关主机:只提供 HTTP 服务,作为集群的统一流量入口,只能作为服务消费者,不能作为 RPC 服务提供者
应用服务接口
应用服务接口(Application Service Interface)是标注了 [ServiceRoute] 特性的 C# 接口,是 silky 微服务对外暴露能力的契约定义。
应用服务接口承担以下职责:
- 定义对外暴露的方法签名(RPC 契约)
- 通过 HTTP 路由属性(
[HttpGet]、[HttpPost]等)声明 Web API 路由规则 - 被框架用于自动生成 RPC 代理(服务消费者侧)
- 被框架用于生成 Swagger 文档
应用服务接口通常放置在 *.Application.Contracts 项目中,与具体实现分离,供其他微服务引用调用。
[ServiceRoute]
public interface IOrderAppService
{
[HttpPost]
Task<CreateOrderOutput> CreateAsync(CreateOrderInput input);
[HttpGet("{id:long}")]
Task<OrderOutput> GetAsync(long id);
}
路由
路由是指通过 WebAPI路径 + HTTP请求方法 或者通过 服务条目Id 在路由表中查找相应服务条目信息的过程。
- 在网关应用中,通过
WebAPI路径+HTTP请求方法查找服务条目 - 在业务微服务应用中,通过
服务条目Id(ServiceEntryId)查找服务条目
服务条目
每个应用服务接口的方法都会生成一个对应的服务条目(Service Entry)。框架在启动时扫描所有标注了 [ServiceRoute] 的接口,为每个方法(及其 HTTP 谓词组合)创建一个服务条目对象,包含路由模板、治理策略、参数信息等元数据。
每个服务条目有两个唯一标识:
- 服务 Id(
ServiceId):接口类型的完全限定名,标识一个应用服务接口 - 服务条目 Id(
ServiceEntryId):方法级别的唯一标识,含参数名和 HTTP 谓词
在应用启动时,服务实例会向注册中心注册本机所有服务条目对应的端点地址,供消费者发现和调用。
路由表
由服务条目组成的集合。微服务集群的路由表会根据服务实例的启动(注册)和停止(注销)得到更新。
在微服务应用实例启动时,会自动注册或更新服务注册中心中该服务条目的地址信息。同时,订阅了服务条目的其他微服务应用也会在内存中更新相应的路由表。
服务注册中心
主要用于保存微服务集群的路由表信息,会根据服务提供者实例的启动(注册)和停止(注销)更新服务条目的地址列表。silky 支持 Zookeeper、Nacos、Consul 三种注册中心。
RPC
RPC 全称 Remote Procedure Call——远程过程调用。是为了解决远程调用服务的一种技术,使得调用者像调用本地服务一样方便透明。简单来说,RPC 就是从一台机器(客户端)上通过参数传递的方式调用另一台机器(服务器)上的一个函数或方法,并得到返回结果。
silky 框架基于 DotNetty 实现了 TCP 长连接 RPC 通信,通过 Autofac 动态代理屏蔽底层通信细节,实现本地透明调用。
服务提供者
在 RPC 通信过程中,负责提供服务接口定义和服务实现类,作为服务端的一方。
服务消费者/服务调用者
在 RPC 通信过程中,通过应用服务接口动态生成本地代理,并通过代理发起网络请求与服务提供者进行通信,将结果返回给调用者的一方。
提示
对于一个业务微服务应用而言,它在集群中既可以作为服务提供者,也可以是服务消费者,主要取决于在某次 RPC 通信过程中是提供服务的一方还是调用服务的一方。
端点
端点(RpcEndpoint)是一个服务实例对外提供 RPC 服务的网络地址信息,包含主机地址(IP)、端口和服务类型(Rpc / WebSocket)。
当一个微服务实例启动时,框架会将该实例的端点信息注册到服务注册中心;实例停止时,自动注销。消费者在发起 RPC 调用时,会根据负载均衡策略从路由表的端点列表中选择一个合适的端点建立连接。
RPC 上下文
RPC 上下文(RpcContext)是一个随 RPC 调用链路自动传递的上下文容器,用于在分布式调用链中共享附加信息(附件),例如:
- 用户身份(用户 Id、用户名、租户 Id 等)
- 分布式追踪信息(TraceId)
- 调用方地址信息
- 审计日志动作信息
无论 RPC 调用经过多少个服务节点,RpcContext 都会通过请求头自动传播,无需开发者手动传递。网关在验证 JWT Token 后,会将 Claims 信息写入 RpcContext,供链路中所有微服务通过 NullSession.Instance 读取。
服务治理
服务治理主要针对分布式微服务框架,处理服务调用之间的关系,包括:服务发布和发现、负载均衡、容错(熔断、限流、降级、超时重试)、安全认证、监控可观测性等。
silky 框架已实现的服务治理能力包括:
- ✅ 服务注册与发现(支持 Zookeeper / Nacos / Consul)
- ✅ 负载均衡(轮询 / 随机 / 哈希一致性)
- ✅ 超时控制
- ✅ 故障转移(失败重试)
- ✅ 熔断保护
- ✅ RPC 限流 / HTTP 限流
- ✅ 服务降级(Fallback)
- ✅ RPC Token 安全保护
服务键
服务键(Service Key)是 silky 框架支持同一应用服务接口拥有多个实现类的机制。通过 [ServiceKey("name")] 特性标注实现类,消费者在调用时可以通过 [ServiceKeyed("name")] 指定要调用哪个具体实现,实现多态路由。
该功能常见于需要针对不同场景(如不同支付渠道、不同存储策略)提供差异化实现的场景。
缓存拦截
在 RPC 通信过程中,为减少网络请求、提高分布式应用的性能,如果数据已经被缓存,则直接从缓存服务中获取相应的数据并返回给服务调用者,无需真正发起远程调用。
缓存拦截通过在应用服务接口方法上标注 [GetCachingIntercept]、[UpdateCachingIntercept]、[RemoveCachingIntercept] 等特性来声明,框架会在调用链中自动处理缓存的读取、更新和删除。
工作单元
工作单元(Unit of Work,UoW)是一种数据库事务管理模式,将一次业务操作中涉及的所有数据库变更聚合在同一个事务中,要么全部提交,要么全部回滚。
在 silky 框架中,通过在服务方法上标注 [UnitOfWork] 特性来声明事务边界:
- 方法正常完成时,框架自动提交事务
- 方法抛出异常时,框架自动回滚事务
该特性同样支持标注在 MassTransit 的 SilkyConsumer<T> 消费方法上,确保消息消费的原子性。
服务条目 Id
服务条目 Id(ServiceEntryId)是每个服务条目的方法级唯一标识,生成规则为:
ServiceEntryId = 接口完全限定名.方法名[.参数名1.参数名2...]:{HTTP谓词}
例如:
Silky.Sample.IGreetingAppService.Say.line:Get
其中:
Silky.Sample.IGreetingAppService— 接口的完全限定名(命名空间 + 接口名)Say— 方法名line— 参数名(方法有多个参数时以.分隔依次列出)Get— HTTP 谓词
短名称模式
当配置了 UsingServiceShortName: true 时,接口完全限定名会简化为服务路由名称([ServiceRoute] 中定义的路径段),减少 Id 长度。
服务 Id(ServiceId)与服务条目 Id 不同,它是接口类型的完全限定名(如 Silky.Sample.IGreetingAppService),标识整个应用服务接口,而非具体的某个方法。
