Netflix 的六邊形架構實踐

2020-12-27 InfoQ技術實驗室

隨著 Netflix 原創內容的逐年增長,我們要構建一些可提升整個創作過程效率的應用。我們的一個大型部門,Studio 工程組織已經構建眾多應用,去幫助從劇本製作到內容播出的全套流程,涉及的環節涵蓋劇本內容獲取、交易談判和供應商管理,以及日程安排、簡化生產流程等。

從開始就高度集成

大約一年前,我們的 Studio 流程團隊開始開發一款跨多個業務領域的全新應用。

當時,我們面臨一項有意思的挑戰:

一方面我們需要從頭開始構建應用的核心,另一方面我們所需的數據分布在眾多不同的系統之中。

我們所需要的一些數據,比如有關影片信息、製作日期、員工和拍攝地點的數據,分布於許多服務中。並且,它們使用的協議也各有不同,包括 gRPC、JSON API、GraphQL 等等。

對我們應用程式的行為和業務邏輯而言,已有數據非常重要。我們從一開始就需要高度集成。

可切換數據源

早期的一款應用程式用來為我們的產品引入可見性,它被設計為單體架構。

在領域知識體系尚未建立的情況下,單體架構可以實現快速開發和快速變更。後來,使用它的開發人員超過 30 人,有超過 300 個資料庫表。

隨著時間流逝,應用程式從涉及面廣泛的服務演變成高度專業化的產品。在這樣的背景下,團隊決定將單體架構解構為一系列專用服務。

做出這一決策並非性能問題,而是要對所有這些領域設置界限,並讓各個專屬團隊能獨立開發針對每個特定領域的服務。

我們的新應用所需的大量數據依舊是之前的單體提供的,但我們知道這個單體將在某一天分解開來。我們不能確定具體時間,但知道這一時刻不可避免,所以需要做好準備。

這樣的話,我們能在一開始利用某些來自單體的數據,因為它們仍然是可信來源;但我們也要做好準備,在新的微服務上線後立刻切換到這些數據源上。

利用六邊形架構

我們需要有在不影響業務邏輯的前提下切換數據源的能力,因此我們需要讓它們保持解耦狀態。

我們決定基於六邊形架構的原則來構建應用。

六邊形架構的思想是將輸入和輸出都放在設計的邊緣部分。不管我們公開的是 REST 還是 GraphQL API,也不管我們從何處獲取數據——是通過資料庫、通過 gRPC 還是 REST 公開的微服務 API,或者僅僅是一個簡單的 CSV 文件——都不應該影響業務邏輯。

這種模式讓我們能將應用程式的核心邏輯與外部的關注點隔離開來。核心邏輯隔離後,意味著我們可以輕鬆更改數據源的細節,而不會造成重大影響或需要在代碼庫重寫大量代碼

我們還看到,在應用中具有清晰邊界的另一大優勢就是測試策略——我們的大多數測試在驗證業務邏輯時,都不需要依賴那些很容易變化的協議。

定義核心概念

借鑑六邊形架構,定義我們業務邏輯的三大概念分別是實體存儲庫交互器

實體(Entities)指的是域對象(例如一部影片或一個拍攝地點),它們不知道自身的存儲位置(不像是 Ruby on Rails 中的 Active Record 或者 Java Persistence API 那樣)。存儲庫(Repositories)是獲取實體及創建和更改實體的接口。它們保存一系列方法,用來與數據源通信並返回單個實體或實體列表。(例如 UserRepository)交互器(Interactors)是用來編排和執行域動作(domain action)的類——可以考慮服務對象或用例對象。它們實現複雜的業務規則和針對特定域動作(例如上線一部節目)的驗證邏輯。有了這三大類對象,我們就可以在定義業務邏輯時無需知曉或者關心數據的存儲位置,也不用理會業務邏輯是怎樣觸發的。業務邏輯之外是數據源和傳輸層:

數據源(Data Sources)是針對不同存儲實現的適配器(Adaptor)。數據源可能是 SQL 資料庫的適配器(Rails 中的 Active Record 類或 Java 中的 JPA)、彈性搜索適配器、REST API,甚至是諸如 CSV 文件或 Hash 之類的簡單適配器。數據源實現在存儲庫上定義的方法,並存儲獲取和推送數據的實現。傳輸層(Transport Layer)可以觸發交互器來執行業務邏輯。我們將其視為系統的輸入。微服務最常見的傳輸層是 HTTP API 層和一組用來處理請求的控制器(Controller)。將業務邏輯提取到交互器後,我們就不會耦合到特定的傳輸層或控制器實現上。交互器不僅可以由控制器觸發,還能由事件、cron 作業或從命令行觸發。

