通过silky框架在.net平台构建微服务应用
必要前提
(必须) 安装 .net5 或是 .net6 sdk。
(必须) 您可以使用visual studio 或是rider作为开发工具。
(必须) 您必须准备一个可用的
zookeeper服务作为服务注册中心。(必须) 使用选择
redis服务作为分布式缓存服务。
使用Web主机构建微服务应用
开发者可以通过.net平台提供Web 主机来构建silky微服务应用。
使用webhost来构建的Silky微服务应用,不但可以作为微服务应用的服务提供者(服务内部可以通过SilkyRpc框架进行通信);也提供http服务,http请求通过应用服务方法(服务条目)生成的webapi,通过silky设定的路由规则即可访问微服务应用提供的相关服务。
我们通过如下步骤可以快速的构建一个使用Web 主机构建的Silky微服务应用。
- 新增一个控制台应用或是ASP.NET Core Empty应用


- 安装
Silky.Agent.Host包
通过 Nuget Package Manger 安装Silky.Agent.Host包:

或是通过控制台命令安装包:
PM> Install-Package Silky.Agent.Host -Version 3.0.2
- 在
Main方法中构建silky主机
namespace Silky.Sample
{
using Microsoft.Extensions.Hosting;
using System.Threading.Tasks;
class Program
{
public static async Task Main(string[] args)
{
await CreateHostBuilder(args).Build().RunAsync();
}
private static IHostBuilder CreateHostBuilder(string[] args)
{
return Host.CreateDefaultBuilder(args)
.ConfigureSilkyWebHostDefaults(webBuilder => webBuilder.UseStartup<Startup>());
}
}
}
- 在启用类中配置服务和置中间件、路由
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Silky.Http.Core;
namespace Silky.Sample
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
// 新增必要的服务
services.AddSilkyHttpCore()
.AddSwaggerDocuments()
.AddRouting();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// 判断是否开发环境
if (env.IsDevelopment())
{
// 开发环境使用开发者异常调式页面
app.UseDeveloperExceptionPage();
// 开发环境使用Swagger在线文档
app.UseSwaggerDocuments();
}
// 使用路由中间件
app.UseRouting();
// 添加其他asp.net core中间件...
// 配置路由
app.UseEndpoints(endpoints =>
{
// 配置SilkyRpc路由
endpoints.MapSilkyRpcServices();
});
}
}
}
- 更新配置
silky支持通过json或是yml格式进行配置。您可以通过appsettings.json为公共配置项指定配置信息,也可以通过新增appsettings.${ENVIRONMENT}.json文件为指定的环境更新配置属性。
一般地,您必须指定rpc通信的token,服务注册中心地址等配置项。如果您使用redis作为缓存服务,那么您还需要将distributedCache:redis:isEnabled配置项设置为true,并给出redis服务缓存的地址。
在appsettings.json配置文件中新增如下配置属性:
{
"RegistryCenter": {
"Type": "Zookeeper",
"ConnectionStrings": "127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183;127.0.0.1:2184,127.0.0.1:2185,127.0.0.1:2186"
},
"DistributedCache": {
"Redis": {
"IsEnabled": true,
"Configuration": "127.0.0.1:6379,defaultDatabase=0"
}
},
"Rpc": {
"Token": "ypjdYOzNd4FwENJiEARMLWwK0v7QUHPW",
"Port": 2200
}
}
将配置文件属性的复制到输出目录,设置为: 始终复制 或是 如果较新则复制。

- 创建zookeeper服务和redis缓存服务
在该示例项目中,我们使用Zookeeper作为服务注册中心。我们在silky的示例项目中给出各种基础服务的docker-compose的编排文件,其中,也包括了zookeeper和redis服务的。
将docker-compose.zookeeper.yml和docker-compose.redis.yml拷贝到本地,保存为相同名称的文件,进入到保存文件的本地目录。
# 创建一个名称为silky_service_net的docker网络
docker network create silky_service_net
# 使用docker-compose创建zookeeper和redis服务
docker-compose -f docker-compose.zookeeper.yml -f docker-compose.redis.yml up -d
- 微服务应用的其他层(项目)
完成主机项目后,您可以新增应用接口层、应用层、领域层、基础设施层等其他项目,更多内容请参考微服务架构节点。
一个典型的微服务模块的划分与传统的DDD领域模型的应用划分基本一致。需要将应用接口单独的抽象为一个程序集,方便被其他微服务应用引用,其他微服务应用通过应用接口生成RPC代理,与该微服务通信。
一个典型的微服务模块的项目结构如下所示:

