主机的概念
silky 的主机概念与 .NET 的主机概念一致,是封装应用资源的对象,用于托管应用和管理应用的生命周期。
silky 根据业务场景的不同,提供了四种主机类型:
| 主机类型 | 构建方法 | RPC 服务提供 | HTTP 服务 | WebSocket |
|---|---|---|---|---|
| Web 主机 | ConfigureSilkyWebHostDefaults | ✅ | ✅ | ❌ |
| 通用主机 | ConfigureSilkyGeneralHostDefaults | ✅ | ❌ | ❌ |
| WebSocket 主机 | ConfigureSilkyWebSocketDefaults | ✅ | ❌ | ✅ |
| 网关主机 | ConfigureSilkyGatewayDefaults | ❌ | ✅ | ❌ |
所有主机类型均通过安装 Silky.Agent.Host NuGet 包来使用。
业务主机类型
使用 Web 主机构建微服务应用
使用 Web 主机构建的 silky 应用具有如下特性:
- 同时提供 HTTP 服务和 RPC 服务,暴露 HTTP 端口和 RPC 端口
- 可以作为外部流量的入口,集群外部通过 HTTP 服务访问微服务应用集群
- 作为 RPC 服务提供者,通过 RPC 框架与其他微服务进行通信

这种方式适合希望同时对外提供 HTTP 接口、对内参与 RPC 通信的微服务,也适合在不引入独立网关的中小型项目中使用。
使用默认 Web 主机模块
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
namespace Silky.Sample
{
public class Program
{
public static async Task Main(string[] args)
{
await CreateHostBuilder(args).Build().RunAsync();
}
private static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureSilkyWebHostDefaults(webBuilder => webBuilder.UseStartup<Startup>());
}
}
使用自定义启动模块
如果需要依赖自定义模块,可以通过 ConfigureSilkyWebHost<T> 指定自定义启动模块(需继承 WebHostModule):
private static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureSilkyWebHost<DemoModule>(webBuilder => webBuilder.UseStartup<Startup>());
自定义模块 DemoModule 示例:
// 通过 [DependsOn] 声明对其他模块的依赖
// [DependsOn(typeof(UserDefinedModule))]
public class DemoModule : WebHostModule
{
public override Task Initialize(ApplicationInitializationContext context)
{
// 应用启动后执行的初始化逻辑
return Task.CompletedTask;
}
public override Task Shutdown(ApplicationShutdownContext context)
{
// 应用停止前执行的清理逻辑
return Task.CompletedTask;
}
public override void ConfigureServices(IServiceCollection services, IConfiguration configuration)
{
// 与 Startup.ConfigureServices 作用相同,适合在模块中统一注册服务
}
protected override void RegisterServices(ContainerBuilder builder)
{
// 通过 Autofac ContainerBuilder 注册服务
// 优势:支持命名服务等 IServiceCollection 不支持的场景
}
}
在 Startup.cs 中配置服务和中间件
public class Startup
{
public IConfiguration Configuration { get; }
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public void ConfigureServices(IServiceCollection services)
{
services
.AddSilkyHttpCore() // Silky HTTP 核心服务(必须)
.AddSwaggerDocuments() // Swagger 在线文档
.AddRouting()
.AddSilkyIdentity() // JWT 身份认证(可选)
.AddSilkyMiniProfiler(); // 性能分析(可选)
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseSwaggerDocuments();
app.UseMiniProfiler();
}
app.UseRouting();
app.UseSilkyIdentity(); // 启用身份认证中间件(可选)
app.UseSilkyWebSocketsProxy(); // 启用 WebSocket 代理(如需转发 ws 请求)
app.UseEndpoints(endpoints =>
{
endpoints.MapSilkyRpcServices(); // 映射 Silky 服务条目路由(必须)
});
}
}
使用通用主机构建微服务应用
使用通用主机构建的 silky 应用具有如下特性:
- 只提供 RPC 服务,不提供 HTTP 服务,集群外部无法直接访问
- 必须通过网关或具有 HTTP 服务的微服务间接访问
- 资源占用更少,适合纯后端业务逻辑服务

使用默认通用主机模块
using Microsoft.Extensions.Hosting;
var hostBuilder = Host.CreateDefaultBuilder(args)
.ConfigureSilkyGeneralHostDefaults();
await hostBuilder.Build().RunAsync();
使用自定义启动模块
private static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureSilkyGeneralHost<DemoModule>();
自定义模块需继承 GeneralHostModule(注意与 Web 主机的 WebHostModule 区分):
// [DependsOn(typeof(UserDefinedModule))]
public class DemoModule : GeneralHostModule
{
public override Task Initialize(ApplicationInitializationContext context)
{
return Task.CompletedTask;
}
public override Task Shutdown(ApplicationShutdownContext context)
{
return Task.CompletedTask;
}
public override void ConfigureServices(IServiceCollection services, IConfiguration configuration)
{
// 注册服务
}
protected override void RegisterServices(ContainerBuilder builder)
{
// 通过 Autofac 注册服务
}
}
注意
通用主机不提供 HTTP 服务,因此无法配置 HTTP 中间件(配置了也不生效)。
通用主机中通过 IConfigureService 接口注册服务:
public class ConfigureService : IConfigureService
{
public void ConfigureServices(IServiceCollection services, IConfiguration configuration)
{
services
.AddSilkySkyApm() // SkyAPM 链路追踪(可选)
.AddMessagePackCodec(); // MessagePack 编解码(可选)
// 集成 EFCore
services.AddDatabaseAccessor(
options => { options.AddDbPool<DefaultContext>(); },
"Demo.Database.Migrations");
// 集成消息总线(CAP、MassTransit 等)
// services.AddCap(x => { ... });
}
public int Order => 1; // 多个 IConfigureService 时通过 Order 控制执行顺序
}
构建具有 WebSocket 服务能力的微服务应用
具有 WebSocket 服务能力的微服务应用具有如下特性:
- 同时提供 RPC 服务和 WebSocket 服务(WebSocket 默认端口
3000) - 可以通过网关的 WebSocket 代理中间件与该微服务的 WebSocket 服务进行握手
- 服务端可主动向客户端推送消息

