升訊威在線客服系統的併發高性能數據處理技術:爲多線程處理同步數據

我在業餘時間開發維護了一款免費開源的升訊威在線客服系統,也收穫了許多用戶。對我來說,只要能獲得用戶的認可,就是我最大的動力。

最近客服系統成功經受住了客戶現場組織的壓力測試,獲得了客戶的認可。
客戶組織多名客服上線後,所有員工同一時間打開訪客頁面瘋狂不停的給在線客服發消息,系統穩定無異常無掉線,客服回覆消息正常。消息實時到達無任何延遲。

https://kf.shengxunwei.com/


我會通過一系列的文章詳細分析升訊威在線客服系統的併發高性能技術是如何實現的,使用了哪些方案以及具體的做法。本文將介紹如何爲多線程處理同步數據。

先看實現效果

客服端

訪客端

爲多線程處理同步數據

多個線程可以調用單個對象的屬性和方法時,對這些調用進行同步處理是非常重要的。 否則,一個線程可能會中斷另一個線程正在執行的任務,可能使該對象處於無效狀態。 其成員不受這類中斷影響的類叫做線程安全類。

  • .NET 提供了幾種策略,用於同步對實例和靜態成員的訪問:

  • 同步代碼區域。 可以使用 Monitor 類或此類的編譯器支持,僅同步需要它的代碼塊,從而提升性能。

  • 手動同步。 可以使用 .NET 類庫提供的同步對象。 請參閱同步基元概述,其中介紹了 Monitor 類。

  • 同步上下文。 僅對於 .NET Framework 和 Xamarin 應用程序,你可以使用 SynchronizationAttribute 爲 ContextBoundObject 對象啓用簡單的自動同步。

  • System.Collections.Concurrent 命名空間中的集合類。 這些類提供了內置的同步添加和刪除操作。 有關詳細信息,請參閱線程安全集合。

公共語言運行時提供一個線程模型,在該模型中,類分爲多種類別,這些類別可以根據要求以各種不同的方式進行同步。 下表顯示了爲具有給定同步類別的字段和方法提供的同步支持。

同步代碼區域

可以使用 Monitor 類或編譯器關鍵字,同步代碼塊、實例方法和靜態方法。 不支持同步靜態字段。

Visual Basic 和 C# 都支持使用特定語言關鍵字標記代碼塊,在 C# 中使用的是 lock 語句,在 Visual Basic 中使用的是 SyncLock 語句。 由線程執行代碼時,會嘗試獲取鎖。 如果該鎖已由其他線程獲取,則在鎖變爲可用狀態之前,該線程一直處於阻止狀態。 線程退出同步代碼塊時,鎖會被釋放,與線程的退出方式無關。

由於 lock 和 SyncLock 語句是使用 Monitor.Enter 和 Monitor.Exit 實現,因此 Monitor 的其他方法可以在同步區域內與它們結合使用。

還可以使用值爲 MethodImplOptions.Synchronized 的 MethodImplAttribute 修飾方法,其效果和使用 Monitor 或其中一個編譯器關鍵字鎖定整個方法正文相同。

Thread.Interrupt 可用於中斷對線程執行阻止操作(如等待訪問同步代碼區域)。 Thread.Interrupt 還用於中斷對線程執行 Thread.Sleep 等操作。

Visual Basic 和 C# 均支持使用 Monitor.Enter 和 Monitor.Exit 鎖定對象的語言關鍵字。

在這兩種情況下,如果代碼塊中引發異常,則 lock 或 SyncLock 獲取的鎖將自動釋放。 C# 和 Visual Basic 編譯器在發出 try/finally 塊時,在 try 的起始處使用 Monitor.Enter,在 finally 塊中使用 Monitor.Exit。 如果 lock 或 SyncLock 塊內部引發了異常,則會運行 finally 處理程序,從而允許執行任何清除工作。

WaitHandle 類和輕量同步類型