项目的依赖关系如下:
(1) 主机项目依赖应用层,从而达到对应用的托管。
(2) 应用接口层用于定义服务接口和DTO对象,应用层需要依赖应用接口层,实现定义好的服务接口。
(3) 领域层主要用于实现具体的业务逻辑,可以依赖自身的应用接口层以及其他微服务应用的应用接口层(开发者可以通过nuget包安装其他微服务应用的应用接口项目或是直接添加项目的方式进行引用);领域层依赖自身的应用接口层的原因是为了方便使用DTO对象;引用其他微服务的应用接口层可以通过接口生成的动态代理,与其他微服务通过SilkyRPC框架进行通信。
(4) 领域共享层(Domain.Shared) 一般用于定义ddd概念中的值类型以及枚举等,方便被其他微服务应用引用。
(5) EntityFramework作为基础服务层,提供数据访问能力,当然,开发者也可以选择使用其他ORM框架。
- 应用接口的定义和实现
应用接口层(Silky.Sample.Application.Contracts) 安装包Silky.Rpc:

或是通过控制台命令安装包:
PM> Install-Package Silky.Rpc -Version 3.0.2
新增一个服务接口IGreetingAppService,并且定义一个Say()方法,应用接口需要使用[ServiceRoute]特性进行标识。
[ServiceRoute]
public interface IGreetingAppService
{
Task<string> Say(string line);
}
接下来,我们需要 应用层(Silky.Sample.Application) 依赖(引用) 应用接口层(Silky.Sample.Application.Contracts), 并新增一个服务类GreetingAppService,通过它实现服务接口IGreetingAppService。
public class GreetingAppService : IGreetingAppService
{
public Task<string> Say(string line)
{
return Task.FromResult($"Hello {line}");
}
}
- 通过Swagger文档在线调试
运行应用程序,即可打开swagger在线文档。开发者可以通过swagger生成的在线文档调试API。

使用.NET通用主机构建微服务应用
开发者可以通过.net平台提供通用主机来构建silky微服务应用。
使用.NET 通用主机构建微服务应用只能作为服务提供者,通过SilkyRPC框架与其他微服务应用进行通信;无法提供http服务,也就是说,集群外部无法直接访问该微服务应用,只能通过网关或是其他提供http服务的微服务应用访问该微服务应用的服务。
使用.NET 通用主机构建Silky微服务应用的步骤与使用使用Web 主机构建微服务应用的步骤基本一致,区别在于无需配置Startup类,也不能配置http中间件(配置了也无效);开发者可以通过实现IConfigureService接口来完成对服务注入的配置。
1-2 步骤与使用web主机构建微服务应用一致。
- 在
Main方法中构建silky主机
namespace Silky.Sample
{
using Microsoft.Extensions.Hosting;
using System.Threading.Tasks;
class Program
{
public static async Task Main(string[] args)
{
await CreateHostBuilder(args).Build().RunAsync();
}
private static IHostBuilder CreateHostBuilder(string[] args)
{
return Host.CreateDefaultBuilder(args)
.ConfigureSilkyGeneralHostDefaults();
}
}
}
创建ConfigureService类,用于实现IConfigureService接口,在ConfigureServices()方法中配置服务注入依赖。
public class ConfigureService : IConfigureService
{
public void ConfigureServices(IServiceCollection services, IConfiguration configuration)
{
services.AddSilkySkyApm()
//其他服务(包括第三方组件的服务或是silky框架的其他服务,例如:Efcore组件,MessagePack编解码,Cap或是MassTransit等分布式事件总线等)
//...
;
}
}
5-7步骤与使用web主机构建微服务应用一致。
启动应用后,我们可以在控制台看到相关的日志输出,应用服务启动成功。

