❤️ 关注 Furion 微信公众号有惊喜哦!
🫠 遇到问题了
Skip to main content
⭐️ 开通 VIP 服务仅需 499 元/年,尊享 365 天项目无忧23 立即开通23 ⭐️
特别赞助

34.5. 单文件发布

版本说明

以下内容仅限 Furion 3.5.2 + 版本使用。

34.5.1 历史背景

.NET Core 3 起,微软就提供了单文件发布的技术支持,但实际上并不是 .NET 所有 CLR 都支持单文件发布,如 Microsoft.Extensions.DependencyModel 包本身不支持单文件发布,原因是内部使用了 Assembley.CodeBase

好巧不巧Furion 中招了,在过去两年中,Furion 依赖该包的 DependencyContext.Default 特性进行程序集扫描,所以单文件发布也就成了 Furion 不愿提起的痛!!!

终于,在 Furion v3.5.2+ 版本想出了新的解决方案,自此彻底解决了单文件发布的问题。

34.5.2 必要配置

Furion v3.5.2+ 版本之后,新增了 ISingleFilePublish 接口。

  • 编辑启动层 .csproj 文件,添加下列代码到 <PropertyGroup> 节点中
<PublishReadyToRunComposite>true</PublishReadyToRunComposite>
关于 ReadyToRun

如果发布时未打勾 ReadyToRun 选项,则无需配置上述代码。

  • Web 启动层 创建类型并实现该接口,如:
using System.Reflection;

namespace YourProject.Web.Entry;

/// <summary>
/// 解决单文件发布问题
/// </summary>
public class SingleFilePublish : ISingleFilePublish
{
/// <summary>
/// 解决单文件不能扫描的程序集
/// </summary>
/// <remarks>和 <see cref="IncludeAssemblyNames"/> 可同时配置</remarks>
/// <returns></returns>
public Assembly[] IncludeAssemblies()
{
// 需要 Furion 框架扫描哪些程序集就写上去即可
return Array.Empty<Assembly>();
}

/// <summary>
/// 解决单文件不能扫描的程序集名称
/// </summary>
/// <remarks>和 <see cref="IncludeAssemblies"/> 可同时配置</remarks>
/// <returns></returns>
public string[] IncludeAssemblyNames()
{
// 需要 Furion 框架扫描哪些程序集就写上去即可
return new[]
{
"YourProject.Application",
"YourProject.Core",
"YourProject.EntityFramework.Core",
"YourProject.Web.Core",
"Furion.Extras.ObjectMapper.Mapster" // 解决 Mapster 单文件失效问题,v3.5.3+版本后无需配置
};
}
}
配置说明

IncludeAssembliesIncludeAssemblyNames 的区别是前者是开发者直接返回 Assembley 集合,后者是直接返回名称,Furion 会自动加载程序集,可同时配置,也可以配置其中一个。

如果只配置启用一个,则另外一个返回 Array.Empty<Assembley>()Array.Empty<string>() 即可。

如果发布后出现 Mapster 不能映射问题,可将 Furion.Extras.ObjectMapper.Mapster 添加到 IncludeAssemblyNames 集合中即可。v3.5.3+ 版本后无需配置。

34.5.3 发布

小知识

如无需生成 .pdb 调试包可在生成中禁用即可。

34.5.4 自定义启动端口

默认单文件发布监听的是 https://localhost:5001,如果需要修改,可在 program.cs 中配置:

var builder = WebApplication.CreateBuilder(args).Inject();
builder.WebHost.UseUrls("https://*:8089");
var app = builder.Build();
app.Run();

这样就可以通过 https://localhost:8089 访问。

34.5.5 pm2 守护进程部署

34.5.5.1 运行弊端

正常情况下,将应用程序发布成单文件后,需点击 XXXXX.exe 进行启动,这时候程序自动打开终端(控制台),之后根据提示在浏览器上打开对应的地址即可。

但是这种方式有以下问题:

  • 必须保证终端/控制台一直运行
  • 终端/控制台有时候会出现假死的情况,导致应用程序无法访问
  • 无法实时监听应用程序资源使用情况(如 CPU,内存,日志等)
  • 无法映射端口启动
  • 集群变得复杂

34.5.5.2 pm2 守护进程部署

为了解决上述问题,推荐 NodeJS 一个非常强大的工具 pm2 https://pm2.keymetrics.io/,通过该工具可以解决上述的所有问题。

必要条件

  1. 系统必须安装 NodeJS 环境 https://nodejs.org/en/

相信大部分人电脑都已经安装。

  1. 通过 npmyarn 全局安装 pm2 工具

npm:

npm install pm2@latest -g

yarn:

yarn global add pm2
  1. 启动应用程序

使用 pm2 非常简单就可以启动守护进程应用程序。

pm2 start --name pms PMS.Web.Entry.exe
指定端口

如需指定端口,可使用下列命令:

pm2 start --name pms PMS.Web.Entry.exe -- --urls=https://localhost:8089

注意 -- 后面可以写完整的 dotnet 命令。

命令说明

pms.exe 为项目发布后的启动层名称,如果名称包含 空格,则使用双引号包裹,如 "p ms.exe"

--name 配置应用程序在 pm2 中的唯一标识。

start 后面跟着是 .exe 文件,在 linux/macos 下无需指定后缀名。

启动成功后即可通过浏览器访问指定端口,通常是 http://localhost:5000

PS C:\Users\bqrjsoft\Desktop\pms> pm2 start --name pms PMS.Web.Entry.exe
[PM2] Starting C:\Users\bqrjsoft\Desktop\pms\PMS.Web.Entry.exe in fork_mode (1 instance)
[PM2] Done.
┌─────┬────────┬─────────────┬─────────┬─────────┬──────────┬────────┬──────┬───────────┬──────────┬──────────┬──────────┬──────────┐
│ id │ name │ namespace │ version │ mode │ pid │ uptime │ ↺ │ status │ cpu │ mem │ user │ watching │
├─────┼────────┼─────────────┼─────────┼─────────┼──────────┼────────┼──────┼───────────┼──────────┼──────────┼──────────┼──────────┤
│ 0 │ pms │ default │ N/A │ fork │ 41764 │ 0s │ 0 │ online │ 0% │ 85.0mb │ bqrjsoft │ disabled │
└─────┴────────┴─────────────┴─────────┴─────────┴──────────┴────────┴──────┴───────────┴──────────┴──────────┴──────────┴──────────┘
PS C:\Users\bqrjsoft\Desktop\pms>

34.5.5.3 pm2 常见操作

  • 实时监听运行状态
pm2 monit
  • 显示运行日志
pm2 logs
  • 查看应用信息
pm2 info pms

注意,pms 为您配置的 --name 名称。

  • 随机启动
pm2 startup
pm2 save
Windows 下随机启动

可查阅 pm2-windows-startup

npm install pm2-windows-startup -g
pm2-startup install
pm2 save
  • 其他操作
// 重启应用
pm2 restart app_name

// 重载应用
pm2 reload app_name

// 停止应用
pm2 stop app_name

// 删除应用
pm2 delete app_name

更多 pm2 文档可查阅 https://pm2.keymetrics.io/docs/usage/quick-start/

34.5.6 反馈与建议

与我们交流

给 Furion 提 Issue