Escrevendo um daemon Linux em C #
Quando você quiser executar o processo .NET Core como um daemon no Red Hat Enterprise Linux, você pode criar uma unidade sistematorida personalizada. Hoje vou escrever sobre dois exemplos de unidade sistemada personalizada para .NET Core. Um é um tipo de oneshot para executar um aplicativo de console .NET Core e o outro é um tipo simples para executar um aplicativo ASP.NET Core Web.
Tipo oneshot com um aplicativo de console
Construindo um aplicativo
Você pode usar no sistema com especificação do diretório de projetos como um diretório de trabalho. No entanto, vamos construir um arquivo binário e usá-lo para sistemato. Crie seu projeto com final de edição Programa.cs conforme seguido. dotnet run
dotnet new
using System;
using System.IO;
namespace ConsoleApplication
{
public class Program
{
public static void Main(string[] args)
{
var path = Path.GetTempFileName();
File.WriteAllText(path, "Hello Temp File!");
Console.WriteLine($"Wrote temp file: {path}");
}
}
}
Em seguida, publique o projeto com comando. Você verá os arquivos binários sob diretório. dotnet publishbin/<Configuration>/<Framework>
$ dotnet publish -c Release
Publishing ConsoleApp for .NETCoreApp,Version=v1.1
Project ConsoleApp (.NETCoreApp,Version=v1.1) was previously compiled. Skipping compilation.
publish: Published to /home/tatanaka/Documents/git/tanaka-takayoshi/SystemdExample/1.1/ConsoleApp/bin/Release/netcoreapp1.1/publish
Published 1/1 projects successfully
Criando um sistema personalizado
No início, crie um usuário para executar daemon e um diretório de trabalho.
$ sudo useradd -s /sbin/nologin dotnetuser
$ sudo mkdir /var/SystemdExample
$ sudo cp /home/tatanaka/Documents/git/tanaka-takayoshi/SystemdExample/1.1/ConsoleApp/bin/Release/netcoreapp1.1/publish/* /var/SystemdExample
$ sudo chown -R dotnetuser:dotnetuser /var/SystemdExample
Em seguida, crie um arquivo de unidade sistematod personalizada em diretório. O nome do arquivo deve ser . Eu criei. /etc/systemd/system/<unit-name>.<unit-type>
/etc/systemd/system/netcore-console-example.service
[Unit]
Description=Example for .NET Core ConsoleApp with systemd
DefaultDependencies=no
[Service]
Type=oneshot
RemainAfterExit=no
ExecStart=/opt/rh/rh-dotnetcore11/root/usr/bin/dotnet ConsoleApp.dll
WorkingDirectory=/var/SystemdExample
User=dotnetuser
Group=dotnetuser
[install]
Você deve especificar o caminho completo do dotnet no ExecStart. O acima é o caso do Red Hat fornecido .NET Core 1.1. Então você pode executar o daemon com o comando. Você pode ver a saída do console com comando ou comando. systemctlsystemctl statusjournalctl
$ sudo systemctl start netcore-console-example.service
$ sudo systemctl status netcore-console-example.service
● netcore-console-example.service - Example for .NET Core ConsoleApp with systemd
Loaded: loaded (/etc/systemd/system/netcore-console-example.service; enabled; vendor preset: disabled)
Active: inactive (dead) since Fri 2017-02-24 00:29:16 JST; 13s ago
Process: 18075 ExecStart=/opt/rh/rh-dotnetcore11/root/usr/bin/dotnet ConsoleApp.dll (code=exited, status=0/SUCCESS)
Main PID: 18075 (code=exited, status=0/SUCCESS)
Feb 24 00:29:16 localhost.localdomain systemd[1]: Starting Example for .NET Core ConsoleApp with systemd...
Feb 24 00:29:16 localhost.localdomain dotnet[18075]: Wrote temp file: /tmp/tmph1ok6H.tmp
Feb 24 00:29:16 localhost.localdomain systemd[1]: Started Example for .NET Core ConsoleApp with systemd.
$ journalctl -u netcore-console-example.service -e
Feb 24 00:29:16 localhost.localdomain systemd[1]: Starting Example for .NET Core ConsoleApp with systemd...
Feb 24 00:29:16 localhost.localdomain dotnet[18075]: Wrote temp file: /tmp/tmph1ok6H.tmp
Feb 24 00:29:16 localhost.localdomain systemd[1]: Started Example for .NET Core ConsoleApp with systemd.
$ sudo cat /tmp/tmph1ok6H.tmp
Hello Temp File!
Trabalhando com PrivateTemp
Na unidade sistemal acima, o programa grava um arquivo em pasta temporária. Às vezes, você quer escrever um arquivo temporário, que é protegido de outros usuários. Você pode usar o PrivateTemp com especificação na seção. [Service]
[Service]
Type=oneshot
RemainAfterExit=no
ExecStart=/opt/rh/rh-dotnetcore11/root/usr/bin/dotnet ConsoleApp.dll
WorkingDirectory=/var/SystemdExample
User=dotnetuser
Group=dotnetuser
PrivateTemp=true
Depois de recarregar o arquivo da unidade, o programa pode acessar diretório como antes, mas este não é um diretório real. /tmp/tmp
$ sudo systemctl daemon-reload
$ sudo systemctl start netcore-console-example.service
$ sudo systemctl status netcore-console-example.service
● netcore-console-example.service - Example for .NET Core ConsoleApp with systemd
Loaded: loaded (/etc/systemd/system/netcore-console-example.service; enabled; vendor preset: disabled)
Active: inactive (dead) since Fri 2017-02-24 00:35:46 JST; 12s ago
Process: 18415 ExecStart=/opt/rh/rh-dotnetcore11/root/usr/bin/dotnet ConsoleApp.dll (code=exited, status=0/SUCCESS)
Main PID: 18415 (code=exited, status=0/SUCCESS)
Feb 24 00:35:46 localhost.localdomain systemd[1]: Starting Example for .NET Core ConsoleApp with systemd...
Feb 24 00:35:46 localhost.localdomain dotnet[18415]: Wrote temp file: /tmp/tmpJLWAGC.tmp
Feb 24 00:35:46 localhost.localdomain systemd[1]: Started Example for .NET Core ConsoleApp with systemd.
$ ls /tmp/tmpJLWAGC.tmp
ls: cannot access /tmp/tmpJLWAGC.tmp: No such file or directory
Tipo simples com um aplicativo web
Construindo um aplicativo
Agora vamos construir um aplicativo web ASP.NET Core. Hoje eu uso um projeto de modelo padrão.
$ dotnet new -t web
Created new C# project in /home/tatanaka/Documents/git/tanaka-takayoshi/SystemdExample/1.1/WebApp.
$ dotnet restore
** snipped**
log : Restore completed in 9721ms.
$ dotnet publish -c Release
Publishing WebApp for .NETCoreApp,Version=v1.1
** snipped **
publish: Published to /home/tatanaka/Documents/git/tanaka-takayoshi/SystemdExample/1.1/WebApp/bin/Release/netcoreapp1.1/publish
Published 1/1 projects successfully
Agora pode ser executado com comando dotnet.
$ dotnet bin/Release/netcoreapp1.1/publish/WebApp.dll
info: Microsoft.Extensions.DependencyInjection.DataProtectionServices[0]
User profile is available. Using '/home/tatanaka/.aspnet/DataProtection-Keys' as key repository; keys will not be encrypted at rest.
Hosting environment: Production
Content root path: /home/tatanaka/Documents/git/tanaka-takayoshi/SystemdExample/1.1/WebApp
Now listening on: http://localhost:5000
Application started. Press Ctrl+C to shut down.
Criando um sistema personalizado
Eu uso o mesmo dotnetuser para este Aplicativo Web.
$ sudo mkdir /var/SystemdExample
$ sudo cp -R bin/Release/netcoreapp1.1/publish/* /var/SystemdWebExample
$ sudo chown -R dotnetuser:dotnetuser /var/SystemdWebExample
Em seguida, crie um arquivo de unidade sistematod personalizada . /etc/systemd/system/netcore-web-example.service
[Unit]
Description=Example for .NET Core WebApp with systemd
DefaultDependencies=no
Wants=network.target # network is required
After=network.target
[Service]
ExecStart=/opt/rh/rh-dotnetcore11/root/usr/bin/dotnet WebApp.dll
WorkingDirectory=/var/SystemdWebExample
Restart=always
RestartSec=10 # Restart service after 10 seconds if dotnet service crashes
SyslogIdentifier=dotnet-example
User=dotnetuser
Group=dotnetuser
PrivateTmp=true
Environment=ASPNETCORE_ENVIRONMENT=Production # specify environment variable for environment
Environment=ASPNETCORE_URLS=http://*:8080 # specify environement variable for listening port
[Install]
WantedBy = multi-user.target
Finalmente, você pode executar ASP.NET aplicativo Core como um daemon Linux. Observe que este aplicativo ouve a porta 8080 em vez de ASP.NET Core padrão 5000, pois especifico a variável ambiente no arquivo unitário. ASPNETCORE_URLS
$ systemctl start netcore-web-example.service
[tatanaka@localhost WebApp]$ systemc^C
[tatanaka@localhost WebApp]$ sudo systemctl status netcore-web-example.service
[sudo] password for tatanaka:
● netcore-web-example.service - Example for .NET Core WebApp with systemd
Loaded: loaded (/etc/systemd/system/netcore-web-example.service; disabled; vendor preset: disabled)
Active: active (running) since Sat 2017-02-25 01:02:12 JST; 11s ago
Main PID: 7041 (dotnet)
CGroup: /system.slice/netcore-web-example.service
└─7041 /opt/rh/rh-dotnetcore11/root/usr/bin/dotnet WebApp.dll
Feb 25 01:02:12 localhost.localdomain systemd[1]: Started Example for .NET Core WebApp with systemd.
Feb 25 01:02:12 localhost.localdomain systemd[1]: Starting Example for .NET Core WebApp with systemd...
Feb 25 01:02:12 localhost.localdomain dotnet-example[7041]: info: Microsoft.Extensions.DependencyInjection.DataProtectionServices[0]
Feb 25 01:02:12 localhost.localdomain dotnet-example[7041]: User profile is available. Using '/home/dotnetuser/.aspnet/DataProtection-Keys' as key repository; keys will not be encrypted at rest.
Feb 25 01:02:13 localhost.localdomain dotnet-example[7041]: Hosting environment: Production
Feb 25 01:02:13 localhost.localdomain dotnet-example[7041]: Content root path: /var/SystemdWebExample
Feb 25 01:02:13 localhost.localdomain dotnet-example[7041]: Now listening on: http://*:8080
Feb 25 01:02:13 localhost.localdomain dotnet-example[7041]: Application started. Press Ctrl+C to shut down.
$ journalctl -u netcore-web-example -xf
-- Logs begin at Mon 2017-02-20 11:58:31 JST. --
Feb 25 01:02:36 localhost.localdomain dotnet-example[7041]: info: Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware[2]
Feb 25 01:02:36 localhost.localdomain dotnet-example[7041]: Sending file. Request path: '/images/banner4.svg'. Physical path: '/var/SystemdWebExample/wwwroot/images/banner4.svg'
Feb 25 01:02:36 localhost.localdomain dotnet-example[7041]: info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
Feb 25 01:02:36 localhost.localdomain dotnet-example[7041]: Request finished in 0.1973ms 200 image/svg+xml
Feb 25 01:02:36 localhost.localdomain dotnet-example[7041]: info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
Feb 25 01:02:36 localhost.localdomain dotnet-example[7041]: Request starting HTTP/1.1 GET http://localhost:8080/favicon.ico
Feb 25 01:02:36 localhost.localdomain dotnet-example[7041]: info: Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware[2]
Feb 25 01:02:36 localhost.localdomain dotnet-example[7041]: Sending file. Request path: '/favicon.ico'. Physical path: '/var/SystemdWebExample/wwwroot/favicon.ico'
Feb 25 01:02:36 localhost.localdomain dotnet-example[7041]: info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
Feb 25 01:02:36 localhost.localdomain dotnet-example[7041]: Request finished in 0.5824ms 200 image/x-icon
No entanto, isso não é suficiente para o uso de produção para ASP.NET Core. Você pode ter que configurar um servidor proxy reverso como nginx, firewalls e assim por diante. Além disso, se você quiser saber muito mais sobre sistema, por favor, consulte nosso documento.
Para obter informações adicionais e artigos sobre o .NET Core, visite nossa página da web .NET Core para mais informações sobre este tópico.