创建

首先你要确保你已经安装了.NET Core 3.0或以上版本

老版本的Windows服务请看 这篇文章

  • 使用命令行创建:  dotnet new worker
  • 使用Visual Studio创建

中文版:

英文版:

创建的新项目包含两个文件。其中 Program.cs 文件是应用的启动程序。另外一个文件是 Worker.cs 文件,你可以在这个文件编写你的业务代码。

这看起来应该是相当的容易,但是为这个程序添加额外的并行后台服务,你还需要添加一个类,并让它继承 BackgroundService 类:

public class MyNewBackgroundWorker : BackgroundService
{
protected override Task ExecuteAsync(CancellationToken stoppingToken)
{
//Do something.
}
}

然后在 Program.cs 中,我们要做的只是把当前的Worker注册到服务集合(Service Collection)中即可。

.ConfigureServices((hostContext, services) =>
{
services.AddHostedService<Worker>();
services.AddHostedService<MyNewBackgroundWorker>();
});

实际上作为“后台服务”任务的运行程序, AddHostedService 方法已经在框架中存在了很长时间了。在之前我们已经完成的一篇关于ASP.NET Core托管服务的文章, 但是在当时场景中,我们托管是是整个应用,而非一个在你应用程序幕后运行的东西。

优化系统的 Worker.cs ,代码执行顺序是冲上往下依次执行的(程序开始-停止)

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging; namespace WorkerService
{
public class Worker : BackgroundService
{
private readonly ILogger<Worker> _logger; public Worker(ILogger<Worker> logger)
{
_logger = logger;
} public override Task StartAsync(CancellationToken cancellationToken)
{
_logger.LogInformation($"Worker started at: {DateTime.Now}");
return base.StartAsync(cancellationToken);
} protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
_logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
await Task.Delay(, stoppingToken);
}
} public override Task StopAsync(CancellationToken cancellationToken)
{
_logger.LogError($"Worker stopped at: {DateTime.Now}"); return base.StopAsync(cancellationToken);
} public override void Dispose()
{
_logger.LogInformation($"Worker disposed at: {DateTime.Now}"); base.Dispose();
}
}
}

部署Windows服务

需要引用  Microsoft.Extensions.Hosting.WindowsServices  Neget 包

Install-Package Microsoft.Extensions.Hosting.WindowsServices

修改 Program.cs 文件,添加 UseWindowsService() 方法调用

public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureServices((hostContext, services) =>
{
services.AddHostedService<Worker>();
})
.UseWindowsService();

这样代码部分就完成了。

然后使用 cmd 命令把我们发布后的程序代码部署成Windows服务,需要使用管理员权限运行CMD

借助 sc.exe 工具。sc.exe是帮助开发部署 WindowsNT 服务的工具,路径: C:\Windows\System32\sc.exe。这个网上教程一大堆,可以自行了解,这里不多介绍。

相关命令:

下面的 ServiceName 是自定义的,可以自行修改

## 创建服务
sc create ServiceName BinPath=E:\Work\Code\WindowsServiceDemo\WorkerService\bin\Debug\netcoreapp3.\WorkerService.exe ## 启动服务
sc start ServiceName ## 停止服务
sc stop ServiceName ## 删除服务
sc delete ServiceName ## 添加服务描述
sc description ServiceName "描述" ## 改变服务的启动方式 手动/自动/禁用
sc config ServiceName start= demand/auto/disabled

install.bat

set serviceName=ServiceName
set serviceFilePath=E:\Work\Code\WindowsServiceDemo\WorkerService\bin\Debug\netcoreapp3.\WorkerService.exe
set serviceDescription=服务描述 sc create %serviceName% BinPath=%serviceFilePath%
sc config %serviceName% start=auto
sc description %serviceName% %serviceDescription%
sc start %serviceName%
pause

unstall.bat

set serviceName=ServiceName

sc stop   %serviceName%
sc delete %serviceName% pause

最后使用管理员权限运行 install.bat

查看下服务面板

以上是参考 这边文章 编写的。

部署Linux服务

环境:一台全新的Centos 7.7.1908 系统

安装 .net core相关环境

参考:https://docs.microsoft.com/zh-cn/dotnet/core/install/linux-package-manager-centos7

注册 Microsoft 密钥和源:

 sudo rpm -Uvh https://packages.microsoft.com/config/centos/7/packages-microsoft-prod.rpm

安装 .NET Core SDK:

sudo yum install dotnet-sdk-3.0  -y

