.NET-記一次架構優化實戰與方案-底層服務優化 .NET-記一次架構優化實戰與方案-梳理篇 .NET-記一次架構優化實戰與方案-前端優化 .NET-記一次架構優化實戰與方案-底層服務優化 .NET-

目錄

  1. .NET-記一次架構優化實戰與方案-梳理篇

  2. .NET-記一次架構優化實戰與方案-前端優化

  3. .NET-記一次架構優化實戰與方案-底層服務優化

前言

  通過上一篇《.NET-記一次架構優化實戰與方案-前端優化》與你們分享了對頁面加載優化的心得和經歷。雖然優化前端的性能效率,可是因爲底層服務的觸發方式,根本性問題仍然存在的。html

問題分析

  在本系列第一篇文章咱們提到,底層服務是一系列的JOB,那麼問題主要存在如下兩點:前端

  • 代碼冗餘
  • 時效低

代碼冗餘

例如:git

  • 領獎方法不統一,一次性的寫一套,可循環的又寫一套。
  
    •  
  • 每一個類型任務都須要獨自的實現該任務的完成任務 JOB 與發放獎勵 JOB

  

  以上問題直接致使了後續開發、平常維護成本太高。github

  由於早期開發時缺乏溝通,沒有封裝成公共的方法,而JOB每一個開發人員都單獨實現了一套,固然他們未必那麼蠢,多是某個先完成了,後續的先前COPY後修改一下。數據庫

  試想一下,沒新增一個任務類型就要重寫一份完成任務的JOB和自動發獎的JOB,這是一個N*2的工做量。若是後續有個規則改了,那是否是每一個JOB都跑去改一次?設計模式

時效低

  因爲任務完成是由定時服務根據業務數據源定時批量執行:架構

  1. 定時任務頻率低,則致使數據集中過多處理
  2. 定時任務頻率高,則致使 Job 對數據庫的壓力劇增或者 99%的無用查詢,無結果並不表明不會形成消耗,由於查詢都是要通過下面步驟,創建鏈接、詞法分析、語法分析、選取執行方式、到存儲引擎讀取數據、返回客戶端。
  3. 隨着數據源數據量增長,查詢耗時也逐漸增長

  以上問題直接致使了,用戶完成任務後沒法及時查看完成任務並領獎,如需及時查看狀態須要在展現頁面邏輯額外添加查詢後更新的操做負載均衡

優化實施

流程圖

方案一(抽離公共點)

目的:減小代碼冗餘,提升可維護性,提升後續新任務的開發效率框架

具體實施:從業務流程圖能夠直觀的觀察出,整個底層業務流程基本一致,只有數據源上的差別,所以能夠從如下方面入手優化:前端優化

  1. 抽離出惟一的自動發獎 Job,發獎JOB基於【任務完成結果】進行發獎,逐步去除原個性任務自動發獎 Job。
  2. 自動發獎與手動領獎的具體執行流程一致的,可將其封裝成公共方法。分別由H5領獎按鈕與領獎JOB進行調用。
  3. 任務完成 Job 使用模板模式,由基類統一業務執行流程,每一個任務類型只需繼承任務父類,再由子類重寫查詢數據源。固然也能夠簡單粗暴點不使用設計模式,把查詢數據源後的完成任務的方法封裝成一個公共方法供不一樣任務類型的JOB去調用。

從我角度來看,這種方案處理沒有任何壞處的。若是真要計較,那就是所涉及的JOB都得改,可是從上述分析出,若是真要重構,工做量也是在寫父類模板和封裝公共方法,查詢數據源代碼是能夠複用的。可是帶來的收益就是良好的擴展性和可維護性。

方案二(業務埋點)

該方案主要對任務參與的觸發方式變動,不一樣的任務類型由對應的業務最終流程的完成點進行發送隊列消息,由任務服務(消費端)訂閱相關消息執行任務完成流程。

通俗講叫業務埋點,固然也能夠稱其爲事件驅動。

架構圖

事件驅動架構

  服務之間是高內聚的,它們的耦合度應該很低,當服務須要相互協做時,假設服務「A」須要觸發服務「B」中的某段邏輯,日常的方式是讓服務A直接串行調用服務B中的某個方法。但前提是A必須知道B的存在,若是B出異常了就會影響到A的正常執行。

這樣它們之間就是強耦合的,A必須依賴於B了。這樣使得系統更難以維護與擴展,所以引入事件驅動來下降服務間的耦合度

  當服務A須要觸發服務B的邏輯時,不要直接調用它,咱們能夠將消息發送到消息隊列,由服務B訂閱相應的隊列,並在事件發生時異步執行操做。這意味着服務A、B都依賴於中間件消息隊列,但他們之間將不須要知道彼此的存在,所以它們之間於此解耦。

若是將此方案引入咱們的活動業務中,收益主要分爲短時間與長期。

短時間收入

  1.  減小無用重複的查詢:無需重複查詢數據源,只需由業務端推送可靠的消息,減小對數據庫的多餘壓力
  2. 用戶體驗良好:時效性高,原集中時間點批量處理,現分散到不一樣的時間點執行
  3. 伸縮性優秀:RabbitMQ 自帶負載均衡功能,在消費能力不足狀況下,能夠作到業務無損的動態橫向擴展。雖然JOB也能夠作到,可是須要對物理表作特殊處理,增長中間狀態

長期收益

  事件驅動架構長期收益比短時間要大,以RabbitMQ與投資業務舉個例子。初期完成核心業務投資理財,投資後咱們須要APP通知用戶,在此投資不管成功與否都往RabbitMQ發送消息,投資成功RouteKey=TZ.SUCCESS,投資失敗RouteKey=TZ.FAILE。APP通知服務訂閱隊列NoticeQueue綁定RouteKey=TZ.#,其中包括成功和失敗的消息,服務根據消息狀態發送APP通知。哪天業務拓展須要增長投資成功積分,只須要添加積分服務訂閱隊列IntegrationQueue並綁定RouteKey=TZ.SUCCESS消息便可。接着又多了任務活動、信用消費等,如此類推。

  因而可知,如同廣播同樣,我不知道大家誰要,若是大家須要的就好好監聽着,不須要就當耳旁風。

複雜點

分佈式事務

  既然咱們使用了RabbitMQ中間件,那麼分佈式事務會選擇基於可靠消息的方案:

  1. 消息可靠性:保證業務端的本地事務執行成功的同時也保證隊列消息正常發佈
  2. 消息補償:保證消息消費端的正常消費,若是消費失敗後需從新投遞,若是從新投遞失敗可由補償服務補償發送。
  3. 冪等處理:因存在自動重試機制,避免重複執行業務致使的意外問題。

模型圖

  

  這種基於可靠消息的方案,也叫本地消息事務表的方案,可根據本身狀況自研解決,也可以使用相似開源分佈式事務框架 CAP 解決。https://github.com/dotnetcore/CAP

結束

  本系列到此基本上分享完了,若是你們有更加好的意見,可在下方評論反饋給我。

相關文章
相關標籤/搜索