必要前提
-
(必須) 安裝 .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