六邊形架構的依賴圖向內收縮

在傳統的分層架構中,我們所有的依賴項都會指向一個方向,上面的每一層都會依賴自己下面的層。傳輸層會依賴交互器,而交互器會依賴持久存儲層。

在六邊形架構中,所有依賴項都指向中心方向。我們的核心業務邏輯對傳輸層或數據源一無所知。但傳輸層仍然知道如何使用交互器,數據源也知道如何對接存儲庫接口。

這樣,我們就可以為將來切換到其他 Studio 系統的更改做好準備,並且當需要邁出這一步時,我們很容易就能完成切換數據源的任務。

切換數據源

切換數據源的需求比我們預期來得更早一些——我們的單體架構突然遇到一個讀取瓶頸,並且需要將某個實體的特定讀取切換到一個在 GraphQL 聚合層上公開的新版微服務上。這個微服務和單體保持同步,數據相同,並且它們從各個服務中讀取時產生的結果也是一致。

我們設法在 2 小時內就將數據讀取從一個 JSON API 切換到一個 GraphQL 數據源上。

我們之所以能如此快地完成這一操作,主要歸功於六邊形架構。我們沒有讓任何持久存儲細節洩漏到業務邏輯中。我們創建了一個實現存儲庫接口的 GraphQL 數據源。因此,只需要做簡單的一行代碼更改,即可開始從新的數據源讀取數據。

通過適當的抽象,很容易更改數據源

到這個時候,我們就知道使用六邊形架構沒錯了。

單行代碼更改有一大優勢,那就是它可以減小發布風險。如果下遊微服務在初始部署時失敗,回滾也會非常容易。這也讓我們能解耦部署和激活作業,因為可以通過配置來決定使用哪個數據源。

隱藏數據源細節

這種架構的一大優勢是讓我們能封裝數據源的實現細節。

我們遇到這樣一種情況:有一次,我們需要一個尚不存在的 API 調用——有一個服務用一個 API 來獲取單個資源,但沒有實現批量獲取。與提供該 API 的團隊交流後,我們得知這個批量獲取端點需要一些時間才能交付。因此,我們決定在這個端點構建的同時,使用另一種方案來解決這個問題。

我們定義了一個存儲庫方法,該方法可以在給定多個記錄標識符的情況下獲取多個資源——並且該方法在數據源的初始實現會向下遊服務發送多個並發調用。我們知道這是一個臨時的解決方案,數據源實現的下一步改進是在批量 API 構建完畢後切換到新 API 上。

我們的業務邏輯不需要了解特定的數據源限制

這樣的設計讓我們能繼續開發以滿足業務需求,同時不會積累太多技術債,也無需事後更改任何業務邏輯。

測試策略

當我們開始嘗試六邊形架構時,就知道需要提出一種測試策略。要提升開發速度的先決條件就是擁有可靠且非常快的測試套件。我們不認為這是錦上添花,而是必要條件。

我們決定在三個不同的層上測試應用:

我們測試了交互器,業務邏輯的核心存在於此,但與任何類型的持久層或傳輸層無關。我們用上了依賴注入,並 mock 任意類型的存儲庫交互。在這裡我們詳細測試業務邏輯,大部分測試都位於此處。

我們測試數據源,以確定它們是否與其他服務正確集成,它們是否對接上存儲庫接口,並檢查它們在出現錯誤時的行為。我們試著儘量減少這些測試的數量。

我們具有遍及整個棧的集成規範,從我們的 Transport/API 層到交互器、存儲庫、數據源以及重要的下遊服務全部包含在內。這些規範測試的是我們是否正確「布線」了一切。如果一個數據源是一個外部 API,我們將命中該端點並記錄響應(並將其存儲在 git 中),從而讓我們的測試套件可以在每次後續調用時快速運行。我們不會在這一層進行廣泛測試,通常每個域動作只有一個成功場景和一個失敗場景。

我們不會測試存儲庫,因為它們是數據源實現的簡單接口;並且我們很少測試實體,因為它們是定義了屬性的普通對象。我們會測試實體是否有其他方法(這裡不涉及持久層)。

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

能輕鬆在任何機器上運行的測試套件,它用起來非常棒,我們的開發團隊可以在不中斷的前提下做日常功能測試。

延遲決策

現在我們可以輕鬆將數據源切換到不同的微服務上。關鍵的一大好處是,我們能延遲一些關於是否以及如何存儲應用程式內部數據的決策。根據功能用例,我們甚至可以靈活確定數據存儲的類型——可以是關係型也可以是文檔型。

