最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

從零開始搭建一個通用的業(yè)務技術架構(gòu),這套架構(gòu)絕了!

2023-03-17 11:46 作者:要寵你上天  | 我要投稿

1、通用架構(gòu)概述

創(chuàng)業(yè)之初,我們往往會為了快速迭代出產(chǎn)品,而選擇最簡單的技術架構(gòu),比如LAMP架構(gòu),SSH三層架構(gòu)。這些架構(gòu)可以適應初期業(yè)務的快速發(fā)展,但是,隨著業(yè)務變得越來越復雜,我們會發(fā)現(xiàn)這些架構(gòu)越來越難支撐業(yè)務的發(fā)展,出現(xiàn)在一個類中寫好幾千行代碼,一個方法中到處都是if else語句,如果中間遇到主程序猿離職,后面介入的程序猿幾乎無法理解這些代碼,到最后,產(chǎn)品越來越難迭代,只能推翻重做。如果我們在創(chuàng)業(yè)初始就以一種適應性較強的架構(gòu)去寫代碼,后面就會少走很多彎路。下面的文章是我自己總結(jié)出來的一套架構(gòu),經(jīng)過實踐,適應性還算不錯。


2、通用架構(gòu)實現(xiàn)

總的來說我的通用架構(gòu)還是以三層架構(gòu)為基礎進行演變的,在經(jīng)典的三層架構(gòu)中,最上層的是controller,中間是service,下層是dao。在我的架構(gòu)中,最上層是網(wǎng)關層,controller只是網(wǎng)關的一種,中間是業(yè)務層,service只是業(yè)務層的入口,最下層是基礎層,dao只是基礎層中的數(shù)據(jù)存儲組件。


2.1、網(wǎng)關層

網(wǎng)關層本質(zhì)上是對不同的網(wǎng)絡協(xié)議的請求進行處理,比如HTTP協(xié)議,TCP協(xié)議,當然,也可以對其他協(xié)議進行處理。具體見下圖:

2.1.1、HTTP請求

一般來自PC端和APP端的請求都是基于HTTP協(xié)議的,對于處理HTTP請求的方案,業(yè)內(nèi)已經(jīng)非常成熟了。首先,tomcat容器本身已經(jīng)把HTTP請求處理的復雜性封裝掉了,其次,spring mvc對請求處理提供了RESTful風格的編碼方式,大大降低了開發(fā)的復雜度。我們要做的就是對controller按照業(yè)務領域劃分,比如按照訂單、會員去劃分大的領域,里面的各種方法就是這個領域內(nèi)的操作。這里的controller就是統(tǒng)一網(wǎng)關處理層,對于每個controller的方法只做三件事,第一,將請求參數(shù)解析出來并組裝成內(nèi)部參數(shù),第二調(diào)用下層服務執(zhí)行業(yè)務邏輯,第三組裝返回結(jié)果,對于異常情況,需要記錄異常堆棧日志并轉(zhuǎn)換錯誤碼,堆棧信息不要暴露到調(diào)用方。


2.1.2、TCP請求

對于處理TCP請求的方案,業(yè)內(nèi)也已經(jīng)很成熟了,比如Netty。但是,TCP請求畢竟太底層,我們往往會基于TCP協(xié)議去開發(fā)自己的協(xié)議。另外,很多分布式框架都是基于TCP協(xié)議的,比如RPC框架Dubbo,消息框架RocketMQ等等。從單機系統(tǒng)到分布式系統(tǒng),無非就是網(wǎng)關層多了處理TCP請求的邏輯,理論上底層的業(yè)務是無需感知自己到底是出于單機環(huán)境還是分布式環(huán)境,網(wǎng)關層的作用就是要屏蔽這種不同外部調(diào)用源的細節(jié)。在Dubbo服務端中,我們需要實現(xiàn)遠程接口,并對遠程服務調(diào)用進行內(nèi)部的轉(zhuǎn)發(fā),轉(zhuǎn)發(fā)的邏輯也很簡單,首先是解析參數(shù)并組裝內(nèi)部參數(shù),然后調(diào)用業(yè)務層的接口執(zhí)行業(yè)務邏輯,最后組裝返回結(jié)果,對于異常處理也需要在這里做掉,防止異常暴露給外部應用。