多個 .NET 同步基元派生自 System.Threading.WaitHandle 類,該類會封裝本機操作系統同步句柄並將信號機制用於線程交互。 這些類包括:

  • System.Threading.Mutex,授予對共享資源的獨佔訪問權限。 如果沒有任何線程擁有它,則 mutex 將處於已發出信號狀態。

  • System.Threading.Semaphore,限制可同時訪問某一共享資源或資源池的線程數。 當信號量計數大於零時,會將信號量的狀態設置爲已發出信號;當信號量計數爲零時,會將信號量的狀態設置爲未發出信號。

  • System.Threading.EventWaitHandle,表示線程同步事件,可以處於已發出信號狀態或未發出信號狀態。

  • System.Threading.AutoResetEvent,派生自 EventWaitHandle,當發出信號時,會在發佈單個等待線程後自動重置爲未發出信號狀態。

  • System.Threading.ManualResetEvent,派生自 EventWaitHandle,當發出信號時,會保持已發出信號狀態,直到調用 Reset 方法。

在 .NET Framework 中,由於 WaitHandle 派生自 System.MarshalByRefObject,因此,這些類型可用於跨應用程序域邊界同步線程的活動。

輕量同步類型不依賴於基礎操作系統句柄,通常會提供更好的性能。 但是,它們不能用於進程間同步。 將這些類型用於一個應用程序中的線程同步。

其中的一些類型是派生自 WaitHandle 的類型的替代項。 例如,SemaphoreSlim 是 Semaphore 的輕量替代項。

同步對共享資源的訪問

System.Threading.Monitor 類通過獲取或釋放用於標識資源的對象上的 lock 來授予對共享資源的相互獨佔訪問權限。 持有 lock 時,持有 lock 的線程可以再次獲取並釋放 lock。 阻止任何其他線程獲取 lock,Monitor.Enter 方法等待釋放 lock。 Enter 方法可獲取釋放的 lock。 還可以使用 Monitor.TryEnter 方法指定線程嘗試獲取 lock 的持續時間。 由於 Monitor 類具有線程關聯,因此獲取了 lock 的線程必須通過調用 Monitor.Exit 方法來釋放 lock。

可以通過使用 Monitor.Wait、Monitor.Pulse 和 Monitor.PulseAll 方法來協調用於獲取同一對象上的 lock 的線程的交互。

System.Threading.Mutex 類(與 Monitor 類似),授予對共享資源的獨佔訪問權限。 使用 Mutex.WaitOne 方法重載之一請求 mutex 的所有權。 Mutex(與 Monitor 類似)具有線程關聯,並且已獲取 mutex 的線程必須通過調用 Mutex.ReleaseMutex 方法來釋放它。

Mutex 類(與 Monitor 不同)可用於進程間同步。 爲此,請使用命名 mutex,它在整個操作系統中都可見。 若要創建命名 mutex 實例,請使用指定了名稱的 Mutex 構造函數。 還可以調用 Mutex.OpenExisting 方法來打開現有的命名系統 mutex。


簡介

升訊威在線客服與營銷系統是一款客服軟件,但更重要的是一款營銷利器。

https://kf.shengxunwei.com/

  • 可以追蹤正在訪問網站或使用 APP 的所有訪客,收集他們的瀏覽情況,使客服能夠主動出擊,施展話術,促進成單。
    訪* 客端在 PC 支持所有新老瀏覽器。包括不支持 WebSocket 的 IE8 也能正常使用。
  • 移動端支持所有手機瀏覽器、APP、各大平臺的公衆號對接。
  • 支持訪客信息互通,可傳輸訪客標識、名稱和其它任意信息到客服系統。
  • 具備一線專業技術水平,網絡中斷,拔掉網線,手機飛行模式,不丟消息。同類軟件可以按視頻方式對比測試。

希望能夠打造: 開放、開源、共享。努力打造 .net 社區的一款優秀開源產品。

鐘意的話請給個贊支持一下吧,謝謝~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章