成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Netflix 的六邊形架構(gòu)實(shí)踐

新聞 架構(gòu)
隨著 Netflix 原創(chuàng)內(nèi)容的逐年增長(zhǎng),我們要構(gòu)建一些可提升整個(gè)創(chuàng)作過程效率的應(yīng)用。我們的一個(gè)大型部門,Studio 工程團(tuán)隊(duì)已經(jīng)構(gòu)建眾多應(yīng)用,去幫助從劇本制作到內(nèi)容播出的全套流程,涉及的環(huán)節(jié)涵蓋劇本內(nèi)容獲取、交易談判和供應(yīng)商管理,以及日程安排、簡(jiǎn)化生產(chǎn)流程等。

 本文闡述了Netflix是如何基于六邊形架構(gòu)去開發(fā)一款全新應(yīng)用的。

隨著 Netflix 原創(chuàng)內(nèi)容的逐年增長(zhǎng),我們要構(gòu)建一些可提升整個(gè)創(chuàng)作過程效率的應(yīng)用。我們的一個(gè)大型部門,Studio 工程團(tuán)隊(duì)已經(jīng)構(gòu)建眾多應(yīng)用,去幫助從劇本制作到內(nèi)容播出的全套流程,涉及的環(huán)節(jié)涵蓋劇本內(nèi)容獲取、交易談判和供應(yīng)商管理,以及日程安排、簡(jiǎn)化生產(chǎn)流程等。

1. 從開始就高度集成

大約一年前,我們的 Studio 流程團(tuán)隊(duì)開始開發(fā)一款跨多個(gè)業(yè)務(wù)領(lǐng)域的全新應(yīng)用。

當(dāng)時(shí),我們面臨一項(xiàng)有意思的挑戰(zhàn):

一方面我們需要從頭開始構(gòu)建應(yīng)用的核心,另一方面我們所需的數(shù)據(jù)分布在眾多不同的系統(tǒng)之中。

我們所需要的一些數(shù)據(jù),比如有關(guān)影片信息、制作日期、員工和拍攝地點(diǎn)的數(shù)據(jù),分布于許多服務(wù)中。并且,它們使用的協(xié)議也各有不同,包括 gRPC、JSON API、GraphQL 等等。

對(duì)我們應(yīng)用程序的行為和業(yè)務(wù)邏輯而言,已有數(shù)據(jù)非常重要。我們從一開始就需要高度集成。

2. 可切換數(shù)據(jù)源

早期的一款應(yīng)用程序用來(lái)為我們的產(chǎn)品引入可見性,它被設(shè)計(jì)為單體架構(gòu)。在領(lǐng)域知識(shí)體系尚未建立的情況下,單體架構(gòu)可以實(shí)現(xiàn)快速開發(fā)和快速變更。后來(lái),使用它的開發(fā)人員超過 30 人,有超過 300 個(gè)數(shù)據(jù)庫(kù)表。

隨著時(shí)間流逝,應(yīng)用程序從涉及面廣泛的服務(wù)演變成高度專業(yè)化的產(chǎn)品。在這樣的背景下,團(tuán)隊(duì)決定將單體架構(gòu)解構(gòu)為一系列專用服務(wù)。

做出這一決策并非性能問題,而是要對(duì)所有這些領(lǐng)域設(shè)置界限,并讓各個(gè)專屬團(tuán)隊(duì)能獨(dú)立開發(fā)針對(duì)每個(gè)特定領(lǐng)域的服務(wù)。

我們的新應(yīng)用所需的大量數(shù)據(jù)依舊是之前的單體提供的,但我們知道這個(gè)單體將在某一天分解開來(lái)。我們不能確定具體時(shí)間,但知道這一時(shí)刻不可避免,所以需要做好準(zhǔn)備。

這樣的話,我們能在一開始利用某些來(lái)自單體的數(shù)據(jù),因?yàn)樗鼈內(nèi)匀皇强尚艁?lái)源;但我們也要做好準(zhǔn)備,在新的微服務(wù)上線后立刻切換到這些數(shù)據(jù)源上。

