首页 > 编程语言 >使用ServiceSelf解决.NET应用程序做服务的难题

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

时间:2023-04-23 12:56:05浏览次数:51  
标签:服务 windows 应用程序 监听 ServiceSelf 进程 NET 日志

1 ServiceSelf

.NET 泛型主机的应用程序提供自安装为服务进程的能力,支持windows和linux平台。

功能

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

2 自我服务安装

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

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

现在,你可以在使用ServiceSelf描述服务:

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,所以桌面用户看不到服务进程的控制台,也没有管道可以重定向来读取服务进程的控制输出。

ServiceSelf为服务进程集成了"自研的"的基于管道传输的Google.Protobuf结构化日志提供者,在监听者开启监听之后,这个日志提供者才会工作,把结构化的日志传输给监听者,监听者可以使用关键词来过滤得到完整的一条结构化日志,而不是只过滤得一条日志内容的某一行或几行,再把完整的结构化日志打印到监听者的Console上。也就是它不会在服务进程上让日志无脑地输出到串行化输出的低性能控制台,也不会让服务进程在没有监听者的情况下无脑的输出Google.Protobuf结构化日志,即这个日志组件对服务进程没有性能影响。

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

由于监听者与服务进程是同一个应用程序的不同进程,当应用程序的OutputType是WinExe模式且运行在windows时,这时候是没有Console的,ServiceSelf做为监听者角色时会检测和动态创建Console然后将日志输出到Console。

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

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

5 后记

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

标签:服务,windows,应用程序,监听,ServiceSelf,进程,NET,日志
From: https://www.cnblogs.com/kewei/p/17346228.html

相关文章

  • 【介绍】.NET新加特性介绍
    ​简介        当下的.Net新版本引进了几种新特性,包括全局命名空间引用、可空引用类型和顶级语句。这些特性在一定程度上改善了 .NET 平台的开发效率, 对于短小精干的小程序,这些新的特性无疑可以把开发效率提高到新的高度。正文全局引用命名空间        ......
  • centos部署.net5项目
    开发环境是vs2019创建一个.netcore项目 测试一下运行 然后发布到文件夹 将文件夹弄到服务器上安装.NET运行时sudorpm-Uvhhttps://packages.microsoft.com/config/centos/7/packages-microsoft-prod.rpmsudoyuminstalldotnet-sdk-5.0dotnet--info启动网站......
  • 记一次 .NET 某外贸ERP 内存暴涨分析
    一:背景1.讲故事上周有位朋友找到我,说他的API被多次调用后出现了内存暴涨,让我帮忙看下是怎么回事?看样子是有些担心,但也不是特别担心,那既然找到我,就给他分析一下吧。二:WinDbg分析1.到底是哪里的泄露这也是我一直在训练营灌输的理念,一定要知道是哪一边的暴涨,否则很可能就南......
  • Unlock the Power of High-Performance Networking with the IPQ9554
    UnlockthePowerofHigh-PerformanceNetworkingwiththeIPQ9554Intoday'sworld,reliableandhigh-speedinternetconnectivityisessentialforeverythingfromonlinegamingandstreamingtoremoteworkandlearning.Whetheryou'reaconsumer......
  • netty之TCP粘包拆包问题解决
    TCP粘包拆包问题解决什么TCP粘包和拆包问题假设客户端向服务端连续发送了两个数据包,分别用ABC和DEF来表示,那么服务端收到的数据可以分为以下三种情况:第一种情况,接收端正常收到两个数据包,即没有发生拆包和粘包的现象。第二种情况,接收端只收到一个数据包,这一个数据包中包含了发送端发......
  • 长连接Netty服务内存泄漏,看我如何一步步捉“虫”解决
    作者:京东科技王长春背景事情要回顾到双11.11备战前夕,在那个风雨交加的夜晚,一个急促的咚咚报警,惊破了电闪雷鸣的黑夜,将沉浸在梦香,熟睡的我惊醒。一看手机咚咚报警,不好!有大事发生了!电话马上打给老板:老板说:长连接吗?我说:是的!老板说:该来的还是要来的,最终还是来了,快,赶紧先把服......
  • C# 应用程序管理员运行
    右键项目-添加新项 改变UAC规则的level属性为 requireAdministrator,保存重新生成即可 ......
  • LearnETutorial 中文系列教程【翻译完成】
    在线阅读在线阅读(Gitee)ApacheCN学习资源目录人工智能中文教程C中文教程Golang中文教程HTML中文教程Java中文教程机器学习中文教程PHP中文教程Python中文教程R中文教程网络安全中文教程贡献指南本项目需要校对,欢迎大家提交PullRequest。请您勇敢地去翻译和改进翻译。虽然......
  • kubernetes1.27 kuberadm方式安装全过程
    配置hosts#master"10.102.4.13master">>/etc/hosts#node1"10.102.4.14node1">>/etc/hosts#node2"10.102.4.15node2">>/etc/hosts安装kubeadm、kubelet和kubectl(三台都要)cat<<EOF|sudotee/etc/yum.repos.......
  • mybatis-plus使用聚合函数报错---------net.sf.jsqlparser.parser.ParseException: En
    错误日志: Causedby:net.sf.jsqlparser.parser.ParseException:Encounteredunexpectedtoken:"with""WITH"atline62,column20.Wasexpectingoneof:"&""::"";""<<&q......