《进击吧!Blazor!》是本人与张善友老师合作的Blazor零基础入门教程视频,此教程能让一个从未接触过Blazor的程序员掌握开发Blazor应用的能力。

视频地址:https://space.bilibili.com/483888821/channel/detail?cid=151273

Blazor WebAssembly 是单页应用 (SPA) 框架,用于使用 .NET 生成交互式客户端 Web 应用,采用 C# 代替 JavaScript 来编写前端代码

本系列文章基于《进击吧!Blazor!》编写,但因篇幅有限,省略了部分代码,完整示例代码:https://github.com/TimChen44/Blazor-ToDo

作者:陈超超

Ant Design Blazor 项目贡献者,拥有十多年从业经验,长期基于.Net技术栈进行架构与开发产品的工作,现就职于正泰集团。

邮箱:timchen@live.com

欢迎各位读者有任何问题联系我,我们共同进步。

部署是开发的最后一部,我们这次就来聊聊Blazor的部署方法。

发布

VS已经为我们预制了多个目标的发布工具,使用这些工具可以很容易的完成发布和部署。

1.首先在ToDo.Server项目上右键,选择发布...功能

2.接着选择要发布的目标,常用的环境都支持,我们就以Azure为例



3.根据目标不同填写一些配置,VS也会帮我们保存配置信息便于下次使用。



4.配置一些依赖,比如本例中需要配置数据库,最后点击”发布“按钮,接着喝杯茶等待一下。



5.经过VS后台的一顿操作,发布完成,并且会自动打开发布的站点,效果如下



到这里,这篇文章结束了,各位再见!

这个,我们本着“搞事情”的精神,"没有困难制造困难"的理念来重构我们的发布,各位走起~~~~

首先可以确定上面VS为我们提供的发布工具确实非常方便,比较适合小团队开发一些小规模的系统,但是通常企业中使用会遇到以下的问题

  • 负责发布的运维工程师与负责编码的开发工程师不是同一拨人,不可能让运维工程师用VS开着源码进行发布,代码安全,生产环境安全双双无法保证。
  • 自动化的IC/CD普及度的增加,生成和发布过程挪到了各DevOps平台,所以也不适合在VS中操作。

广告时间:推荐大家尝试一下微软的Azure DevOps,支持本地部署,支持所有语言,预制各平台发布流程等等,配置一个项目的IC/CD过程犹如前面的操作一样,鼠标点点就完事,懒人的福音。

综上述,我们可以采用比较灵活的的做法,先将项目发布成文件,然后将这些文件部署到不同的环境中。这也符合自动化的IC/CD的常规流程,先集成再部署。

如果使用Docker,可以在IC时直接Build出Image,也可以在CD时Build出Image,我觉得没有标准,适合自己就行。

发布到文件夹

那么我们继续使用VS的发布工具将项目打包

1.选择发布到文件夹选项,并设定输出位置



2.点击发布完成编译并输出。



3.点击上面的”铅笔“图标可以进行详细配置



目标框架 设置使用那个.net框架进行编译

部署模式 它分为框架依赖独立两个选共享

框架依赖 模式下生成的文件需要.net运行时才能运行,优点体积较小,程序本省不依赖目标运行时,方便移植

独立 模式下编译器会把.net运行时与程序打包在一起,运行平台无需.net运行时,缺点是体积较大,编译的程序依赖于目标运行时

目标运行时 选择针对那个平台编译,可以是win、linux、osx系统,以及x64、x86、arm指令集

生成单个文件 勾选后可以把程序打包在一个文件中,运行的时候程序会自动解包并运行

裁剪未使用的程序集 将一些项目中引用但是代码中并未使用的程序集剔除以减少程序包的体积

我们的示例程序使用配置 部署模式依赖框架目标运行时可移植

如果编译过程使用自动化工具进行打包,除了打包命令中额外增加参数外,我们也可以在.csproj文件中做以下配置来实现上面的参数

<PropertyGroup>
<PublishSingleFile>True</PublishSingleFile><!-- 生成单个文件 -->
<PublishTrimmed>True</PublishTrimmed><!-- 裁剪未使用的程序集 -->
<SelfContained>true</SelfContained><!-- 框架依赖:独立 -->
<RuntimeIdentifier>win-x86</RuntimeIdentifier><!-- 目标运行时 -->
</PropertyGroup>

4.程序以文件形式输出在我们给定的路径

部署

