今天就跟大家聊聊有關(guān).NET中的底層服務(wù)該怎么優(yōu)化,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結(jié)了以下內(nèi)容,希望大家根據(jù)這篇文章可以有所收獲。
創(chuàng)新互聯(lián)建站主要從事網(wǎng)站設(shè)計(jì)、做網(wǎng)站、網(wǎng)頁設(shè)計(jì)、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務(wù)。立足成都服務(wù)龍崗,十載網(wǎng)站建設(shè)經(jīng)驗(yàn),價格優(yōu)惠、服務(wù)專業(yè),歡迎來電咨詢建站服務(wù):13518219792
底層服務(wù)問題主要存在以下兩點(diǎn):
代碼冗余
時效低
例如:
領(lǐng)獎方法不統(tǒng)一,一次性的寫一套,可循環(huán)的又寫一套。
每個類型任務(wù)都需要獨(dú)自的實(shí)現(xiàn)該任務(wù)的完成任務(wù) JOB 與發(fā)放獎勵 JOB
以上問題直接導(dǎo)致了后續(xù)開發(fā)、日常維護(hù)成本過高。
因?yàn)樵缙陂_發(fā)時缺少溝通,沒有封裝成公共的方法,而JOB每個開發(fā)人員都單獨(dú)實(shí)現(xiàn)了一套,當(dāng)然他們未必那么蠢,可能是某個先完成了,后續(xù)的先前COPY后修改一下。
試想一下,沒新增一個任務(wù)類型就要重寫一份完成任務(wù)的JOB和自動發(fā)獎的JOB,這是一個N*2的工作量。如果后續(xù)有個規(guī)則改了,那是不是每個JOB都跑去改一次?
由于任務(wù)完成是由定時服務(wù)根據(jù)業(yè)務(wù)數(shù)據(jù)源定時批量執(zhí)行:
定時任務(wù)頻率低,則導(dǎo)致數(shù)據(jù)集中過多處理
定時任務(wù)頻率高,則導(dǎo)致 Job 對數(shù)據(jù)庫的壓力劇增或者 99%的無用查詢,無結(jié)果并不代表不會造成消耗,因?yàn)椴樵兌际且?jīng)過下面步驟,建立連接、詞法分析、語法分析、選取執(zhí)行方式、到存儲引擎讀取數(shù)據(jù)、返回客戶端。
隨著數(shù)據(jù)源數(shù)據(jù)量增加,查詢耗時也逐漸增加
以上問題直接導(dǎo)致了,用戶完成任務(wù)后無法及時查看完成任務(wù)并領(lǐng)獎,如需及時查看狀態(tài)需要在展示頁面邏輯額外添加查詢后更新的操作
目的:減少代碼冗余,提高可維護(hù)性,提高后續(xù)新任務(wù)的開發(fā)效率
具體實(shí)施:從業(yè)務(wù)流程圖可以直觀的觀察出,整個底層業(yè)務(wù)流程基本一致,只有數(shù)據(jù)源上的差異,因此可以從以下方面入手優(yōu)化:
抽離出唯一的自動發(fā)獎 Job,發(fā)獎JOB基于【任務(wù)完成結(jié)果】進(jìn)行發(fā)獎,逐步去除原個性任務(wù)自動發(fā)獎 Job。
自動發(fā)獎與手動領(lǐng)獎的具體執(zhí)行流程一致的,可將其封裝成公共方法。分別由H5領(lǐng)獎按鈕與領(lǐng)獎JOB進(jìn)行調(diào)用。
任務(wù)完成 Job 使用模板模式,由基類統(tǒng)一業(yè)務(wù)執(zhí)行流程,每個任務(wù)類型只需繼承任務(wù)父類,再由子類重寫查詢數(shù)據(jù)源。當(dāng)然也可以簡單粗暴點(diǎn)不使用設(shè)計(jì)模式,把查詢數(shù)據(jù)源后的完成任務(wù)的方法封裝成一個公共方法供不同任務(wù)類型的JOB去調(diào)用。
從我角度來看,這種方案處理沒有任何壞處的。如果真要計(jì)較,那就是所涉及的JOB都得改,但是從上述分析出,如果真要重構(gòu),工作量也是在寫父類模板和封裝公共方法,查詢數(shù)據(jù)源代碼是可以復(fù)用的。但是帶來的收益就是良好的擴(kuò)展性和可維護(hù)性。
該方案主要對任務(wù)參與的觸發(fā)方式變更,不同的任務(wù)類型由對應(yīng)的業(yè)務(wù)最終流程的完成點(diǎn)進(jìn)行發(fā)送隊(duì)列消息,由任務(wù)服務(wù)(消費(fèi)端)訂閱相關(guān)消息執(zhí)行任務(wù)完成流程。
通俗講叫業(yè)務(wù)埋點(diǎn),當(dāng)然也可以稱其為事件驅(qū)動。
服務(wù)之間是高內(nèi)聚的,它們的耦合度應(yīng)該很低,當(dāng)服務(wù)需要相互協(xié)作時,假設(shè)服務(wù)“A”需要觸發(fā)服務(wù)“B”中的某段邏輯,平常的方式是讓服務(wù)A直接串行調(diào)用服務(wù)B中的某個方法。但前提是A必須知道B的存在,如果B出異常了就會影響到A的正常執(zhí)行。
這樣它們之間就是強(qiáng)耦合的,A必須依賴于B了。這樣使得系統(tǒng)更難以維護(hù)與擴(kuò)展,因此引入事件驅(qū)動來降低服務(wù)間的耦合度。
當(dāng)服務(wù)A需要觸發(fā)服務(wù)B的邏輯時,不要直接調(diào)用它,我們可以將消息發(fā)送到消息隊(duì)列,由服務(wù)B訂閱相應(yīng)的隊(duì)列,并在事件發(fā)生時異步執(zhí)行操作。這意味著服務(wù)A、B都依賴于中間件消息隊(duì)列,但他們之間將不需要知道彼此的存在,因此它們之間于此解耦。
如果將此方案引入我們的活動業(yè)務(wù)中,收益主要分為短期與長期。
減少無用重復(fù)的查詢:無需重復(fù)查詢數(shù)據(jù)源,只需由業(yè)務(wù)端推送可靠的消息,減少對數(shù)據(jù)庫的多余壓力
用戶體驗(yàn)良好:時效性高,原集中時間點(diǎn)批量處理,現(xiàn)分散到不同的時間點(diǎn)執(zhí)行
伸縮性優(yōu)秀:RabbitMQ 自帶負(fù)載均衡功能,在消費(fèi)能力不足情況下,可以做到業(yè)務(wù)無損的動態(tài)橫向擴(kuò)展。雖然JOB也可以做到,但是需要對物理表做特殊處理,增加中間狀態(tài)
事件驅(qū)動架構(gòu)長期收益比短期要大,以RabbitMQ與投資業(yè)務(wù)舉個例子。初期完成核心業(yè)務(wù)投資理財,投資后我們需要APP通知用戶,在此投資無論成功與否都往RabbitMQ發(fā)送消息,投資成功RouteKey=TZ.SUCCESS,投資失敗RouteKey=TZ.FAILE。APP通知服務(wù)訂閱隊(duì)列NoticeQueue綁定RouteKey=TZ.#,其中包括成功和失敗的消息,服務(wù)根據(jù)消息狀態(tài)發(fā)送APP通知。哪天業(yè)務(wù)拓展需要增加投資成功積分,只需要添加積分服務(wù)訂閱隊(duì)列IntegrationQueue并綁定RouteKey=TZ.SUCCESS消息即可。接著又多了任務(wù)活動、信用消費(fèi)等,如此類推。
由此可見,如同廣播一樣,我不知道你們誰要,如果你們需要的就好好監(jiān)聽著,不需要就當(dāng)耳旁風(fēng)。
既然我們使用了RabbitMQ中間件,那么分布式事務(wù)會選擇基于可靠消息的方案:
消息可靠性:保證業(yè)務(wù)端的本地事務(wù)執(zhí)行成功的同時也保證隊(duì)列消息正常發(fā)布
消息補(bǔ)償:保證消息消費(fèi)端的正常消費(fèi),如果消費(fèi)失敗后需重新投遞,如果重新投遞失敗可由補(bǔ)償服務(wù)補(bǔ)償發(fā)送。
冪等處理:因存在自動重試機(jī)制,避免重復(fù)執(zhí)行業(yè)務(wù)導(dǎo)致的意外問題。
這種基于可靠消息的方案,也叫本地消息事務(wù)表的方案,可根據(jù)自己情況自研解決,也可使用類似開源分布式事務(wù)框架 CAP 解決。
看完上述內(nèi)容,你們對.NET中的底層服務(wù)該怎么優(yōu)化有進(jìn)一步的了解嗎?如果還想了解更多知識或者相關(guān)內(nèi)容,請關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝大家的支持。