构建 WebSocket 主机
using Microsoft.Extensions.Hosting;
var hostBuilder = Host.CreateDefaultBuilder(args)
.ConfigureSilkyWebSocketDefaults();
await hostBuilder.Build().RunAsync();
使用自定义启动模块
自定义模块需继承 WebSocketHostModule:
// [DependsOn(typeof(UserDefinedModule))]
public class DemoModule : WebSocketHostModule
{
public override Task Initialize(ApplicationContext applicationContext)
{
return Task.CompletedTask;
}
public override Task Shutdown(ApplicationContext applicationContext)
{
return Task.CompletedTask;
}
}
实现 WebSocket 服务
提供 WebSocket 服务的实现类需要继承 WsAppServiceBase,在建立会话后可通过 SessionManager 向客户端推送消息:
public class TestAppService : WsAppServiceBase, ITestAppService
{
private readonly ILogger<TestAppService> _logger;
public TestAppService(ILogger<TestAppService> logger)
{
_logger = logger;
}
// 建立 WebSocket 会话时触发
protected override void OnOpen()
{
base.OnOpen();
_logger.LogInformation("WebSocket session established, SessionId: {SessionId}", ID);
}
// 收到客户端消息时触发
protected override void OnMessage(MessageEventArgs e)
{
_logger.LogInformation("Received: {Message}", e.Data);
// 向当前客户端回送消息
Send($"Server received: {e.Data}");
}
// 会话关闭时触发
protected override void OnClose(CloseEventArgs e)
{
base.OnClose(e);
_logger.LogInformation("WebSocket session closed, reason: {Reason}", e.Reason);
}
}
WebSocket 代理要求
前端需要通过网关的 WebSocket 代理中间件与 WebSocket 服务建立会话,需满足以下要求:
- 通过请求头或
querystring参数指定hashkey(即bussinessId),框架使用该值通过哈希算法路由到固定的 WebSocket 服务实例 - 为保证每次都路由到同一个服务实例,对应的网关只能部署一个实例
- 网关必须启用 WebSocket 代理中间件:
// 在网关的 Configure() 中配置 WebSocket 代理中间件
app.UseSilkyWebSocketsProxy();
建议
可以考虑将普通业务服务对应一组网关(支持多实例),WebSocket 应用对应另一组网关(只允许单实例),分开部署以满足各自需求。
构建网关
网关作为微服务集群对外的统一流量入口,具有如下特性:
- 只提供 HTTP 服务,作为集群流量入口
- 不提供 RPC 服务,只能作为服务消费者,不能作为 RPC 服务提供者
- 通过引用各微服务的应用接口层,自动获得各服务的路由信息和 RPC 代理能力

网关 vs Web 主机
- 网关:只能作为服务消费者,转发外部 HTTP 请求;无 RPC 服务注册
- Web 主机:除了转发 HTTP 请求外,还能作为 RPC 服务提供者,注册服务到注册中心
使用默认网关模块
using Microsoft.Extensions.Hosting;
private static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureSilkyGatewayDefaults(webBuilder => webBuilder.UseStartup<Startup>());
使用自定义启动模块
自定义模块需继承 GatewayHostModule:
private static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureSilkyGateway<DemoModule>(webBuilder => webBuilder.UseStartup<Startup>());
网关 Startup 配置
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services
.AddSilkyHttpCore() // Silky HTTP 核心服务(必须)
.AddRouting()
.AddSwaggerDocuments() // 聚合所有微服务的 Swagger 文档
.AddSilkyIdentity() // 统一身份认证(可选)
.AddSilkyMiniProfiler(); // 性能分析(可选)
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseSwaggerDocuments();
}
app.UseRouting();
app.UseSilkyIdentity(); // 统一身份认证中间件
app.UseSilkyWebSocketsProxy(); // WebSocket 代理(如需支持 ws 转发)
app.UseEndpoints(endpoints =>
{
endpoints.MapSilkyRpcServices(); // 映射路由(必须)
});
}
}
说明:silky 框架在 v3.x 中,网关无需逐个引用各微服务应用接口层的包,只需与业务微服务接入同一个服务注册中心,网关即可自动获取所有微服务的服务条目信息并生成路由和 Swagger 文档。