使用 ASP.NET Core 进行托管部署

如果使用ASP.NET Core的Kestrel Web 服务器托管程序,我们只需运行我们上面发布输出的ToDo.Server.exe文件即可



到这里有个小问题,就是我们不想使用默认的5000和5001端口,这个我们就需要人为的给定端口。

修改ToDo.ServerProgram.cs文件

public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder
.UseUrls("http://*:4000", "https://*:4001")
.UseStartup<Startup>();
});

我们使用.UseUrls来给定Url地址,这里*代表适配所有IP或域名,端口分别设定为40004001

这里又冒出一个小问题,目前端口硬编码在程序中,发布后无法修改,遇到这个问题,我们可以通过启动参数、配置文件等多个方法实现发布后修改,在这里我贴上通过启动参数修改端口的代码。

public static IHostBuilder CreateHostBuilder(string[] args)
{
var configuration = new ConfigurationBuilder().AddCommandLine(args).Build();
return Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder
.UseUrls($"http://*:{configuration["httpport"] ?? "5000"}", $"https://*:{configuration["httpsport"] ?? "5001"}")
.UseStartup<Startup>();
});
}

启动的时候附上对应参数实现修改端口的目的。

使用 IIS 进行托管部署

我们也可以使用IIS来托管部署我们的程序。

  1. 需要在部署的服务器上安装ASP.NET Core Hosting Bundle,这个可以让IIS支持.Net Core应用。下载地址:https://dotnet.microsoft.com/download/dotnet/5.0

  2. 添加名为ToDo的站点,选择发布的文件所在目录,配置端口等

  3. 将应用程序池ToDoNET CLR版本设置为无托管代码

  4. 启动站点就能看到自己部署的程序了。

与ASP.Net Core的区别

看到这里,各位觉得Blazor和ASP.Net Core在部署上有什么区别吗?答案是:没区别。

前后端分开部署

当遇到规模不小的项目时,我们会考虑到性能、安全等因素时,可能会选择前后端分别部署在不同的服务器上,这时我们只需要新建一个空项目,然后引用Blazor项目即可,操作如下

  1. 添加名为ToDo.BlazorHost的ASP.NET Core空项目

  2. 引用ToDo.Client项目

  3. 安装Microsoft.AspNetCore.Components.WebAssembly.Server

  4. 修改launchSettings.json文件,配置应用端口默认为4000

    "iisExpress": {
"applicationUrl": "http://localhost:4000",
"sslPort": 0
}
  1. 修改Startup.cs文件,让项目支持Blazor应用
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseBlazorFrameworkFiles();//配置应用程序从根“/”提供Blazor框架文件
app.UseStaticFiles();//提供静态文件支持
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapFallbackToFile("index.html");//配置默认路由地址
});
}
  1. 修改ToDo.Client项目Program.cs文件,设置HttpClient默认请求地址为ToDo.Server项目的地址
builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri($"http://localhost:5000") });
  1. 修改ToDo.Server项目launchSettings.json文件,配置IIS Express调试端口默认为5000
      "iisExpress": {
"applicationUrl": "http://localhost:5000",
"sslPort": 0
}
  1. 修改Startup.cs文件,添加跨域支持,此处为了演示方便,我开启了所有跨域设置
app.UseCors(config => config.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader().AllowCredentials().WithOrigins("http://localhost:4000"));
  1. 删除ToDo.ServerToDo.Client的引用,以及Blazor相关的设置,ToDo.Server作为一个存粹的WebAPI站点存在。

  2. 为了验证前端请求的数据是那个服务返回,我们做一个反馈服务器地址的接口给前端调用。

修改AuthController.cs文件

[HttpGet]
public string GetHost()
{
return HttpContext.Request.Host.ToString();
}

修改Login.razor文件

<p>前端地址:<span>@ClientHost</span></p>
<p>API服务地址:<span>@ServerHost</span></p>
string ClientHost;
string ServerHost;
protected override async Task OnInitializedAsync()
{ ClientHost = WebAssemblyHostBuilder.CreateDefault().HostEnvironment.BaseAddress;
ServerHost = await Http.GetStringAsync($"api/Auth/GetHost");
await base.OnInitializedAsync();
}

同时启动ToDo.ServerToDo.BlazorHost项目的调试,看到以下效果

网关部署