安装完成之后可以输入 dotnet --version 查看是否可以返回对应版本

修改代码

程序代码需要引用 Microsoft.Extensions.Hosting.Systemd  Neget包

Install-Package Microsoft.Extensions.Hosting.Systemd

修改  Program.cs  文件,添加  UseSystemd()  方法调用,可以和 UseWindowsService() 共存

        public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureServices((hostContext, services) =>
{
services.AddHostedService<Worker>();
})
.UseWindowsService()
.UseSystemd();

然后把发布文件移至linux系统

部署服务

linux的服务是通过systemd守护进程部署的。现在在系统中我们有了一个发布后的应用程序,我们需要为systemd创建配置文件部署服务。步骤如下:

创建一个.service文件(我们要部署服务,因此需要.service文件),填入以下内容。可以在Linux中直接创建或者通过windows创建然后拷贝至linux。

参考链接

[Unit]
Description= my test app
[Service]
Type=notify
ExecStart=/usr/bin/dotnet /home/demo/WorkerService.dll [Install]
WantedBy=multi-user.target
Description:描述,看个人需要是否添加。不需要可以去掉。只留下 [Service] 和 [Install]
Type=notify:当前服务启动完毕,会通知Systemd,再继续往下执行
ExecStart:启动当前服务的命令,程序如何启动,第一个路径是固定路径。第二个路径是应用程序的dll路径(可以自定义)
WantedBy:表示该服务所在的 Target服务组, multi-user.target,表示多用户命令行状态。

把 .service文件移动至  /etc/systemd/system/   固定目录下,假设自定义文件名称为:testapp.service(如果使用其他名称,请更改testapp)

使用systemctl命令重新加载新的配置文件

sudo systemctl daemon-reload

查看相关服务状态

sudo systemctl status testapp

您应该看到类似以下的内容:

这表明您已注册的新服务已禁用,我们可以通过运行以下命令来启动我们的服务:

sudo systemctl start testapp.service

重新运行 sudo systemctl status testapp  查看服务状态显示已激活正在运行中

设置服务开机自启

sudo systemctl enable testapp.service

到此我们的服务已经完整的部署到了linux系统中

现在我们有一个运行了systemd的应用程序,我们可以看看日志记录集成。使用systemd的好处之一是可以使用journalctl访问的集中式日志记录系统。

首先,我们可以使用journalctl(访问日志的命令)查看服务日志:

sudo journalctl -u testapp

可以看到我们的程序正在运行,可以使用 ↑↓ ← →查看日志内容。或者使用grep搜索。q  键退出

卸载自定义服务

servicename=testapp.service

systemctl stop $servicename
systemctl disable $servicename
rm -rf /etc/systemd/system/$servicename
rm -rf /etc/systemd/system/$servicename symlinks that might be related
systemctl daemon-reload
systemctl reset-failed

相关链接

部署Windows服务相关链接:

https://www.cnblogs.com/lwqlun/p/12038062.html

https://devblogs.microsoft.com/aspnet/net-core-workers-as-windows-services/

https://www.cnblogs.com/Rwing/p/net-core-workers-as-windows-services.html

自定义安装服务相关配置相关链接:
http://www.ruanyifeng.com/blog/2016/03/systemd-tutorial-commands.htmlhttps://www.cnblogs.com/jhxxb/p/10654554.html

 

systemd命令相关链接:

https://www.cnblogs.com/tsdxdx/p/7288490.html

http://www.ruanyifeng.com/blog/2016/03/systemd-tutorial-commands.html

https://www.cnblogs.com/zyh121344305/p/8677015.html

https://www.cnblogs.com/jhxxb/p/10654554.html

部署Linux服务相关链接:

https://devblogs.microsoft.com/dotnet/net-core-and-systemd/

https://stackoverflow.com/questions/51589504/asp-net-core-2-0-unable-to-start-service-on-debian

源码地址:https://github.com/RainFate/WindowsServiceDemo/tree/Init/WorkerService

