托管和部署 Blazor ServerHost and deploy Blazor Server
本文内容
作者:Luke Latham、Rainer Stropek 和 Daniel Roth
主机配置值Host configuration values
部署Deployment
使用 Blazor Server 托管模型,可从 ASP.NET Core 应用中在服务器上执行 Blazor。UI 更新、事件处理和 JavaScript 调用是通过 SignalR 连接进行处理。
能够托管 ASP.NET Core 应用的 Web 服务器是必需的。Visual Studio 包括“Blazor Server 应用” 项目模板(使用 dotnet new 命令时为 blazorserverside
模板)。
可伸缩性Scalability
计划部署以将可用的基础设施充分用于 Blazor Server 应用。请参阅以下资源来解决 Blazor Server 应用的可伸缩性:
部署服务器Deployment server
考虑单一服务器(纵向扩展)的可伸缩性时,应用可用的内存可能是用户需求增加时应用将耗尽的第一个资源。服务器上的可用内存影响以下因素:
- 服务器可以支持的主动电路数。
- 客户端上的 UI 延迟。
有关生成安全且可伸缩的 Blazor 服务器应用的指南,请参阅 安全 ASP.NET Core Blazor 服务器应用。
每个电路使用约 250 KB 的内存来实现至少为 Hello World 样式的应用。电路大小取决于应用代码和与每个组件相关的状态维护要求。我们建议你在开发应用和基础设施的过程中衡量资源需求,但在计划部署目标时可以将以下基准作为起点:如果希望应用支持 5,000 个并发用户,请考虑为应用预算至少 1.3 GB 服务器内存(或每用户 ~273 KB)。
SignalR 配置 configuration
Blazor Server 应用使用 ASP.NET Core SignalR 与浏览器进行通信。SignalR 的托管和缩放条件 适用于 Blazor Server 应用。
由于低延迟、可靠性和安全性,使用 WebSocket 作为 SignalR 传输时,Blazor 的效果最佳。当 WebSocket 不可用时,或在将应用显式配置为使用长轮询时,SignalR 将使用长轮询。部署到 Azure 应用服务时,请在服务的 Azure 门户设置中将应用配置为使用 WebSocket。有关为 Azure 应用服务配置应用的详细信息,请参阅 SignalR 发布指南。
Azure SignalR 服务Azure SignalR Service
我们建议将 Azure SignalR 服务用于 Blazor Server 应用。该服务允许将 Blazor Server 应用扩展到大量并发 SignalR 连接。此外,SignalR 服务的全球覆盖和高性能数据中心可帮助显著减少由于地理位置造成的延迟。若要配置应用(并选择性地预配),Azure SignalR 服务应:
启用该服务以支持粘滞会话 ,在此情况下,客户端在预呈现时被重定向回同一服务器。将
ServerStickyMode
选项或配置值设置为Required
。通常,应用使用下述方法之一创建配置 :Startup.ConfigureServices
:
services.AddSignalR().AddAzureSignalR(options =>
{
options.ServerStickyMode =
Microsoft.Azure.SignalR.ServerStickyMode.Required;
});
配置(使用下述方法之一) :
- appsettings.json :
"Azure:SignalR:ServerStickyMode": "Required"
-
Azure 门户中的应用服务“配置” > “应用程序设置”(名称:Azure:SignalR:ServerStickyMode
,值:Required
) 。
在 Visual Studio 中创建适用于 Blazor Server 应用的 Azure 应用发布配置文件。
将 Azure SignalR 服务依赖项添加到配置文件。如果 Azure 订阅没有要分配给应用的预先存在的 Azure SignalR 服务实例,请选择“创建新的 Azure SignalR 服务实例” 以预配新的服务实例。
将应用发布到 Azure。
IISIIS
使用 IIS 时,请启用:
KubernetesKubernetes
使用以下粘滞会话的 Kubernetes 注释创建入口定义:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: <ingress-name>
annotations:
nginx.ingress.kubernetes.io/affinity: "cookie"
nginx.ingress.kubernetes.io/session-cookie-name: "affinity"
nginx.ingress.kubernetes.io/session-cookie-expires: "14400"
nginx.ingress.kubernetes.io/session-cookie-max-age: "14400"
Linux 与 NginxLinux with Nginx
要使 SignalR Websocket 正常运行,请确保将代理的 Upgrade
和 Connection
标头设置为以下值,并将 $connection_upgrade
映射到以下值之一:
- 默认情况下为升级标头值。
- 缺少升级标头或升级标头为空时为
close
。
http {
map $http_upgrade $connection_upgrade {
default Upgrade;
'' close;
}
server {
listen 80;
server_name example.com *.example.com
location / {
proxy_pass http://localhost:5000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
}
有关详细信息,请参阅以下文章:
衡量网络延迟Measure network latency
可以使用 JS 互操作来衡量网络延迟,如以下示例所示:
@inject IJSRuntime JS
@if (latency is null)
{
<span>Calculating...</span>
}
else
{
<span>@(latency.Value.TotalMilliseconds)ms</span>
}
@code
{
private DateTime startTime;
private TimeSpan? latency;
protected override async Task OnInitializedAsync()
{
startTime = DateTime.UtcNow;
var _ = await JS.InvokeAsync<string>("toString");
latency = DateTime.UtcNow - startTime;
}
}
为获得合理的 UI 体验,我们建议使用 250 毫秒或更低的持续 UI 延迟。