當這個項目開始時,我們對正在構建的這個系統的了解是非常少的。我們不應該將自己鎖定在一個會導致項目悖論和不明智決策的架構中。

我們現在做的決策符合我們需求,並且讓我們能快速行動。六邊形架構的最大優點在於,它可以讓我們的應用程式靈活適應未來需求。

關注我並轉發此篇文章,私信我「領取資料」,即可免費獲得InfoQ價值4999元迷你書!

相關焦點

  • OpenStack架構分析與實踐
    一、業務架構設計思路OpenStck做的比較好的一點就是架構設計比較通過,對於不同的模塊,其業務架構設計方面一般滿足以下設計思路:• REST API接收外部請求• Scheduler負責調度服務• Worker負責任務分配• Driver負責任務實現• 消息隊列負責組件內部通信
  • 直播中「周邊」系統的最佳實踐|架構師實踐日
    在 7 月 31 日的上海架構師實踐日中,來自 LeanCloud 研發工程師吳俊,為我們帶來了他們在直播中「周邊」系統的最佳實踐 ,以下是對他演講內容的整理。「七牛架構師實踐日」——這裡只談架構 七牛架構師實踐日是由七牛雲發起的線下技術沙龍活動,聯合業內資深技術大牛以及各大巨頭公司和創業品牌的優秀架構師,致力於為業內開發者、架構師和決策者提供最前沿、最有深度的技術交流平臺,幫助大家知悉技術動態,學習經驗成果。
  • 蘑菇街直播實踐 架構師實踐日
    蘑菇街作為國內「直播+電商」模式的先行者,在七牛架構師實踐日上,帶來了他們從直播立項到開發上線全過程的經驗分享。下面就是對他此次演講內容的整理。嘉賓簡介:袁健吉,蘑菇街高級開發工程師,從事 iOS 移動開發,目前負責蘑菇街 iOS 客戶端直播業務的功能開發以及和各業務方溝通的相關工作,擅長 iOS 領域圖像、視頻、直播相關技術。
  • 10個最佳實踐技巧,實現有效的微服務架構!
    今天,小芯給大家帶來的是不能不提系列——正確實施微服務架構的10條技巧(也是10個最佳實踐)。微服務架構是什麼?這是筆者自己整理的定義:微服務架構是將軟體系統分解為自主模塊,這些自主模塊可獨立部署,並通過輕量級,與語言無關的方式進行通信,共同實現業務目標。軟體系統很複雜。
  • 微影技術架構實踐之路
    十億級別DPV千萬級別DAU系統可處理訂單為每秒10萬整個系統的調用達到每秒30萬90%請求的延遲時間200毫秒以內SLA(Service-LevelAgreement,服務等級協議)99 %        好的系統架構都相似,而不合理的系統卻有各自的問題。
  • 雲原生生態大會Day2,網易數帆Service Mesh與百勝中國中臺架構實踐
    12月16-17日,由CNCF、網易數帆、VMware、PingCAP和阿里雲聯合主辦2020 Cloud Native Day雲原生生態大會線上召開,來自聯合主辦方及字節跳動、Zilliz、百勝中國等公司的17位重磅演講嘉賓,帶來2天主題分享,解析雲原生領軍企業和組織、頭部用戶的雲原生戰略與實踐
  • 【博採】Netflix:數據處理架構的演進
    Netflix之所以能夠如此成功,離不開對用戶行為數據的收集與分析,那麼Netflix會收集哪些數據,這些數據會用來做什麼,其處理架構又是什麼呢?本文根據Netflix博客上的《Netflix's Viewing Data: How We Know Where You Are in House of Cards》一文整理而來。
  • 汕尾城區:「三級架構」「五大系列」實踐點打造城市文化名片
    汕尾城區:「三級架構」「五大系列」實踐點打造城市文化名片金羊網  作者:嚴藝文  2019-06-10 金羊網訊 記者嚴藝文報導:「來,快傳給我!」雨後的惠民廣場上,幾個活潑的男孩正在踢足球。惠民廣場對面,正是汕尾市城區新時代文明實踐中心所在地。
  • 新浪微博混合雲架構實踐挑戰之鏡像分發實戰
    相信大家通過前面幾篇的介紹,對微博DCP系統的架構已經有了一些了解,今天我們來聊一聊微博混合雲在鏡像分發方面的一些實踐經驗。
  • 來看土星霧層上的神秘六邊形
    現在對這個六邊形的了解還很模糊。土星六邊形的一張高清彩圖。(圖源:美國航天局/噴氣推進實驗室加州理工學院/SSI/漢普頓大學)一個新的研究發現,土星詭異的六邊形有一個廣泛的霧層系統。「土星六邊形」是土星北極的一個漩渦,顧名思義,它是詭異的六邊形,這個六邊形是一個永恆的雲狀,它像一個巨大的旋轉塔一樣矗立在土星上。
  • 六邊形雪花是如何形成的?
    六邊形雪花是如何形成的?時間:2016-12-21 10:25   來源:360問答   責任編輯:沫朵 川北在線核心提示:原標題:雪花為何都是六角? 六邊形雪花是如何形成的? 雪花,一種晶體,結構隨溫度的變化而變化,又名未央花和六出,一種美麗的結晶體,它在飄落過程中成團攀聯在一起,就形成雪片。單個雪花的大小通常在0.054.6毫米之間。
  • NETFLIX觀看教程
    我相信大家在網上都聽說過netflix(奈飛)吧?
  • 架構設計的四大思維支柱
    大家可能會覺得架構管理軟體更重要、更直接,但是架構管理軟體是根據架構設計方法論和架構設計實踐做出來的,所以方法論和模型資產是更重要的基礎性工具,而以目前架構設計的「混亂」現狀而言,沒有通用的架構管理工具也是必然的,因為公認能普適的架構理論和行業級標準化的模型資產都沒有,也就沒有合適的、可以真正直達「痛處」架構管理工具,如果能做出這樣的工具,那麼,一定可以開闢一個世界級的市場。
  • 可不要再錯過冬季六邊形和月亮了!
    11月初,我們就能欣賞到月亮穿越「冬季六邊形」的動態之舞。作為冬季最著名的恆星群之一,每年「冬季六邊形」就像老朋友們一樣按時列隊回歸,來參加年終星空派對。北半球的冬季六邊形攝影來源:Petr Horálek星空派對開始的時候,我們不僅能欣賞到老朋友們——獵戶座、雙子座和金牛座的閃亮登臺,還能看到月亮在它們中間翩翩起舞——它們用魔法把月亮也帶上了舞臺。冬季六邊形是一個巨大的星群,橫跨夜空,由六顆一等星組成,每年仲秋前後就出現在夜空了,整個冬季可見,直到最後一顆星消逝在春天西方的黃昏中。
  • 直觀下的證明:二維網格點是無法做出一個正六邊形和等邊三角形
    上一篇我們介紹了如果點陣網格可以做出一個等邊三角形,那麼必定能做出一個正六邊形,使其6個頂點分布在網格點上我們選取其中一個邊,旋轉90度如下圖所示旋轉後的邊的另一個端點必在網格點上接著我們旋轉第二條邊,旋轉角度為90度,如下圖所示同樣旋轉後的邊的另一個端點仍處在網格點上
  • 花藝架構|技巧和創意的融合
    架構設計作為當下花藝設計流行的趨勢 ,架構花藝設計的形式也被越來越廣泛的運用 。無論是商業產品的再創作還是競技選手作品的設計 ,架構的注入都為這些作品創造了無限的可能性。學習過架構的人都知道,這裡是一個魔法世界,可以給你的花藝設計帶來無限創新的可能性,也會帶你走向花藝設計的另一個高峰。如果說架構的骨架設計是靜態的表達,那無限的內部空間交由我們去探索創作。
  • 日本選手六邊形能力圖出爐 奧原自評兩項0分
    日本選手六邊形能力圖出爐 奧原自評兩項0分 2020-12-23 14:38  愛羽客羽毛球網
  • 京東資深架構師爆肝純手打700頁架構進階寶典我粉了
    前言在這個大家熱議的人工智慧時代,也使我們有了更多的反思,其實在這些熱點議題的背後,一些基礎架構與底層系統技術的發展與實現或許更加務實和接地氣一些,同時產業界也需要有更堅實的基礎架構與底層系統技術來支撐日益增長的龐大的業務量。
  • 暢快訪問Netflix /HBO的全新解決方案
    很多發燒友應該都聽說過netflix /HBO的大名,然而正常情況下國內無法正常訪問,以netflix 舉例,不同於國內愛奇藝騰訊等假4K片源,
  • 土星六邊形大風暴,比木星大紅斑還恐怖詭異!竟能裝下4個地球!
    極地風暴在土星的北極比大紅斑更神秘,更令人難以置信的是,這個風暴呈現出奇怪的六邊形。1980年,旅行者1號在穿越土星時發現了人類第一次在土星上觀察到的大風暴。但因為旅行者1號的任務是飛出太陽系,所以返回的土星風暴資料非常少。所以,科學家們就沒有足夠的圖像和數據進行分析研究了。