dotnet core 網(wǎng)站一個(gè)痛點(diǎn)是不會(huì)自動(dòng)重啟。
ftp上傳更新后需要查找原先的進(jìn)程,kill掉那個(gè)進(jìn)程唱歧,然后啟動(dòng)。
想想原先dotnet ftp直接覆蓋就ok了粒竖,不用啟動(dòng)一個(gè)shell颅崩,登陸,ps -aux|grep dotnet 蕊苗,找到那個(gè)進(jìn)程沿后, kill 進(jìn)程號(hào),然后 到 網(wǎng)站目錄下朽砰,nohup dotnet xxx.dll &? .
我想尖滚,可以寫個(gè)小程序,進(jìn)行這幾步操作瞧柔。
但有個(gè)問(wèn)題漆弄,怎么知道文件改動(dòng)了。想到有個(gè)FileSystemWatcher的類造锅,能夠解決這個(gè)問(wèn)題撼唾。
最初是考慮監(jiān)視 .dll 文件 ,后來(lái)想哥蔚,如果有多個(gè) .dll 文件倒谷,一個(gè)替換就啟動(dòng)一次,那不是需要啟動(dòng)多次嗎肺素?后來(lái)考慮延時(shí)啟動(dòng)恨锚,比如 10秒后,.dll文件沒(méi)有被替換了倍靡,就重啟猴伶,但延時(shí)的時(shí)間不好控制。后來(lái)想塌西,是不是考慮復(fù)雜了他挎。直接設(shè)置一個(gè)文件,如果文件存在就重啟捡需,監(jiān)視程序重啟后把那個(gè)文件刪除不就可以了办桨。web發(fā)布的時(shí)候把那個(gè)文件設(shè)為總是復(fù)制。ftp上傳的時(shí)候最后上傳這個(gè)文件就可以了站辉。
寫好代碼呢撞,測(cè)試损姜。通過(guò)。
Program.cs
using System;
using System.IO;
using System.Configuration;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Configuration.Json;
using System.Diagnostics;
namespace dog
{
? ? class Program
? ? {
? ? ? ? static void read_config()
? ? ? ? {
? ? ? ? ? ? var builder = new ConfigurationBuilder();
? ? ? ? ? ? builder.AddJsonFile("dog.json");
? ? ? ? ? ? IConfigurationRoot config =? builder.Build();?
? ? ? ? ? ? file_path = config["file_path"];
? ? ? ? ? ? command = config["command"];
? ? ? ? ? ? argument = config["argument"];
? ? ? ? ? ? find = config["find"];
? ? ? ? ? ? debug_file = config["debug_file"];
? ? ? ? ? ? command2 = config["command2"];
? ? ? ? ? ? argument2 = config["argument2"];
? ? ? ? ? ? watch_create_file = config["watch_create_file"];
? ? ? ? }
? ? ? ? public static string file_path = "";
? ? ? ? public static string? command = "";
? ? ? ? public static string? argument = "";
? ? ? ? public static string? find = "";
? ? ? ? public static string? debug_file = "";
? ? ? ? public static string? command2 = "";
? ? ? ? public static string? argument2 = "";
? ? ? ? public static string watch_create_file = "";
? ? ? ? static void restart()
? ? ? ? {
? ? ? ? ? ? string pid = "";
? ? ? ? ? ? var psi = new System.Diagnostics.ProcessStartInfo(command, argument);
? ? ? ? ? ? psi.RedirectStandardOutput = true;
? ? ? ? ? ? using (var process = System.Diagnostics.Process.Start(psi))
? ? ? ? ? ? {
? ? ? ? ? ? ? ? var output = process.StandardOutput.ReadToEnd();
? ? ? ? ? ? ? ? string[] lines = output.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
? ? ? ? ? ? ? ? foreach(string aLine in lines)
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? if (aLine.IndexOf(find) != -1)
? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? string[] lines2 = aLine.Split(new string[]{" "},StringSplitOptions.RemoveEmptyEntries);
? ? ? ? ? ? ? ? ? ? ? ? pid = lines2[1];
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ? if(pid!=""){
? ? ? ? ? ? ? ? command = "kill";
? ? ? ? ? ? ? ? argument = pid;
? ? ? ? ? ? ? ? psi = new System.Diagnostics.ProcessStartInfo(command, argument);
? ? ? ? ? ? ? ? psi.RedirectStandardOutput = true;
? ? ? ? ? ? ? ? using (var process = System.Diagnostics.Process.Start(psi))
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? psi = new System.Diagnostics.ProcessStartInfo(command2, argument2);
? ? ? ? ? ? ? ? psi.RedirectStandardOutput = true;
? ? ? ? ? ? ? ? using (var process = System.Diagnostics.Process.Start(psi))
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? static void Main(string[] args)
? ? ? ? {
? ? ? ? ? ? read_config();? ? ? ? ?
? ? ? ? ? ? WatcherStrat(file_path, "*.prop");? ? ? ? ? ?
? ? ? ? ? ? Console.ReadKey();? ? ? ?
? ? ? ? }
? ? ? ? private static void WatcherStrat(string path, string filter)
? ? ? ? {
? ? ? ? ? ? FileSystemWatcher watcher = new FileSystemWatcher();
? ? ? ? ? ? watcher.Path = path;
? ? ? ? ? ? watcher.Filter = filter;
? ? ? ? ? ? watcher.Changed += new FileSystemEventHandler(OnProcess);
? ? ? ? ? ? watcher.Created += new FileSystemEventHandler(OnProcess);
? ? ? ? ? ? watcher.Deleted += new FileSystemEventHandler(OnProcess);
? ? ? ? ? ? watcher.Renamed += new RenamedEventHandler(OnRenamed);
? ? ? ? ? ? watcher.EnableRaisingEvents = true;
? ? ? ? ? ? watcher.NotifyFilter = NotifyFilters.Attributes | NotifyFilters.CreationTime | NotifyFilters.DirectoryName | NotifyFilters.FileName | NotifyFilters.LastAccess
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? | NotifyFilters.LastWrite | NotifyFilters.Security | NotifyFilters.Size;
? ? ? ? ? ? watcher.IncludeSubdirectories = true;
? ? ? ? }
? ? ? ? private static void OnProcess(object source, FileSystemEventArgs e)
? ? ? ? {
? ? ? ? ? ? if (e.ChangeType == WatcherChangeTypes.Created)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? OnCreated(source, e);
? ? ? ? ? ? }
? ? ? ? ? ? else if (e.ChangeType == WatcherChangeTypes.Changed)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? OnChanged(source, e);
? ? ? ? ? ? }
? ? ? ? ? ? else if (e.ChangeType == WatcherChangeTypes.Deleted)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? OnDeleted(source, e);
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? private static void OnCreated(object source, FileSystemEventArgs e)
? ? ? ? {
? ? ? ? ? ? Console.WriteLine("文件新建事件處理邏輯 {0}? {1}? {2}", e.ChangeType, e.FullPath, e.Name);
? ? ? ? ? ? string file_name = System.IO.Path.GetFileName(e.FullPath);
? ? ? ? ? ? if(file_name==watch_create_file){
? ? ? ? ? ? ? ? restart();
? ? ? ? ? ? ? ? System.IO.File.Delete(e.FullPath);
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? private static void OnChanged(object source, FileSystemEventArgs e)
? ? ? ? {
? ? ? ? ? ? Console.WriteLine("文件改變事件處理邏輯{0}? {1}? {2}", e.ChangeType, e.FullPath, e.Name);
? ? ? ? }
? ? ? ? private static void OnDeleted(object source, FileSystemEventArgs e)
? ? ? ? {
? ? ? ? ? ? Console.WriteLine("文件刪除事件處理邏輯{0}? {1}? {2}", e.ChangeType, e.FullPath, e.Name);
? ? ? ? }
? ? ? ? private static void OnRenamed(object source, RenamedEventArgs e)
? ? ? ? {
? ? ? ? ? ? Console.WriteLine("文件重命名事件處理邏輯{0}? {1}? {2}", e.ChangeType, e.FullPath, e.Name);
? ? ? ? }
? ? }
}
dog.json
{
? "file_path": "/data/wwwroot/xxxxxxx/",
? "command": "ps",
? "argument": " -aux",
? "find": "dotnet core_xxxxx.dll",
? "debug_file": "/root/dog/debug.txt",
? "command2":"nohup",
? "argument2":"/etc/init.d/dotnet_start.sh &",
? "watch_create_file":"restart.prop"
}