1. 程式人生 > 實用技巧 >JMS微服務開發示例(六)安全退出程序

JMS微服務開發示例(六)安全退出程序

預設情況下,如果在linux,需要關閉微服務程序,請務必使用 kill -15 程序id 命令,其他命令可能會直接關閉程序,造成資料丟失。

例如,有個後臺任務,執行了一半,這時候程序突然關閉了,會形成一些無法預計的後果。

Kill -15 命令的安全性

預設情況下,當發出kill -15命令,微服務需要按順序,做完以下事情後,程序才會關閉:

1、執行IProcessExitHandler新增的任務

2、斷開閘道器連線

3、等待事務託管中心事務清零

4、等待定時任務執行完畢

5、等待客戶端請求數清零

所以,為了保證資料完整性,對於一些後臺執行的任務,如果不是使用MicroServiceHost.RegisterScheduleTask

開啟的定時任務,那麼,您需要手動寫一些程式碼保證你的任務執行完畢後,程序才會退出。

可以參考以下示例:

    /// <summary>
    /// 單個使用者事件處理佇列
    /// </summary>
    class UserActionQueue:IDisposable
    {
        System.Threading.AutoResetEvent _waitObj = new System.Threading.AutoResetEvent(false);
        ConcurrentQueue<Action> Actions { get
; } public long UserId { get; } IProcessExitHandler _processExitHandler; bool _exited; public UserActionQueue(long userid) { this.UserId = userid; this.Actions = new ConcurrentQueue<Action>(); _processExitHandler = Global.ServiceProvider.GetService<JMS.IProcessExitHandler>();
//當程序退出時,呼叫onProcessExit() _processExitHandler.AddHandler(onProcessExit); new Thread(run).Start(); } private void onProcessExit() { try { var obj = _waitObj; _waitObj = null; obj.Set(); obj.Dispose(); while(!_exited) //只有_exited = true時,才表示任務執行完畢,不會有任務執行了一半 { Thread.Sleep(100); } } catch { } } /// <summary> /// 新增一個任務到隊列當中 /// </summary> /// <param name="action"></param> public void AddAction(Action action) { this.Actions.Enqueue(action); //通知佇列馬上執行 _waitObj.Set(); } void run() { while (!_processExitHandler.ProcessExited) { try { _waitObj.WaitOne(); if (_waitObj == null) break; //執行佇列裡面的任務 if (this.Actions.TryDequeue(out Action o)) { o(); } } catch { } } _exited = true; } public void Dispose() { onProcessExit(); } }