使用ServiceSelf解决.NET应用程序做服务的难题

科技资讯 投稿 8800 0 评论

使用ServiceSelf解决.NET应用程序做服务的难题

1 ServiceSelf

功能

    自我服务安装
  • 自我服务卸载
  • 自我服务日志监听

2 自我服务安装

Microsoft.Extensions.Hosting.Systemd和Microsoft.Extensions.Hosting.WindowsServices两个服务生命周期包,但在服务安装这块目前还非常不便:在windows平台,需要管理员身份使用sc.exe工具来安装服务;在linux平台,需要自己手动写服务单元文件和使用systemctl加载服务。不常用的sc和服务单元文件的内容知识,就像学了外语之后又长期不用外语的我们一样,时间一久就忘记。而且windows服务进程的默认工作目录是%SystemRoot%\System32,在没有日志组件的帮助下,sc.exe安装的服务在运行后我们可能就掉到工作目录的坑里,影响包括但不限于配置文件的读取、asp.netcore的ContentRoot、wwwroot静态文件等。

自我服务安装的能力,它提供了windows服务和linux的systemd服务的公共参,同时另外提供windows独有的服务配置和systemd独有的完整服务配置,此外还解决了windows服务没有工作目录配置的缺陷。

var serviceName = "myapp";
var serviceOptions = new ServiceOptions
{
    Arguments = new[] { new Argument("key", "value" },
    Description = "这是演示示例应用",
};
serviceOptions.Linux.Service.Restart = "always";
serviceOptions.Linux.Service.RestartSec = "10";
serviceOptions.Windows.DisplayName = "演示示例";
serviceOptions.Windows.FailureActionType = WindowsServiceActionType.Restart;

// serviceName和serviceOptions甚至可以为null
if (Service.UseServiceSelf(args, serviceName, serviceOptions
{
    var host = Host.CreateDefaultBuilder(args
        // 为Host配置UseServiceSelf(
        .UseServiceSelf(                     
        .Build(;

    host.Run(;
}

然后在控制台下以管理员或root身份执行如下命令:

./myapp start // 安装并启动服务

3 自我服务卸载

在控制台下以管理员或root身份执行如下命令:

./myapp stop // 停止并删除服务

4 自我服务日志监听

虽然有文件日志、大型的日志采集平台或框架等,但他们也取代不了控制台实时显示的日志,相反他们是互补的。控制台模式启动时,我们很容易直接在控制台看到实时日志的打印,但安装为服务后,查看控制台日志变得不容易或无法实现,在linux平台有journalctl,它是基于管道的,它无法知道一条日志内容的边界,很难把符合过滤特征的日志完整显示;windows平台有session隔离机制,服务进程和桌面用户进程不在同一个session,所以桌面用户看不到服务进程的控制台,也没有管道可以重定向来读取服务进程的控制输出。

之所以要自己实现基于管道传输的Google.Protobuf结构化日志提供者,而不直接使用Microsoft的EventSourceLoggerProvider,是因为跨进程读取日志时需要依赖Microsoft.Diagnostics.Tracing.TraceEvent,这个包非常大而全,其依赖项也特别多,而我们仅仅日志这一小功能而已。

现在输入logs子命令,就在Console上输出服务进程的实时日志:

./myapp logs // 控制台输出服务的日志
./myapp logs filter="key words" // 控制台输出匹配了"key words"的服务的日志

5 后记

ServiceSelf在api设计上十分精炼,你只要关注Service.UseServiceSelf(IHostBuilder.UseServiceSelf(两个函数即可,但可以为你的服务进程提供非常完整的解决方案,您可以到 github上关注此项目。

编程笔记 » 使用ServiceSelf解决.NET应用程序做服务的难题

赞同 (50) or 分享 (0)
游客 发表我的评论   换个身份
取消评论

表情
(0)个小伙伴在吐槽