2.1.3、小結(jié)

網(wǎng)關層本質(zhì)是對協(xié)議進行處理,同時將業(yè)務邏輯收斂到網(wǎng)關層,而不是暴露給外部,當內(nèi)部業(yè)務邏輯進行重構(gòu)的時候,外部調(diào)用方就不需要感知這些變化,當外部調(diào)用源增加時,內(nèi)部業(yè)務邏輯不需要感知這種變化,從而將外部調(diào)用方和內(nèi)部業(yè)務邏輯進行了解耦。


2.2、業(yè)務層

業(yè)務層是一個系統(tǒng),無論是單機系統(tǒng)還是分布式系統(tǒng)群中的某個業(yè)務系統(tǒng),業(yè)務層都是承載業(yè)務流程和規(guī)則的地方。業(yè)務層從外到內(nèi)包含三層:第一層是業(yè)務服務,第二層是業(yè)務流程,第三層是業(yè)務組件。具體如下圖:


2.2.1、業(yè)務服務


業(yè)務服務是業(yè)務層對外的統(tǒng)一門面,它由三方面組成:業(yè)務接口、入?yún)?、出參?/p>

a) 業(yè)務接口

一個業(yè)務接口代表一個領域的業(yè)務服務,比如訂單域的業(yè)務服務就由接口OrderService表示,會員域的業(yè)務服務就由接口MemberService表示。接口可以按照執(zhí)行性質(zhì)分為讀接口和寫接口,比如OrderReadService和OrderWriteService。讀寫分離的好處是可以對集群進行讀寫分組,從而管理流量,當然,單機系統(tǒng)讀寫分離意義不是太大。領域內(nèi)的操作則以業(yè)務接口中的方法的形式體現(xiàn),比如訂單域有下單createOrder,取消訂單cancelOrder等等操作。對于這些操作,盡量設計出有業(yè)務含義的方法,而不是增刪改查,當然,對于一些簡單的業(yè)務,也只能增刪改查。

b)入?yún)?/strong>

接下來,是入?yún)⒌脑O計。入?yún)τ谧x方法,比較簡單,不做討論。對于寫方法,我們將入?yún)⒃O計成有層次的數(shù)據(jù)模型。首先需要設計出公共的數(shù)據(jù)模型,比如訂單數(shù)據(jù)模型,商家數(shù)據(jù)模型,商品數(shù)據(jù)模型等,然后將這些數(shù)據(jù)模型和一些特定業(yè)務下的個性數(shù)據(jù)結(jié)合,組成Request對象,這個request對象按照不同業(yè)務操作不同而不同,對應的返回結(jié)果就是response,它也是隨著不同業(yè)務返回的參數(shù)不同。

舉個例子,拿下餐飲訂單來說,首先,我們應該識別出這些業(yè)務流程中一些比較基礎的數(shù)據(jù)模型,比如餐飲領域的菜品、桌位等,這些模型之所以說是基礎模型,是因為,不管下什么餐飲訂單,菜品和桌位肯定是逃不了的,它們是可以被復用的!因此,我們分別為這些基礎模型設計相對于的DO(Domian Object):DishDO(菜品)、BoardDO(桌位)等等,接下來,我們?yōu)橄虏惋嬘唵卧O計一個請求對象DishOrderCreateRequest其中DishOrderCreateRequest內(nèi)部包含了DishDO和BoardDO,另外會包含一些特定的屬性,比如人數(shù)啊,折扣啊等等,這樣一來就能做到通用和靈活兼顧,DishOrderCreateRequest代表的個性化的靈活的業(yè)務入?yún)ⅲ鳧ishDO和BoardDO等則代表了不易變化的基礎模型。

c) 出參