用户无法直接访问该微服务应用,必须通过网关引用该微服务的 应用接口层 ,通过网关的提供的http服务间接的访问该微服务应用提供的服务。
构建具有websocket服务能力的微服务应用
开发者通过构建具有websocket服务能力的微服务应用, 这样的微服务应用可以除了可以作为服务提供者之外,还具有提供websocket通信的能力(websocket端口默认为:3000)。可以通过与服务端进行握手会话(可以通过网关代理),服务端实现向客户单推送消息的能力。
构建具有websocket服务能力的微服务应用与使用.NET通用主机构建微服务应用的步骤一致,只是用于构建微服务应用的方法有差异。
1-2 步骤与使用web主机构建微服务应用一致。
- 在
Main方法中构建silky主机
namespace Silky.Sample
{
using Microsoft.Extensions.Hosting;
using System.Threading.Tasks;
class Program
{
public static async Task Main(string[] args)
{
await CreateHostBuilder(args).Build().RunAsync();
}
private static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureSilkyWebSocketDefaults();
}
}
创建ConfigureService类,用于实现IConfigureService接口,在ConfigureServices()方法中配置服务注入依赖。
public class ConfigureService : IConfigureService
{
public void ConfigureServices(IServiceCollection services, IConfiguration configuration)
{
services.AddSilkySkyApm()
//其他服务(包括第三方组件的服务或是silky框架的其他服务,例如:Efcore组件,MessagePack编解码,Cap或是MassTransit等分布式事件总线等)
//...
;
}
}
5-6步骤与使用web主机构建微服务应用一致。
- 构建具有提供websocket服务能力的服务
应用服务接口的定义与一般应用服务的接口定义一样,只需要在一个普通的接口标识[ServiceRoute]特性即可。
[ServiceRoute]
public interface ITestAppService
{
// 可以定义其他方法(服务条目),定义的方法可以与其他微服务应用通过RPC框架进行通信
}
我们需要在 应用层(Silky.Sample.Application) 安装 Silky.WebSocket包。
PM> Install-Package Silky.WebSocket -Version 3.0.2
并新增一个 TestAppService类, 通过它来实现 ITestAppService, 除此之外,我们需要 TestAppService类继承 WsAppServiceBase基类。
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 established a session");
}
// 当服务端接收到客服端的消息时
protected override void OnMessage(MessageEventArgs e)
{
_logger.LogInformation(e.Data);
}
// 当websocket会话关闭时
protected override void OnClose(CloseEventArgs e)
{
base.OnClose(e);
_logger.LogInformation("websocket disconnected");
}
// 其他服务方法
}
启动应用后,我们可以在控制台看到相关的日志输出,应用服务启动成功。我们定义的websocket的服务的webapi地址为:/api/test。

- 客户端透过网关与websocket服务握手
客户端无法直接与该微服务应用进行握手,必须通过网关引用该微服务的 应用接口层 ,通过网关的提供的websocket代理服务与该微服务进行握手,通过ws[s]://gateway_ip[:gateway_port]/websocket_webapi与之前定义websocket服务进行会话。
我们在构建的网关应用中引用该微服务的应用接口层,并启动网关应用(网关服务地址为127.0.0.1:5000),并可通过地址:ws://127.0.0.1:5000/api/test与之前定义的websocket服务进行握手和通信。
客户端与websocket服务进行握手时,需要通过qstring参数或是请求头设置hashkey,确保每次通信的微服务应用都是同一个实例。


