快速響應請求淺談

排着前不見頭後不見尾的隊,心裏是崩潰的,又進退兩難,是一種等待。
叫號,玩手機等,是一種等待。
一句我等你,而後遙遙無期,是一種等待。
此爲信物,待我長髮及腰...,是一種等待。前端

關於響應

發起請求,接收到反饋即算響應。響應的內容是想要的結果,或僅是一句安慰,在合適的場景下合適的呈現都能有好的體驗,響應顧及這種反饋體驗,出發點就對了。數據庫

快速響應方式

不一樣的應用場景,決定快速響應的方式。c#

(1)發起型,只關心提交的數據是否到達。緩存

發起型只關心提交是否成功,不關心後續處理過程,此時,應在接收數據成功後當即反饋成功,處理過程交給其它異步線程或進程處理。框架

(2)實時結果型,等着出結果。異步

提交請求數據後,若是處理時間較短(如3秒之內),則可處理完成以後反饋結果。不然,可先反饋數據接收成功,提示處理中,而後異步標記處理狀態供前端查詢或是通知前端進度,此時前端已經收到反饋,而後以一種非阻塞的方式呈現處理進度。性能

前端也能夠是收到反饋以後,直接引導用戶進入下一步,進入下一步後,若是已經處理完了則皆大歡喜,未處理完,仍然能夠經過狀態信息,給用戶反饋當前處理狀況。pwa

(3)信息查詢型線程

信息查詢,一般能夠先加載頁面,再異步加載查詢結果。而數據部分,能夠經過使用緩存減小數據庫查詢,當緩存中存在相關信息時,直接使用緩存中的數據返回。緩存須要適當的刷新策略,簡單方式,如無緩存則查詢數據庫,有則檢測是否超過刷新時間決定是否刷新。一般可使用成熟的緩存框架。code

快速響應方法

基本原則:儘早反饋

基本方法:先返回,異步處理,再通知

(1)線程化

接收到請求數據後,處理過程以線程方式進行,請求直接返回。以下 c# 代碼,假設處理過程耗時 3 秒,則使用如下方式,耗時接近 0 秒。

Stopwatch sw = new Stopwatch();
sw.Start(); -- 計時開始

var thread = new Thread(new ThreadStart(() => {
    // 處理過程
    Thread.Sleep(3000);
}));

thread.Start();            

--  顯示耗時
return sw.ElapsedMilliseconds.ToString();

這種方式的主要問題在於,當處理時長偏長而請求數較多時,線程數據會急劇增長可能耗盡全部資源,而使得應用不可用。

(2)線程池

使用線程池能下降反覆建立銷燬線程的損耗,並對資源的使用加以控制!在 C# 中,咱們能夠經過如下線程池的方法達到線程化的效果。

ThreadPool.QueueUserWorkItem((state) => {
    // 處理過程
    Thread.Sleep(3000);
    Debug.Write("處理完畢!");
});

(3)隊列化

任務請求不均衡,高峯期特別集中,而應用處理能力有限,此時能夠創建一種排隊機制,來的任務加入隊列,不緊不慢的去執行,能夠充分發揮機器性能又不至於超過其處理能力。任務的執行主體簡要形式如如下 C# 示例。

/// <summary>
/// 任務執行線程主體
/// </summary>
private void TaskRunning()
{
    while (_Working)
    {
        QueueTask<T> task = null;
        lock (_RunLocker)   
        {
            if (_TaskRunQueue.Count > 0)
            {
                task = _TaskRunQueue.Dequeue();  
            }
        }
        // 還存在任務執行其任務過程
        if (task != null)
        {
            task.Callback(task.ObjectKey, task.Context);
        }
        else
        {
            // 等待新任務通知
            _WaitHandle.WaitOne();
        }
    }
}

(4)中間件

使用中間件,能有效進行應用間的解藕,並使得應用極具擴展性與伸縮性,相關數據丟給中間件,中間件負責分發任務給相關工做進程,並管理好其狀態。如 RabbitMQ,經過它能夠在不一樣應用進程中進行通訊與任務管理。

任務處理方式

(1)發佈訂閱方式

肯定一個主題,須要該主題相關的數據的應用訂閱該主題便可,當數據方發佈該主題時,訂閱方會收到相應的消息而後觸發業務處理。當同一數據(消息)多方應用依據其進行處理時,發佈訂閱方式很是合適。

(2)生產者消費者方式

當不少耗時任務到達時,能夠開啓多個工做進程來並行處理這些任務。發起任務方是生產者,工做進程就是消費者,生產一個,空閒工做進程立刻接手一個(即消費一個)。仍然處理不過來了,能夠繼續增長工做進程。

容錯處理

容錯處理主要針對任務執行失敗的情形,如何確保任務必定有結果的執行。其一,須要確保在任務派發後,其工做進程執行失敗時,能自動從新委派給其它工做進程。其二,當分配者自身中斷後能恢復任務隊列。實現這些,須要有相應的處理機制,如任務執行結果 ACK 通知、持久化消息等。而這些,都有較爲成熟的解決方案,如 RabbitMQ 等。

相關文章
相關標籤/搜索