.NET Core部署Windows服务的更多相关文章

  1. netcore项目在Windows部署:使用NSSM部署Windows服务

    NSSM部署Windows服务 1 准备工作 在Windows平台部署Asp.net core应用程序一般采用IIS,但是如果我们的net core应用执行的是定时任务,需要开机自启,稳定运行的话,使 ...

  2. 使用.NET Core创建Windows服务(二) - 使用Topshelf方式

    原文:Creating Windows Services In .NET Core – Part 2 – The "Topshelf" Way 作者:Dotnet Core Tut ...

  3. C#基于Quartz.NET实现任务调度并部署Windows服务

    一.Quartz.NET介绍 Quartz.NET是一个强大.开源.轻量的作业调度框架,是 OpenSymphony 的 Quartz API 的.NET移植,用C#改写,可用于winform和asp ...

  4. .NET Core 创建Windows服务

    .NET Core 创建Windows服务 作者:高堂 原文地址:https://www.cnblogs.com/gaotang/p/10850564.html 写在前面 使用 TopShelf+Au ...

  5. 使用.NET Core创建Windows服务(一) - 使用官方推荐方式

    原文:使用.NET Core创建Windows服务(一) - 使用官方推荐方式 原文:Creating Windows Services In .NET Core – Part 1 – The &qu ...

  6. 【JavaService】使用Java编写部署windows服务

    如果你玩windows系统,你对服务这个东西并不会陌生,服务可以帮我们做很多事情,在不影响用户正常工作的情况下,可以完成很多我们需要的需求. 众所周知,微软的visio studio内置的Servic ...

  7. 使用.NET Core创建Windows服务 - 使用.NET Core工作器方式

    原文:Creating Windows Services In .NET Core – Part 3 – The ".NET Core Worker" Way 作者:Dotnet ...

  8. 【转】.net core开发windows服务

    .net core开发windows服务 文建Blog

  9. ASP.NET Core使用TopShelf部署Windows服务

    asp.net core很大的方便了跨平台的开发者,linux的开发者可以使用apache和nginx来做反向代理,windows上可以用IIS进行反向代理. 反向代理可以提供很多特性,固然很好.但是 ...

随机推荐

  1. OSI协议

    物理层: 网线连接在客户端计算机上,其实是连接在了计算机的一个叫做网卡的设备上,网卡是专门负责与外界通信的.网线一般是双绞线或者光缆,也可以使用无线电波,中间经过交换机,路由器,防火墙等等一堆设备统称 ...

  2. 一次m2eclipse的安装大坑经历之http://m2eclipse.sonatype.org/sites/m2e

    m2eclipse 插件的安装在<Maven 实战>这本书上是这么说的: ”由于Eclipse默认没有集成对Maven的支持,幸运的是由Maven之父Jason Van Zyl创立的Son ...

  3. Codeforces Round #601 (Div. 2) A Changing Volume

    好吧,其实我拿到这个题的时候,首先想到了bfs,写完之后,开开森森的去交代码,却在第二个数据就TEL,然后优化半天,还是不行. 最终,我盯着1,2,5发呆半天,wc,然后直接贪心 #include&l ...

  4. 如何面试QA(面试官角度)

    面试是一对一 或者多对一的沟通,是和候选人 互相交换信息.平等的. 面试的目标是选择和雇佣最适合的人选.是为了完成组织目标.协助人力判断候选人是否合适空缺职位. 面试类型: (1)预判面试(查看简历后 ...

  5. Spring MVC3 + Ehcache 缓存实现

    转自:http://www.coin163.com/it/490594393324999265/spring-ehcache Ehcache在很多项目中都出现过,用法也比较简单.一般的加些配置就可以了 ...

  6. java基础(五)之static关键词的作用

    static关键词的作用 1.静态成员变量的语法特定2.静态函数的语法特定3.静态代码块的语法特定 定义静态成员变量 Person.java class Person{ static int a; } ...

  7. leetcode 1214 Two Sum BSTs

    function rob(a, b, target) { var hash = {} var stack = [a] while (queue.length) { var node = stack.p ...

  8. js面向对象的程序设计 --- 中篇(创建对象) 之 原型模式

    ·原型模式 我们创建的每一个函数都由一个prototype(原型)属性,这个属性是一个指针,指向一个对象,而这个对象的用途是包含可以由特定类型的所有 实例共享的属性和方法. 如果按照字面意思来理解,那 ...

  9. 进程间通讯IPC的几种方式总结

    Linux进程间的通讯 Unix发展做出重大贡献的两大主力AT&T的贝尔实验室及BSD(加州大学伯克利分校的伯克利软件发布中心)在进程间通信方面的侧重点有所不同.前者对Unix早期的进程间通信 ...

  10. OpenCV函数:提取轮廓相关函数使用方法

    opencv中提供findContours()函数来寻找图像中物体的轮廓,并结合drawContours()函数将找到的轮廓绘制出.首先看一下findContours(),opencv中提供了两种定义 ...