构建Silky微服务网关
实际上,通过.net平台提供Web主机来构建silky微服务应用,也可以认为是一个网关。我们在这里专门构建的网关与通过.net平台提供Web 主机的区别在于该类型的微服务应用只能作为服务消费者,不能作为服务提供者,不能作为RPC服务提供者。
总的来说,网关是对微服务应用集群来说是一个对接外部的流量入口。
构建过程与通过.net平台提供Web 主机一致,我们只需要将创建主机的方法修改为:
private static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureSilkyGatewayDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); });
网关项目通过引用其他微服务应用的应用接口层,就可以作为服务消费者通过SilkyRPC框架调用其他微服务应用提供的服务,并且通过网关提供的http相关中间件可以实现生成在线swagger文档,实现统一的api鉴权,http限流,生成dashboard管理端,实现对微服务集群服务提供者实例的健康检查等功能。
开源地址
- github: https://github.com/liuhll/silky
- gitee: https://gitee.com/liuhll2/silky
在线文档
在线示例
通过silky框架在.net平台构建微服务应用的更多相关文章
- 使用silky脚手架构建微服务应用
目录 模板简介 构建独立应用的模板Silky.App.Template 构建模块化应用的模板Silky.Module.Template 开源地址 在线文档 模板简介 使用 dotnet new 命令可 ...
- Cola Cloud 基于 Spring Boot, Spring Cloud 构建微服务架构企业级开发平台
Cola Cloud 基于 Spring Boot, Spring Cloud 构建微服务架构企业级开发平台: https://gitee.com/leecho/cola-cloud
- 如何使用 Java 构建微服务?
[编者按]微服务背后的大理念是将大型.复杂且历时长久的应用在架构上设计为内聚的服务,这些服务能够随着时间的流逝而演化.本文主要介绍了利用 Java 生态系统构建微服务的多种方法,并分析了每种方法的利弊 ...
- 基于Spring Cloud和Netflix OSS构建微服务,Part 2
在上一篇文章中,我们已使用Spring Cloud和Netflix OSS中的核心组件,如Eureka.Ribbon和Zuul,部分实现了操作模型(operations model),允许单独部署的微 ...
- Chris Richardson微服务翻译:构建微服务之使用API网关
Chris Richardson 微服务系列翻译全7篇链接: 微服务介绍 构建微服务之使用API网关(本文) 构建微服务之微服务架构的进程通讯 微服务架构中的服务发现 微服务之事件驱动的数据管理 微服 ...
- 手把手教你用Spring Cloud和Docker构建微服务
什么是Spring Cloud? Spring Cloud 是Pivotal提供的用于简化分布式系统构建的工具集.Spring Cloud引入了云平台连接器(Cloud Connector)和服务连接 ...
- 微服务系列(二):使用 API 网关构建微服务
编者的话|本文来自 Nginx 官方博客,是微服务系列文章的第二篇,本文将探讨:微服务架构是如何影响客户端到服务端的通信,并提出一种使用 API 网关的方法. 作者介绍:Chris Richardso ...
- 0102-使用 API 网关构建微服务
一.移动客户端如何访问这些服务 1.1.客户端与微服务直接通信[很少使用] 从理论上讲,客户端可以直接向每个微服务发送请求.每个微服务都有一个公开的端点(https ://.api.company.n ...
- 技术分享:Dapr,让开发人员更轻松地构建微服务应用
最近一直在学习微服务相关的技术.微服务架构已成为构建云原生应用程序的标准,并且可以预见,到2022年,将有90%的新应用程序采用微服务架构.微服务架构提供了令人信服的好处,包括可伸缩性,松散的服务耦合 ...
随机推荐
- 修改 CubeMX 生成的 RT-Thread makefile 工程
修改 CubeMX 生成的 RT-Thread makefile 工程 使用 RT-Thread 官方 基于 CubeMX 移植 RT-Thread Nano 生成的 Makefile 工程在编译时有 ...
- PHP中的MySQLi扩展学习(三)mysqli的基本操作
我们继续 MySQLi 扩展的学习,上篇文章中提到过,MySQLi 的扩展相对于 PDO 来说功能更加的丰富,所以我们依然还会在学习过程中穿插各种 MySQLi 中好玩的方法函数.不过,今天的主角是 ...
- Probius+Kubernetes任务系统如虎添翼
Probius是一款自定义任务引擎,可以灵活方便的处理日常运维中的各种任务,我们所有的CI/CD任务都通过Probius来完成的,这篇文章Probius:一个功能强大的自定义任务系统对其有详细的介绍, ...
- Linux C语言 取得MTU (最大传输单元)
参照这篇博客: http://www.geekpage.jp/programming/linux-network/book/04/4-21.php * 查看主机当前网卡,哪块在使用. ifconfig ...
- 鸿蒙内核源码分析(内存汇编篇) | 谁是虚拟内存实现的基础 | 百篇博客分析OpenHarmony源码 | v14.14
百篇博客系列篇.本篇为: v14.xx 鸿蒙内核源码分析(内存汇编篇) | 谁是虚拟内存实现的基础 | 51.c.h .o 内存管理相关篇为: v11.xx 鸿蒙内核源码分析(内存分配篇) | 内存有 ...
- P5363-[SDOI2019]移动金币【阶梯博弈,dp,组合数学】
正题 题目链接:https://www.luogu.com.cn/problem/P5363 题目大意 \(1\times n\)的网格上有\(m\)个硬币,两个人轮流向前移动一个硬币但是不能超过前一 ...
- 高级测试必备技能,Jenkins
Jenkins安装 前言 Jenkins是一个广泛用于持续构建的可视化web工具,就是各种项目的的"自动化"编译.打包.分发部署,将以前编译.打包.上传.部署到Tomcat中的过程 ...
- 现在有一个长度20的SET,其中每个对象的内容是随机生成的字符串,请写出遍历删除LIST里面字符串含"2"的对象的代码。
现在有一个长度20的SET,其中每个对象的内容是随机生成的字符串,请写出遍历删除LIST里面字符串含"2"的对象的代码. public class RemoveTwo { //le ...
- 拥抱开源,共建生态 - 开源生态与效能提升专场 | CIF 精彩看点
随着软件技术日新月异的发展,GitHub 已经进化成为人类软件的基因库,遇到问题第一时间在 GitHub 上寻求合适的解决方案,已经逐渐变成工程师处理问题的常见方法.据 GitHub 年度报告显示,2 ...
- Linux基础安全配置(centos7)
1.帐户口令的生存期不长于90天 sed -i.old 's#99999#90#g' /etc/login.defs egrep "90" /etc/login.defs 2.密码 ...