使用ServiceSelf解决.NET应用程序做服务的难题
1 ServiceSelf
为.NET 泛型主机的应用程序提供自安装为服务进程的能力,支持windows和linux平台。
功能
- 自我服务安装
- 自我服务卸载
- 自我服务日志监听
2 自我服务安装
虽然.NetCore提供了Microsoft.Extensions.Hosting.Systemd和Microsoft.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上关注此项目。
使用ServiceSelf解决.NET应用程序做服务的难题的更多相关文章
- 使用双引擎,让kbmmw 的客户端访问更方便(既给浏览器做服务,也给桌面程序做服务)
前面我们一直都讲了如何使用kbmmw smarthttpservice 给客户端提供REST 服务.主要都是返回给 浏览器访问的,如果我们使用delphi 开发桌面应用,如何使用这些服务呢?其实一切 ...
- Atitit. 解决80端口 System 占用pid 4,,找到拉个程序或者服务占用http 80服务
Atitit. 解决80端口 System 占用pid 4,,找到拉个程序或者服务占用http服务 这个是http.sys系统服务占用了... net stop http ,三,没法儿终止 1. 寻 ...
- 为什么不应该使用Zookeeper做服务发现?(转载)
转载自: http://dockone.io/article/78 [编者的话]本文作者通过ZooKeeper与Eureka作为Service发现服务(注:WebServices体系中的UDDI就是个 ...
- 为什么不应该使用ZooKeeper做服务发现
[编者的话]本文作者通过ZooKeeper与Eureka作为Service发现服务(注:WebServices体系中的UDDI就是个发现服务)的优劣对比,分享了Knewton在云计算平台部署服务的经验 ...
- 用XYNTService把Python程序变为服务
1. XYNTService的使用 1.1. 介绍 1.2. XYNTService 2. 用XYNTService把Python程序变为服务 1. XYNTService的使用 1.1. 介绍 通常 ...
- 使用Consul做服务发现的若干姿势
从2016年起就开始接触Consul,使用的主要目的就是做服务发现,后来逐步应用于生产环境,并总结了少许使用经验.最开始使用Consul的人不多,为了方便交流创建了一个QQ群,这两年微服务越来越火,使 ...
- Consul做服务发现
使用Consul做服务发现的若干姿势 https://www.cnblogs.com/bossma/p/9756809.html 从2016年起就开始接触Consul,使用的主要目的就是做服务发现,后 ...
- 使用.netFx4.0提供的方法解决32位程序访问64位系统的64位注册表
原文:使用.netFx4.0提供的方法解决32位程序访问64位系统的64位注册表 我们知道目标平台是32位的程序运行在64位的系统上,去访问部分注册表的时候系统自动重定向到win32node节点对应的 ...
- 在无人值守程序(服务)中调用Microsoft Graph
作者:陈希章 发表于 2017年5月31日 什么是无人值守程序(服务) 我在此前用了几篇文章分别介绍了在桌面应用程序(控制台),Web应用程序(ASP.NET MVC),以及PowerSehll脚本中 ...
- 掀起Azure AD的盖头来——深入理解Microsoft Graph应用程序和服务权限声明
作者:陈希章 发表于 2017年7月12日 引子 这是一篇计划外的文章.我们都知道要进行Microsoft Graph的开发的话,需要进行应用程序注册.这个在此前我已经有专门的文章写过了.但这里存在一 ...
随机推荐
- 变量调用分析——这个ball到底是那个ball?
public class Ball implements Rollable{ public static void main(String[] args) { Ball ball = new Ball ...
- 01 docker容器技术基础入门
本章内容: 1.container是什么? 2.LXC技术介绍 3.namespaces-名称空间,实现资源隔离 4.容器的资源分配--Cgroup,实现资源分配 5.LXC与dockers ---- ...
- webpack 3/4踩坑,我太难了,从安装、卸载、到使用,各相应的版本号,sass-loader报错-版本的原因,webpack -v 不识别,没卸载干净
-先说卸载: wabpack@4对应的每个插件的版本号都在最后 1 全局安装的话,npm uninstall webpack -g 有时候并不能卸载干净, 2 webpack -v 可判断是否安装成 ...
- WPF中转换与关键帧动画及报错:WPF动画找不到依赖属性:属性未指向路径“(0).(1)[3].(2)”中的 DependencyObject
WPF中的转换有: // 在二维 x-y 坐标系内围绕指定点按顺时针方向旋转对象. <RotateTransform /> // 在二维 x-y 坐标系中平移(移动)对象. <Tra ...
- HTTPS、HTTP/2前端入门篇
随着网络安全重要性日益凸显,越来越多的站点已经全站切换到HTTPS,其中很多HTTPS站点同时将HTTP协议升级到了HTTP/2.作为一只前端,最近一直在学习和应用相关知识点,便总结梳理如下. 一.何 ...
- 笔精墨妙,妙手丹青,微软开源可视化版本的ChatGPT:Visual ChatGPT,人工智能AI聊天发图片,Python3.10实现
说时迟那时快,微软第一时间发布开源库Visual ChatGPT,把 ChatGPT 的人工智能AI能力和Stable Diffusion以及ControlNet进行了整合.常常被互联网人挂在嘴边的& ...
- 【AI 全栈 SOTA 综述 】这些你都不知道,怎么敢说会 AI?【语音识别原理 + 实战】
章目录 前言语音识别原理 信号处理,声学特征提取 识别字符,组成文本 声学模型 语言模型 词汇模型语音声学特征提取:MFCC和LogFBank算法的原理实战一 ASR语音识别模型 ...
- ACM-NEFUOJ-汉诺塔问题
P200汉诺塔 #include<bits/stdc++.h> using namespace std; int main() { int n,i; long long s[40]; s[ ...
- CTF-Web-PHP反序列化
概念解释 PHP 反序列化漏洞又叫做 PHP 对象注入漏洞,我觉得这个表达很不直白,也不能说明根本的问题,不如我们叫他 PHP 对象的属性篡改漏洞好了(别说这是我说的~~) 反序列化漏洞的成因在于代码 ...
- 第一次博客:PTA题目集1-3总结
第一次博客:PTA题目集1-3总结 前言:JAVA是一门非常好的语言,因其面向对象的思想,在解决问题时思路与上学期学习的C语言截然不同,但是其优势也是显然易见的,特别是在写大型程序时其面向对象的思想, ...