3. 利用六邊形架構(gòu)

我們需要有在不影響業(yè)務(wù)邏輯的前提下切換數(shù)據(jù)源的能力,因此我們需要讓它們保持解耦狀態(tài)。

我們決定基于六邊形架構(gòu)的原則來(lái)構(gòu)建應(yīng)用。

六邊形架構(gòu)的思想是將輸入和輸出都放在設(shè)計(jì)的邊緣部分。不管我們公開的是 REST 還是 GraphQL API,也不管我們從何處獲取數(shù)據(jù)——是通過數(shù)據(jù)庫(kù)、通過 gRPC 還是 REST 公開的微服務(wù) API,或者僅僅是一個(gè)簡(jiǎn)單的 CSV 文件——都不應(yīng)該影響業(yè)務(wù)邏輯。

這種模式讓我們能將應(yīng)用程序的核心邏輯與外部的關(guān)注點(diǎn)隔離開來(lái)。核心邏輯隔離后,意味著我們可以輕松更改數(shù)據(jù)源的細(xì)節(jié),而不會(huì)造成重大影響或需要在代碼庫(kù)重寫大量代碼。

我們還看到,在應(yīng)用中具有清晰邊界的另一大優(yōu)勢(shì)就是測(cè)試策略——我們的大多數(shù)測(cè)試在驗(yàn)證業(yè)務(wù)邏輯時(shí),都不需要依賴那些很容易變化的協(xié)議。

4. 定義核心概念

借鑒六邊形架構(gòu),定義我們業(yè)務(wù)邏輯的三大概念分別是實(shí)體、存儲(chǔ)庫(kù)和交互器。

實(shí)體(Entities)指的是域?qū)ο螅ɡ缫徊坑捌蛞粋€(gè)拍攝地點(diǎn)),它們不知道自身的存儲(chǔ)位置(不像是 Ruby on Rails 中的 Active Record 或者 Java Persistence API 那樣)。

存儲(chǔ)庫(kù)(Repositories)是獲取實(shí)體及創(chuàng)建和更改實(shí)體的接口。它們保存一系列方法,用來(lái)與數(shù)據(jù)源通信并返回單個(gè)實(shí)體或?qū)嶓w列表。(例如 UserRepository)

交互器(Interactors)是用來(lái)編排和執(zhí)行域動(dòng)作(domain action)的類——可以考慮服務(wù)對(duì)象或用例對(duì)象。它們實(shí)現(xiàn)復(fù)雜的業(yè)務(wù)規(guī)則和針對(duì)特定域動(dòng)作(例如上線一部節(jié)目)的驗(yàn)證邏輯。

有了這三大類對(duì)象,我們就可以在定義業(yè)務(wù)邏輯時(shí)無(wú)需知曉或者關(guān)心數(shù)據(jù)的存儲(chǔ)位置,也不用理會(huì)業(yè)務(wù)邏輯是怎樣觸發(fā)的。業(yè)務(wù)邏輯之外是數(shù)據(jù)源和傳輸層:

數(shù)據(jù)源(Data Sources)是針對(duì)不同存儲(chǔ)實(shí)現(xiàn)的適配器(Adaptor)。數(shù)據(jù)源可能是 SQL 數(shù)據(jù)庫(kù)的適配器(Rails 中的 Active Record 類或 Java 中的 JPA)、彈性搜索適配器、REST API,甚至是諸如 CSV 文件或 Hash 之類的簡(jiǎn)單適配器。數(shù)據(jù)源實(shí)現(xiàn)在存儲(chǔ)庫(kù)上定義的方法,并存儲(chǔ)獲取和推送數(shù)據(jù)的實(shí)現(xiàn)。

