Architecture 带API网关和微服务的Blazor服务器指南

Architecture 带API网关和微服务的Blazor服务器指南,architecture,microservices,blazor,blazor-server-side,api-gateway,Architecture,Microservices,Blazor,Blazor Server Side,Api Gateway,到目前为止,我还没有找到使用Blazor服务器(不是WebAssembly)和API网关和微服务的指南。讨论这些Blazor以及API网关和微服务的文章总是提到Blazor WebAssembly(Wasm)。(是否假定Blazor服务器应用程序不会使用微服务?此外,出于价值考虑,选择Blazor服务器而不是Blazor WebAssembly的原因是为了更好地保护知识产权。) 无论如何。。。我想知道的是Blazor服务器应用程序是否应该坐在网关前面,通过网关向网关后面的微服务发送其内部API调

到目前为止,我还没有找到使用Blazor服务器(不是WebAssembly)和API网关和微服务的指南。讨论这些Blazor以及API网关和微服务的文章总是提到Blazor WebAssembly(Wasm)。(是否假定Blazor服务器应用程序不会使用微服务?此外,出于价值考虑,选择Blazor服务器而不是Blazor WebAssembly的原因是为了更好地保护知识产权。)

无论如何。。。我想知道的是Blazor服务器应用程序是否应该坐在网关前面,通过网关向网关后面的微服务发送其内部API调用,就像这样

[浏览器]-----(信号器)---[Blazor服务器应用程序]-----(https)---[API网关]-----(http)---[微服务]

或者将应用程序放在网关后面,让信号器连接隧道通过网关,这样做更有意义吗

[浏览器]---(信号器)---[API网关]---(信号器)---[Blazor服务器应用程序]---(http)---[Microservices]


在建立信号器连接之前,请记住浏览器中应用程序的初始负载。这需要分开处理吗?它是否影响上述选项的选择?有没有更好的解决方案,我错过了

我们使用Blazor服务器端作为在Azure Service Fabric(本身是无状态ASP.NET核心服务)中运行的微服务集合的前端,因此这是一个完全合法的场景。我们的整个应用程序都在Azure的云中运行,因此我将使用它的产品来描述我们的实现

为了更好地分离关注点和更容易地保护互联网边界,我们为公共API和SignalR提供了两个独立的服务。因此,API网关充当安全边界,因为它可以处理HTTPS卸载,位于面向公众的子网上,并路由到虚拟网络上的内部服务。然后,提供信号器访问的服务在应用程序网关实例后面的面向公众的子网上运行(用于防火墙+服务路由功能)

因此,我们设立了以下两项服务:

信号员业务 [浏览器]-(信号器)-[Azure应用程序网关]-[Azure服务结构-Blazor服务器端应用程序]-[SF服务远程处理]-[Microservices]

API服务 [浏览器]-(https)-(Azure API管理)-(http)-(Azure服务结构-ASP.NET核心API)-(SF服务远程处理)-(微服务]

Microservice Gotcha-数据保护 特别是在支持身份验证时,ASP.NET Core在内部为Blazor会话中使用的加密状态设置了一些密钥。在microservices场景中,除非您在网络堆栈(负载平衡器、网关、路由器等)中一直使用粘性路由,以确保所有请求始终命中同一个实例(并且在您不注意的情况下,您的实例可能不会重建并移动到其他位置),您将遇到关于未能取消对状态的保护的含糊不清且毫无帮助的错误

修复非常简单-在ASP.NET核心服务的Startup.cs中,确保设置了
services.AddDataProtection()并进行适当配置。因为我们使用的是服务结构,所以我们使用了一个非常适合这个目的的服务结构。要使用,请将NuGet软件包
SoCreate.AspNetCore.DatapProtection.ServiceFabric
安装到您的ASP.NET核心服务中,只需在
ConfigureServices()
方法的Startup.cs中添加以下内容:

public void配置服务(IServiceCollection服务)
{
//...
services.AddDataProtection().PersistKeyServiceFabricDistributedCache(opt=>{
//此ASP.NET核心微服务是唯一的,不要每次都使用新的GUID,否则您将回到您开始的位置,而所有服务都没有一个存储区
opt.CacheStoreId=新Guid(“b87d03b5-f8d1-456f-966d-11d2c4d9774d”);
//特别指向要使用的服务-如果未设置,将自动发现该服务
opt.CacheStoreServiceUri=新Uri(“结构:/MyApplication/DataProtectionStore”);});
//...
}
您可以在后一种方法上指定其他选项,以标识它应该使用的特定服务和唯一ID(这样服务可以在应用程序之间共享),但是如果它在同一个应用程序中,而您没有指定这些选项,它会找到它自己

然后创建一个有状态服务实例,在反映服务名称的文件中从NuGet安装
SoCreate.Extensions.Caching.ServiceFabric
,并将其从
StatefulService
继承替换为从
DistributedCacheStoreService
继承。删除服务中的所有其他内容,但设置更新的构造函数。在名为“DataProtectionStore”的服务中,您的
DataProtectionStore.cs
文件应如下所示:

使用System.Fabric;
使用SoCreate.Extensions.Caching.ServiceFabric
命名空间数据保护存储
{
内部密封类DataProtectionStore:DistributedCacheStoreService
{
受保护的覆盖int-MaxCacheSizeInMegabytes=>500;//可选
公共DataProtectionStore(StatefulServiceContext上下文):基本(上下文,消息=>ServiceEventSource.Current.ServiceMessage(上下文,消息))
{
}
}
}

您可以找到其他关于在“web场”或微服务/分布式环境中托管ASP.NET Core的有用指南。

谢谢您,Xaniff,感谢您花时间写出如此详细和彻底的答案!在特定上下文中描述它以帮助实现也非常感谢。我目前没有使用ServiceFabric,但随着扩展,我将需要使用它或Kubernetes。这正是在使用新技术时通常很难找到的建议!