当用户多了,获作为关键服务时,单点部署就有点不合时宜了,这时需要高可用,负载均衡等需求,因此我们就要拿出我们的网关,把他放在最前面,负责请求分发。

  1. 添加名为ToDo.BlazorHost的ASP.NET Core空项目作为网关ToDo.Gateway

  2. 添加Ocelot组件,Ocelot是一个用.NET Core实现并且开源的API网关,它功能强大,包括了:路由、请求聚合、服务发现、认证、鉴权、限流熔断、并内置了负载均衡器与Service Fabric、Butterfly Tracing集成。

  1. 修改launchSettings.json文件,将访问端口改成5500
    "iisExpress": {
"applicationUrl": "http://localhost:5500",
"sslPort": 0
}
  1. 添加Ocelot.json文件,配置我们网关的策略
{
"Routes": [
{
// - 上游服务配置
"UpstreamPathTemplate": "/api/{url}",
"UpstreamHttpMethod": [ "Get", "Post", "Put", "Delete" ], // - 下游服务配置
"DownstreamPathTemplate": "/api/{url}",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 5000
}
], // - LoadBalancer将决定负载均衡的算法,三种取值
// RoundRobin:轮流发送
// LeastConnection:将请求发往最空闲的那个服务器
// NoLoadBalance:总是发往第一个请求或者是服务发现
"LoadBalancerOptions": {
"Type": "RoundRobin"
}
},
{
// - 上游服务配置
"UpstreamPathTemplate": "/{url}",
"UpstreamHttpMethod": [ "Get", "Post", "Put", "Delete" ], // - 下游服务配置
"DownstreamPathTemplate": "/{url}",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 5100
}
], // - LoadBalancer将决定负载均衡的算法,三种取值
// RoundRobin:轮流发送
// LeastConnection:将请求发往最空闲的那个服务器
// NoLoadBalance:总是发往第一个请求或者是服务发现
"LoadBalancerOptions": {
"Type": "RoundRobin"
}
}
],
"GlobalConfiguration": {
"BaseUrl": "https://api.mybusiness.com"
}
}

上面Ocelot.json文件中注释只是为了介绍常用属性,实际使用中json文件中不能包含注释,否则会造成解析失败,切记。

  1. 修改Program.cs文件,添加载入Ocelot.json文件的代码
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.ConfigureAppConfiguration((hostContext, config) =>
{
config.AddJsonFile("Ocelot.json");
})
.UseStartup<Startup>();
});
  1. 修改Startup.cs文件,添加Ocelot服务
public void ConfigureServices(IServiceCollection services)
{
services.AddOcelot();
} // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseOcelot();
}
  1. 修改ToDo.Client项目的Program.cs文件,配置HttpClient默认地址为网关地址
builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri($"http://localhost:5500") });
  1. 修改ToDo.Server项目的Startup.cs文件,追加跨域请求地址“http://localhost:5500
app.UseCors(config => config.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader().AllowCredentials().WithOrigins("http://localhost:4000", "http://localhost:5500"));

同时调试ToDo.BlazorHostToDo.GatewayToDo.Server三个项目,打开地址http://localhost:5500

我们看到前端地址是localhost:5500,请求的地址也是localhost:5500,但是为我们返回数据的API服务地址是localhost:5000,说明网关已经帮我做了转发。

最后

感谢有读者能看到这里,这是本人第一次写专栏,文章可能会存在一些瑕疵,我会在将来尽力改进。

《进击吧!Blazor!》系列入门教程 第一章到这里就结束了,后续我会继续为大家带来与.Net和Blazor有关的原创文章,文章内容争取做到易读、高质量。

谢谢大家!