傳輸層(Transport Layer)可以觸發(fā)交互器來(lái)執(zhí)行業(yè)務(wù)邏輯。我們將其視為系統(tǒng)的輸入。微服務(wù)最常見的傳輸層是 HTTP API 層和一組用來(lái)處理請(qǐng)求的控制器(Controller)。將業(yè)務(wù)邏輯提取到交互器后,我們就不會(huì)耦合到特定的傳輸層或控制器實(shí)現(xiàn)上。交互器不僅可以由控制器觸發(fā),還能由事件、cron 作業(yè)或從命令行觸發(fā)。

Netflix 的六边形架构实践

六邊形架構(gòu)的依賴圖向內(nèi)收縮

在傳統(tǒng)的分層架構(gòu)中,我們所有的依賴項(xiàng)都會(huì)指向一個(gè)方向,上面的每一層都會(huì)依賴自己下面的層。傳輸層會(huì)依賴交互器,而交互器會(huì)依賴持久存儲(chǔ)層。

在六邊形架構(gòu)中,所有依賴項(xiàng)都指向中心方向。我們的核心業(yè)務(wù)邏輯對(duì)傳輸層或數(shù)據(jù)源一無(wú)所知。但傳輸層仍然知道如何使用交互器,數(shù)據(jù)源也知道如何對(duì)接存儲(chǔ)庫(kù)接口。

這樣,我們就可以為將來(lái)切換到其他 Studio 系統(tǒng)的更改做好準(zhǔn)備,并且當(dāng)需要邁出這一步時(shí),我們很容易就能完成切換數(shù)據(jù)源的任務(wù)。

5. 切換數(shù)據(jù)源

切換數(shù)據(jù)源的需求比我們預(yù)期來(lái)得更早一些——我們的單體架構(gòu)突然遇到一個(gè)讀取瓶頸,并且需要將某個(gè)實(shí)體的特定讀取切換到一個(gè)在 GraphQL 聚合層上公開的新版微服務(wù)上。這個(gè)微服務(wù)和單體保持同步,數(shù)據(jù)相同,并且它們從各個(gè)服務(wù)中讀取時(shí)產(chǎn)生的結(jié)果也是一致。

我們?cè)O(shè)法在 2 小時(shí)內(nèi)就將數(shù)據(jù)讀取從一個(gè) JSON API 切換到一個(gè) GraphQL 數(shù)據(jù)源上。

我們之所以能如此快地完成這一操作,主要?dú)w功于六邊形架構(gòu)。我們沒有讓任何持久存儲(chǔ)細(xì)節(jié)泄漏到業(yè)務(wù)邏輯中。我們創(chuàng)建了一個(gè)實(shí)現(xiàn)存儲(chǔ)庫(kù)接口的 GraphQL 數(shù)據(jù)源。因此,只需要做簡(jiǎn)單的一行代碼更改,即可開始從新的數(shù)據(jù)源讀取數(shù)據(jù)。

Netflix 的六边形架构实践

通過適當(dāng)?shù)某橄螅苋菀赘臄?shù)據(jù)源

到這個(gè)時(shí)候,我們就知道使用六邊形架構(gòu)沒錯(cuò)了。

單行代碼更改有一大優(yōu)勢(shì),那就是它可以減小發(fā)布風(fēng)險(xiǎn)。如果下游微服務(wù)在初始部署時(shí)失敗,回滾也會(huì)非常容易。這也讓我們能解耦部署和激活作業(yè),因?yàn)榭梢酝ㄟ^配置來(lái)決定使用哪個(gè)數(shù)據(jù)源。

6. 隱藏?cái)?shù)據(jù)源細(xì)節(jié)

這種架構(gòu)的一大優(yōu)勢(shì)是讓我們能封裝數(shù)據(jù)源的實(shí)現(xiàn)細(xì)節(jié)。

