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+版本后无需配置
};
}
}
IncludeAssemblies
和 IncludeAssemblyNames
的区别是前者是开发者直接返回 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/,通过该工具可以解决上述的所有问题。
必要条件
- 系统必须安装
NodeJS
环境 https://nodejs.org/en/
相信大部分人电脑都已经安装。
- 通过
npm
或yarn
全局安装pm2
工具
npm:
npm install pm2@latest -g
yarn:
yarn global add pm2
- 启动应用程序
使用 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。