最后,是出參的設計。對于寫方法,一般出參比較簡單。對于讀方法,出參往往是一個結(jié)構(gòu)與層次比較復雜的組合對象。比如查詢一個訂單,這個訂單有訂單基本信息,還有商品信息,收貨人地址信息等。在設計出參的時候,結(jié)構(gòu)上要設計成組合對象,但是真正查詢的時候,通過查詢選擇器,去查詢不同的組合對象。比如查詢選擇器設置商品查詢?yōu)閠rue,地址查詢?yōu)閒alse,那么這次查詢出的訂單就只包含商品,而不包含地址。


2.2.2、業(yè)務流程


業(yè)務流程其實就是對業(yè)務規(guī)則的解釋,只是這種解釋使用代碼去實現(xiàn)的,我們要做的其實就是準確翻譯這些業(yè)務規(guī)則,并維護好這些業(yè)務規(guī)則。

業(yè)務流程中可以大致分為三種動作節(jié)點,1、組裝參數(shù)節(jié)點 2、規(guī)則判斷節(jié)點 3、執(zhí)行動作節(jié)點,其中每個動作節(jié)點都是一些業(yè)務代碼的片段。舉個例子,下餐飲訂單,我們第一步就是將上層傳入的參數(shù)組裝出一個基礎的DishOrderDO(組裝參數(shù)節(jié)點),然后按照特定的規(guī)則去填充這個DishOrderDO(規(guī)則判斷節(jié)點),然后就是調(diào)用DAO去創(chuàng)建DishOrderDO(執(zhí)行動作節(jié)點)。

業(yè)務流程是最容易變化的地方,要想維護好業(yè)務流程并不容易,總的思想是將大的業(yè)務流程拆分成小的業(yè)務流程,抽出每個業(yè)務流程中共有的代碼片段,變成可維護的業(yè)務組件。

2.2.2、業(yè)務組件

a) 基礎組件

業(yè)務組件其實是將一些內(nèi)聚的可復用的代碼片段進行封裝。和業(yè)務流程中的三種業(yè)務節(jié)點相對應,業(yè)務組件也分為三種:組裝參數(shù)組件 、規(guī)則判斷組件 、動作執(zhí)行業(yè)務組件。業(yè)務組件的抽象往往是對業(yè)務有了深刻理解之后才進行的,盲目地進行業(yè)務組件的抽象,往往到頭來白忙活。

b) 能力

對業(yè)務組件進行進一步抽象,可以得到能力。業(yè)務能力是具有一定復用性的組件的組合,比如發(fā)短信能力=組裝短信參數(shù)組件+發(fā)短信組件。對于發(fā)短信能力,可以被不同的業(yè)務流程復用,比如訂單下單成功發(fā)短信,支付成功發(fā)短信,邏輯都是相似的,只有內(nèi)容不同。能力是一種粒度比較大的組件,粒度越大,往往復用性就越小,對能力的抽取,也是基于對特定業(yè)務深刻的理解,沒有一勞永逸的銀彈。

c)更高緯度的抽象

經(jīng)過本人的實踐,對于互聯(lián)網(wǎng)這樣的需求變化極快的場景,更高緯度的組件抽象往往性價比很低,不建議大家去做。


2.3、基礎層

基礎層包含兩個部分,第一是接口定義,第二是技術組件。

2.3.1、接口定義

接口定義是按照不同的技術框架,同時結(jié)合業(yè)務需要,設計出合理的接口,對于業(yè)務組件來說,它們只會感知技術接口,而不會去感知技術實現(xiàn),我們也不應該將具體的技術細節(jié)向上暴露,這也就是所謂的面向接口編程。技術接口往往是業(yè)務與技術之間的橋梁,接口本身是含有業(yè)務含義的,最常見的就是DAO接口,我們設計DAO接口的時候,不會設計成insert、update、query這樣業(yè)務無關的接口,而是設計成insertUser,updateUserById等等和業(yè)務相關的接口,同樣的道理,設計緩存接口的時候,也不能設計成put、get這樣的接口,而應該設計成cacheUser,deprecateUser這樣的接口。

2.3.2、技術組件