《进击吧!Blazor!》系列入门教程 第一章 8.部署的更多相关文章

  1. 《进击吧!Blazor!》系列入门教程 第一章 6.安全

    <进击吧!Blazor!>是本人与张善友老师合作的Blazor零基础入门教程视频,此教程能让一个从未接触过Blazor的程序员掌握开发Blazor应用的能力. 视频地址:https://s ...

  2. 《进击吧!Blazor!》系列入门教程 第一章 7.图表

    <进击吧!Blazor!>是本人与张善友老师合作的Blazor零基础入门教程视频,此教程能让一个从未接触过Blazor的程序员掌握开发Blazor应用的能力. 视频地址:https://s ...

  3. storm入门教程 第一章 前言[转]

    1.1   实时流计算 互联网从诞生的第一时间起,对世界的最大的改变就是让信息能够实时交互,从而大大加速了各个环节的效率.正因为大家对信息实时响应.实时交互的需求,软件行业除了个人操作系统之外,数据库 ...

  4. storm入门教程 第一章 前言

    转自:http://blog.linezing.com/?p=1847 storm:http://www.cnblogs.com/panfeng412/tag/Storm/ http://blog.l ...

  5. [ABP教程]第一章 创建服务端

    Web应用程序开发教程 - 第一章: 创建服务端 关于本教程 在本系列教程中, 你将构建一个名为 Acme.BookStore 的用于管理书籍及其作者列表的基于ABP的应用程序. 它是使用以下技术开发 ...

  6. Laravel 5 系列入门教程(一)【最适合中国人的 Laravel 教程】

    Laravel 5 系列入门教程(一)[最适合中国人的 Laravel 教程] 分享⋅ johnlui⋅ 于 2年前 ⋅ 最后回复由 skys215于 11个月前 ⋅ 17543 阅读   原文发表在 ...

  7. 村田噪声抑制基础教程-第一章 需要EMI静噪滤波器的原因

    1-1. 简介 EMI静噪滤波器 (EMIFIL®) 是为电子设备提供电磁噪声抑制的电子元件,配合屏蔽罩和其他保护装置一起使用.这种滤波器仅从通过连线传导的电流中提取并移除引起电磁噪声的元件.第1章说 ...

  8. [Learn Android Studio 汉化教程]第一章 : Android Studio 介绍

    注:为了看上去比较清晰这里只转载了中文 原地址:  [Learn Android Studio 汉化教程]第一章 : Android Studio 介绍 本章将引导您完成安装和设置开发环境,然后你就可 ...

  9. Storm入门之第一章

    Storm入门之第一章 1.名词 spout龙卷,读取原始数据为bolt提供数据 bolt雷电,从spout或者其他的bolt接收数据,并处理数据,处理结果可作为其他bolt的数据源或最终结果 nim ...

随机推荐

  1. IoT & Raspberry Pi

    IoT & Raspberry Pi https://www.raspberrypi.org/ https://www.raspberrypi.org/training https://pro ...

  2. 云原生系列6 基于springcloud架构风格的本地debug实现

    debug是程序员在日常开发中最常使用的操作, 那么,你是如何快速在微服务架构风格下快速debug后端服务呢? 开发现状 开发的理想状态 本地调测的使用步骤 登录智能网关 如果集成开发环境是在本地局域 ...

  3. synchronized语法

    synchronized( ){ } synchronized 关键字是加锁的意思,用它来修饰方法就表示给该方法加了锁,从而达到线程同步的效果;用它来修饰代码块就表示给该代码块加了锁,从而达到线程同步 ...

  4. Docker Elasticsearch 集群配置

    一:选用ES原因 公司项目有些mysql的表数据已经超过5百万了,各种业务的查询入库压力已经凸显出来,初步打算将一个月前的数据迁移到ES中,mysql的老数据就物理删除掉. 首先是ES使用起来比较方便 ...

  5. 导出----用Excel导出数据库表

    根据条件导出表格: 前端 <el-form-item label=""> <el-button type="warning" icon=&qu ...

  6. TkMybatis添加对象后返回数据的id

    在实体类的id属性上加上下面的注解 //导入的包import javax.persistence.GeneratedValue; @GeneratedValue(generator = "J ...

  7. 第七届蓝桥杯JavaB组——第7题剪邮票

    题目: 剪邮票 如[图1.jpg], 有12张连在一起的12生肖的邮票. 现在你要从中剪下5张来,要求必须是连着的. (仅仅连接一个角不算相连) 比如,[图2.jpg],[图3.jpg]中,粉红色所示 ...

  8. 大数据开发-Spark-Streaming处理数据到mysql

    前面一篇讲到streamin读取kafka数据加工处理后写到kafka数据,大数据开发-Spark-开发Streaming处理数据 && 写入Kafka是针对比如推荐领域,实时标签等场 ...

  9. 巧用 -webkit-box-reflect 倒影实现各类动效

    在很久之前的一篇文章,有讲到 -webkit-box-reflect 这个属性 -- 从倒影说起,谈谈 CSS 继承 inherit -webkit-box-reflect 是一个非常有意思的属性,它 ...

  10. ELK----elasticsearch7.10.1安装配置

    环境: vmware centos7 1.下载适合自己的es版本 https://www.elastic.co/cn/downloads/past-releases/elasticsearch-7-1 ...