[.NET][C#.NET]走跳在Linux的人生(六)Daemon(Mono-Service)

因為一些歷史因素,系統內有些背景下的服務功能在Windows環境下是以Windows Service的方式常駐在系統記憶體中運作,這次要模擬遷移到Linux的環境,想起Daemon小惡魔,好在Mono也有解,我們來筆記。

 

1.Windows環境開發Windows服務程式 

新增Windows服務(.NET Framework)

 


2. 編輯Service程式碼 

打開Service1.cs程式碼撰寫一段常駐程式,每1分鐘執行1次,每次執行就寫log。 

另外也分別在服務程式的初始建構式、OnStart、OnStop紀錄log。

using log4net; 
using System; 
using System.ServiceProcess; 
using System.Timers; 
  
namespace MonoWinService 
{ 
    public partial class Service1 : ServiceBase 
    { 
        private static readonly ILog log = LogManager.GetLogger(typeof(MonoWinService.Service1)); 
        private static string LogUrl = @"/root/dotnet/winservice/log.txt"; 
  
        // new一個timer 
        private Timer timer = new Timer(); 
  
        public Service1() 
        { 
            InitializeComponent(); 
            //log 
            WriteLog("MonoWinService init"); 
        } 
  
        protected override void OnStart(string[] args) 
        { 
            //Debugger.Launch(); 
            // 設定timer的Handler 
            timer.Elapsed += new ElapsedEventHandler(timer_Elapsed); 
  
            // timer的時間間隔(單位: ms) 10執行1次 
            timer.Interval = 1000 * 10; 
  
            // 啟動timer 
            timer.Start(); 
  
            //log 
            WriteLog("MonoWinService OnStart"); 
        } 
  
        protected override void OnStop() 
        { 
            //Debugger.Launch(); 
            // 關閉timer 
            timer.Stop(); 
  
            //log 
            WriteLog("MonoWinService OnStop"); 
        } 
  
        protected override void OnShutdown() 
        { 
            //Debugger.Launch(); 
            // 關閉timer 
            timer.Stop(); 
  
            //log 
            WriteLog("MonoWinService OnShutdown"); 
        } 
  
        // timer的Handler 
        private void timer_Elapsed(object sender, EventArgs e) 
        { 
            try 
            { 
                //log 
                WriteLog($"MonoWinService Timer:{DateTime.Now.ToString()}"); 
            } 
            catch (Exception ex) 
            { 
                WriteLog($"MonoWinService exception:{ex.ToString()}"); 
            } 
        } 
  
        private void WriteLog(string message) 
        { 
            using (System.IO.StreamWriter file = 
           new System.IO.StreamWriter(LogUrl, true)) 
            { 
                file.WriteLine(string.Format($"{DateTime.Now.ToString("")} {message}")); 
            } 
        } 
    } 
} 

 


3.在Windows環境下以Visual Studio編譯

 


4.新增winservice資料夾 

登入Linux環境,打開Terminal程式碼 

mkdir /root/dotnet/winservice

 


5.從Windows過版到Linux環境 

先切到Service專案的Bin目錄,使用命令列指令pscp程式般移執行檔 

pscp -r *.* root@192.168.100.101:/root/dotnet/winservice/

 


6.啟動服務 

Linux環境下,打開Terminal,切換到/root/dotnet/winservice目錄後,輸入以下指令碼 

mono-service2 -l:/root/dotnet/winservice/monowinservice.lock /root/dotnet/winservice/MonoWinService.exe 

 

順便查看服務是否有啟動 

ps –ef | grep 'Mono'

查詢服務寫入log,從初始建構式、服務開始、每60秒寫1筆log

 

*如果指令已執行,但服務沒有啟動,可以打開 /var/log/messages 檔案查看, 像是我們第一次安裝時曾碰到過少了log4net組件問題

 


7.停止服務 

Linux環境下,找到服務的PID,然後kill 

 

找pid方法1: 

ps –ef | grep 'Mono' 

執行後找到第二個欄位中的數字

 

找pid方法2: 

打開剛剛鎖定的檔案monowinservice.lock

 

Kill 

kill 31675 

如果process刪除不了,可以用立刻強制執行的參數 

kill -9 31675 

 

daemon也ok了,接下來要來花一點時間筆記執行效能上的比較,下一篇繼續來試試.NET Core Vs Mono。

 


參考: 

Mono service 

Demo a net mono application on linux 

Demonisation of a .NET Mono application on Linux