單機系統(tǒng)的技術組件一般來說分兩種,一種是通用的技術組件,比如:數(shù)據(jù)存儲、緩存、消息和調(diào)度任務、事務、鎖。一種是基礎設施,比如spring容器,tomcat容器。下面稍微談談通用技術組件。

數(shù)據(jù)存儲:數(shù)據(jù)存儲包括關系型數(shù)據(jù)庫、非關系型數(shù)據(jù)庫以及文件存儲系統(tǒng)。關系型數(shù)據(jù)庫,比如MySQL,適合存放絕大部分業(yè)務數(shù)據(jù)。非關系型數(shù)據(jù)庫,比如hbase,可以存放歷史日志,也可以對歷史的MySQL數(shù)據(jù)進行歸檔。文件存儲系統(tǒng),一般都是基于Linux文件系統(tǒng),比如圖片、html文件等等,也有基于HDFS的,用于大數(shù)據(jù)分析。

緩存:緩存按響應時間分,可以分為納秒級緩存,毫秒級緩存和百毫秒級緩存。納秒級緩存就是一般的基于本地內(nèi)存的緩存,比如encache,毫秒級緩存一般是集中式的內(nèi)存緩存,比如memcache,由于訪問時遠程調(diào)用,因此響應時間會延長到幾毫秒,百毫秒級緩存一般是集中式可持久化的緩存,比如redis,由于存在遠程訪問以及緩存擊穿導致的讀取持久化記錄,它的響應時間會更長些,到幾十甚至上百毫秒。單機系統(tǒng)一般用本地內(nèi)存緩存就夠了,當緩存被擊穿的時候,直接訪問數(shù)據(jù)庫。

消息和調(diào)度任務:消息和調(diào)度任務本質(zhì)都是一種異步化的手段,區(qū)別在于消息無法控制異步的時間,而調(diào)度任務可以。一般,消息發(fā)送出去后,監(jiān)聽消息的系統(tǒng)會立即收到消息,從而立即觸發(fā)業(yè)務邏輯的執(zhí)行,而調(diào)度任務則會按照調(diào)度規(guī)則,一次或者多次的執(zhí)行業(yè)務邏輯。單機系統(tǒng)中消息和調(diào)度任務用到的比較少,在做日志監(jiān)控的時候可能會用到消息,在進行數(shù)據(jù)報表統(tǒng)計的時候可能會用到調(diào)度任務。

事務:事務本質(zhì)都是基于數(shù)據(jù)庫去實現(xiàn)的,單機系統(tǒng)的事務就是依賴數(shù)據(jù)庫的事務,我們可以使用spring-tx的事務模板進行事務操作,在業(yè)務邏輯開發(fā)中,一定要把握事務的大小,建議把業(yè)務比較緊密的一堆數(shù)據(jù)庫操作放在一個事務里,不要隨意的為每個方法都開啟事務。

鎖:單機系統(tǒng)中主要用到兩種鎖:樂觀鎖和悲觀鎖。樂觀鎖依靠在數(shù)據(jù)庫的業(yè)務表加版本字段來實現(xiàn),每次更新都會去判斷版本是否變化,如果變化則需要重試,這種鎖的粒度比較小。悲觀鎖是基于JDK的Lock接口的,對一個業(yè)務流程進行加鎖和釋放鎖的操作,鎖的粒度比較粗。



從零開始搭建一個通用的業(yè)務技術架構(gòu),這套架構(gòu)絕了!的評論 (共 條)

分享到微博請遵守國家法律
永安市| 马龙县| 明溪县| 措勤县| 定远县| 滦平县| 阿坝县| 塘沽区| 油尖旺区| 错那县| 溧阳市| 五原县| 澄迈县| 石门县| 阿拉善左旗| 黑龙江省| 南木林县| 大同县| 忻城县| 松滋市| 嘉定区| 泰宁县| 龙口市| 荥阳市| 女性| 平陆县| 五台县| 遵义县| 当雄县| 台北市| 新龙县| 东海县| 禄劝| 宣城市| 恭城| 舞钢市| 广饶县| 清镇市| 玉屏| 庆元县| 兰考县|