我們遇到這樣一種情況:有一次,我們需要一個(gè)尚不存在的 API 調(diào)用——有一個(gè)服務(wù)用一個(gè) API 來(lái)獲取單個(gè)資源,但沒有實(shí)現(xiàn)批量獲取。與提供該 API 的團(tuán)隊(duì)交流后,我們得知這個(gè)批量獲取端點(diǎn)需要一些時(shí)間才能交付。因此,我們決定在這個(gè)端點(diǎn)構(gòu)建的同時(shí),使用另一種方案來(lái)解決這個(gè)問題。

我們定義了一個(gè)存儲(chǔ)庫(kù)方法,該方法可以在給定多個(gè)記錄標(biāo)識(shí)符的情況下獲取多個(gè)資源——并且該方法在數(shù)據(jù)源的初始實(shí)現(xiàn)會(huì)向下游服務(wù)發(fā)送多個(gè)并發(fā)調(diào)用。我們知道這是一個(gè)臨時(shí)的解決方案,數(shù)據(jù)源實(shí)現(xiàn)的下一步改進(jìn)是在批量 API 構(gòu)建完畢后切換到新 API 上。

Netflix 的六边形架构实践

我們的業(yè)務(wù)邏輯不需要了解特定的數(shù)據(jù)源限制

這樣的設(shè)計(jì)讓我們能繼續(xù)開發(fā)以滿足業(yè)務(wù)需求,同時(shí)不會(huì)積累太多技術(shù)債,也無(wú)需事后更改任何業(yè)務(wù)邏輯。

7. 測(cè)試策略

當(dāng)我們開始嘗試六邊形架構(gòu)時(shí),就知道需要提出一種測(cè)試策略。要提升開發(fā)速度的先決條件就是擁有可靠且非常快的測(cè)試套件。我們不認(rèn)為這是錦上添花,而是必要條件。

我們決定在三個(gè)不同的層上測(cè)試應(yīng)用:

我們測(cè)試了交互器,業(yè)務(wù)邏輯的核心存在于此,但與任何類型的持久層或傳輸層無(wú)關(guān)。我們用上了依賴注入,并 mock 任意類型的存儲(chǔ)庫(kù)交互。在這里我們?cè)敿?xì)測(cè)試業(yè)務(wù)邏輯,大部分測(cè)試都位于此處。

Netflix 的六边形架构实践

我們測(cè)試數(shù)據(jù)源,以確定它們是否與其他服務(wù)正確集成,它們是否對(duì)接上存儲(chǔ)庫(kù)接口,并檢查它們?cè)诔霈F(xiàn)錯(cuò)誤時(shí)的行為。我們?cè)囍M量減少這些測(cè)試的數(shù)量。

Netflix 的六边形架构实践

我們具有遍及整個(gè)棧的集成規(guī)范,從我們的 Transport/API 層到交互器、存儲(chǔ)庫(kù)、數(shù)據(jù)源以及重要的下游服務(wù)全部包含在內(nèi)。這些規(guī)范測(cè)試的是我們是否正確“布線”了一切。如果一個(gè)數(shù)據(jù)源是一個(gè)外部 API,我們將命中該端點(diǎn)并記錄響應(yīng)(并將其存儲(chǔ)在 git 中),從而讓我們的測(cè)試套件可以在每次后續(xù)調(diào)用時(shí)快速運(yùn)行。我們不會(huì)在這一層進(jìn)行廣泛測(cè)試,通常每個(gè)域動(dòng)作只有一個(gè)成功場(chǎng)景和一個(gè)失敗場(chǎng)景。

Netflix 的六边形架构实践

我們不會(huì)測(cè)試存儲(chǔ)庫(kù),因?yàn)樗鼈兪菙?shù)據(jù)源實(shí)現(xiàn)的簡(jiǎn)單接口;并且我們很少測(cè)試實(shí)體,因?yàn)樗鼈兪嵌x了屬性的普通對(duì)象。我們會(huì)測(cè)試實(shí)體是否有其他方法(這里不涉及持久層)。

我們還有改進(jìn)空間,比如我們將來(lái)可以不 ping 所依賴的任何服務(wù),而是 100%依賴合同測(cè)試。有了上述方式編寫的測(cè)試套件,我們可以 100 秒內(nèi)在單個(gè)過程中運(yùn)行大約 3000 個(gè) specs。

能輕松在任何機(jī)器上運(yùn)行的測(cè)試套件,它用起來(lái)非常棒,我們的開發(fā)團(tuán)隊(duì)可以在不中斷的前提下做日常功能測(cè)試。

8. 延遲決策

現(xiàn)在我們可以輕松將數(shù)據(jù)源切換到不同的微服務(wù)上。關(guān)鍵的一大好處是,我們能延遲一些關(guān)于是否以及如何存儲(chǔ)應(yīng)用程序內(nèi)部數(shù)據(jù)的決策。根據(jù)功能用例,我們甚至可以靈活確定數(shù)據(jù)存儲(chǔ)的類型——可以是關(guān)系型也可以是文檔型。

當(dāng)這個(gè)項(xiàng)目開始時(shí),我們對(duì)正在構(gòu)建的這個(gè)系統(tǒng)的了解是非常少的。我們不應(yīng)該將自己鎖定在一個(gè)會(huì)導(dǎo)致項(xiàng)目悖論和不明智決策的架構(gòu)中。

我們現(xiàn)在做的決策符合我們需求,并且讓我們能快速行動(dòng)。六邊形架構(gòu)的最大優(yōu)點(diǎn)在于,它可以讓我們的應(yīng)用程序靈活適應(yīng)未來(lái)需求。

 

責(zé)任編輯:張燕妮 來(lái)源: 架構(gòu)頭條
相關(guān)推薦

2017-02-21 17:25:51

架構(gòu)六邊形架構(gòu)數(shù)據(jù)庫(kù)

2023-08-06 23:31:36

架構(gòu)系統(tǒng)RPC

2019-12-16 08:08:39

六邊形架構(gòu)分層架構(gòu)架構(gòu)

2023-12-13 10:06:28

六邊形架構(gòu)系統(tǒng)測(cè)試

2023-04-14 08:00:00

架構(gòu)測(cè)試開發(fā)

2022-12-28 07:48:40

六邊形動(dòng)畫CSS

2023-11-01 07:41:39

六邊形架構(gòu)適配器架構(gòu)

2024-04-17 08:06:41

六邊形洋蔥架構(gòu)領(lǐng)域

2023-10-30 10:12:20

2021-08-29 18:32:18

CSS

2025-01-17 11:38:10

2025-02-24 07:39:53

2017-06-08 10:33:42

軟件開發(fā)前后端架構(gòu)

2023-09-08 18:37:34

HarmonyOS

2022-11-08 08:00:00

開發(fā)Uber數(shù)據(jù)庫(kù)

2024-07-08 08:33:00

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 狠狠插狠狠操 | 成人在线| 婷婷丁香激情 | 综合久久综合久久 | 国产综合精品一区二区三区 | 精品一区二区三区不卡 | 91视频观看 | 9色视频在线| 操操操操操| 午夜在线 | 国产精品久久久久久久免费观看 | 亚洲网视频| 成人综合在线视频 | 99在线免费观看视频 | 草b视频 | 国产污视频在线 | 亚洲三区在线观看 | 久久久不卡网国产精品一区 | 欧美一级大黄 | 免费观看国产视频在线 | 黄色一级大片在线免费看产 | 国产一区二区三区四区五区加勒比 | 先锋av资源网 | 国产精品久久网 | 综合色久 | 亚洲视频在线看 | 日韩欧美在线视频 | 欧美精品一区二区三区在线播放 | 中文字幕免费视频 | 国产日韩精品一区二区 | 中文字幕乱码一区二区三区 | 欧美中文一区 | 国产午夜亚洲精品不卡 | 亚洲黄色成人网 | 99草免费视频 | 免费一区| 国产91中文 | 国产亚洲精品精品国产亚洲综合 | 91亚洲国产成人久久精品网站 | 成人av影院 | 亚洲国产中文在线 |