當前位置:
首頁 > 知識 > Netflix採用GraphQL的經驗分享

Netflix採用GraphQL的經驗分享

NetflixOSS是Spring Cloud默認堆棧,他們的實踐走在行業前列,在這篇博文中,他們解釋了為什麼GraphQL很棒,以及成長的痛苦在哪裡。

在這篇文章中,我們將分享我們更新前端架構的過程以及將GraphQL引入Marketing Tech系統的經驗。

我們的發布平台的廣告管理應用在內部被稱為Monet,用於增強廣告製作並自動管理外部廣告平台上的營銷廣告系列。Monet幫助推動增量轉換,與我們的產品互動,總體而言,向全世界的用戶展示我們的內容和Netflix品牌的豐富故事。為此,首先,它有助於擴展和自動化廣告製作並管理數百萬個廣告素材排列。其次,我們利用各種信號和匯總數據,例如了解Netflix上的內容流行度,以實現高度相關的廣告。

我們的總體目標是使我們在所有外部發布渠道上的廣告能夠與用戶產生共鳴,並且我們不斷嘗試提高我們這樣做的有效性。

問題

當我們開始時,Monet的React UI層訪問了由Apache Tomcat伺服器支持的傳統REST API。隨著時間的推移,隨著應用程序的發展,我們的用例變得更加複雜。簡單頁面需要從各種來源中提取數據。為了更有效地將此數據載入到客戶端應用程序,我們首先嘗試對後端的數據進行非規範化。管理這種非規範化變得難以維護,因為並非所有頁面都需要所有數據。我們很快遇到了網路帶寬瓶頸。瀏覽器需要獲取比以往更多的非規範化數據。

為了減少發送給客戶端的欄位數量,一種方法是為每個頁面構建自定義端點; 這是一個相當明顯的非首選項。我們選擇GraphQL作為應用程序的中間層,而不是構建這些自定義端點。

我們還認為Falcor是一種可能的解決方案,因為它在許多核心用例中已經在Netflix上取得了很好的成果並且使用量很大,但強大的GraphQL生態系統和強大的第三方工具使得GraphQL成為我們用例的更好選擇。此外,隨著我??們的數據結構越來越以圖形為導向,它最終變得非常自然。添加GraphQL不僅解決了網路帶寬瓶頸問題,而且還提供了許多其他優勢,幫助我們更快地添加功能。

優點

我們已經在NodeJS上運行GraphQL大約6個月,並且它已經證明可以顯著提高我們的開發速度和整體頁面載入性能。以下是自我們開始使用以來對我們有益的一些好處。

1.重新分配負載和有效負載優化

通常,某些機器比其他機器更適合某些任務。當我們添加GraphQL中間層時,GraphQL伺服器仍然需要調用與客戶端直接調用的相同的服務和REST API。現在的區別在於大多數數據在同一數據中心內的伺服器之間流動調用。這些伺服器到伺服器的調用具有非常低的延遲和高帶寬,與來自瀏覽器的直接網路調用相比,前者性能是後者8倍。

因此,從GraphQL伺服器到客戶端瀏覽器的數據傳輸的最後一英里雖然仍然是一個性能慢點,現在採取GraphQL以後可以減少到一次網路調用。由於GraphQL允許客戶端只選擇它需要的數據,我們獲得了明顯更小的有效負載。頁面載入變得更快,尤其是在數據受限的移動網路上,我們的應用程序使用的內存更少。這些更改確實以提高伺服器利用率為代價來執行數據獲取和聚合。

2.可重複的抽象

軟體開發人員通常希望使用可重用的抽象而不是單一用途的方法。使用GraphQL,我們定義每一段數據,並定義它與我們系統中其他數據的關係。當消費者應用程序從多個源獲取數據時,它不再需要擔心與數據連接操作相關聯的複雜業務邏輯。

我們只在GraphQL中定義一次實體:目錄,廣告素材和評論。我們現在可以根據這些定義構建多個頁面的視圖。相同的圖模型可以為多個視圖提供動力,而無需進行任何伺服器端代碼更改。

3.鏈式系統

許多人專註於單一服務中的類型系統,但很少跨服務。一旦我們在GraphQL伺服器中定義了實體,我們就會使用auto codegen工具為客戶端應用程序生成TypeScript類型。我們的React組件的道具接收類型以匹配組件正在進行的查詢。

由於這些類型和查詢也是針對伺服器模式進行驗證的,因此伺服器的任何重大更改都將被使用該數據的客戶端捕獲。將多個服務與GraphQL鏈接在一起並將這些檢查掛鉤到構建過程中,可以在部署錯誤代碼之前捕獲更多問題。理想情況下,我們希望從資料庫層一直到客戶端瀏覽器具有類型安全性。

4.DI / DX - 簡化開發

創建客戶端應用程序時常見的問題是UI / UX,但開發人員界面和開發人員體驗對於構建可維護應用程序同樣重要。在GraphQL之前,編寫一個新的React容器組件需要維護複雜的邏輯,以便為我們需要的數據發出網路請求。開發人員需要考慮一個數據如何與另一個數據相關,如何緩存數據,是否並行或按順序進行調用以及Redux中存儲數據的位置。使用GraphQL查詢包裝器,每個React組件只需要描述它所需的數據,並且包裝器會處理所有這些問題。樣板代碼更少,數據和UI之間的關注點更清晰。這種聲明性數據獲取模型使React組件更容易理解,

5.其他福利

還有一些其他較小的好處,我們也注意到了。首先,如果GraphQL查詢的任何解析程序失敗,則成功的解析程序仍會將數據返回到客戶端,以儘可能多地呈現頁面。其次,後端數據模型大大簡化,因為我們不太關心客戶端的建模,並且在大多數情況下可以簡單地為原始實體提供CRUD介面。最後,測試我們的組件也變得更容易,因為GraphQL查詢可以自動轉換為我們測試的存根,我們可以獨立於React組件測試解析器。

成長的煩惱

我們向GraphQL的遷移是一種簡單的體驗。我們為構建網路請求和轉換數據而構建的大多數基礎架構都可以輕鬆地從我們的React應用程序轉移到我們的NodeJS伺服器,而無需更改任何代碼。我們甚至最終刪除了比我們添加的更多代碼。但是,與任何向新技術的遷移一樣,我們需要克服一些障礙。

1.自私的解析器

由於GraphQL中的解析器旨在作為與其他解析器無關的獨立單元運行,因此我們發現它們對相同或類似的數據進行了許多重複的網路請求。我們通過將數據提供程序包裝在一個簡單的緩存層中來解決這種重複問題,該緩存層將網路響應存儲在內存中,直到所有解析器完成。緩存層還允許我們將對單個服務的多個請求聚合成一次性所有數據的批量請求。解析器現在可以請求他們需要的任何數據,而無需擔心如何優化獲取它的過程。

2.我們編織的網路多麼糟糕

抽象是提高開發人員效率的好方法......直到出現問題。毫無疑問,我們的代碼中存在錯誤,我們不希望使用中間層來混淆根本原因。GraphQL會自動編排對其他服務的網路調用,從而隱藏用戶的複雜性。伺服器日誌提供了一種調試方法,但它們仍然是通過瀏覽器的網路選項卡從自然調試方法中刪除的一步。為了使調試更容易,我們將日誌直接添加到GraphQL響應有效負載,該負載公開了伺服器正在進行的所有網路請求。啟用調試標誌後,您將在客戶端瀏覽器中獲得與瀏覽器直接進行網路調用時相同的數據。

3.打破類型

傳遞對象是OOP的全部內容,但不幸的是,GraphQL打破了這種範式。當我們獲取部分對象時,就不能使用那些返回完整對象的方法和組件。當然,您可以手動轉換對象並希望獲得最佳效果,但是您會失去類型系統的許多好處。幸運的是,TypeScript使用duck typing,因此調整這些方法返回只需要的對象屬性。定義這些更精確的類型需要更多的工作,但總體上提供更大的類型安全性。

接下來是什麼

我們仍然處於探索GraphQL的早期階段,但到目前為止它是一次積極的體驗,我們很高興接受它。這項努力的關鍵目標之一是幫助我們在系統日益複雜的同時提高開發速度。我們希望投資graph 數據模型,以便隨著時間的推移,隨著更多邊緣和節點的增加,我們的團隊將更加高效,而不是陷入複雜的數據結構。即使在過去的幾個月里,我們發現現有的graph模型已經變得足夠強大,我們不需要任何graph 更改就可以構建一些功能。它確實使我們更有成效。

Netflix採用GraphQL的經驗分享

打開今日頭條,查看更多圖片
喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 程序員小新人學習 的精彩文章:

配置 redis 外網可訪問
詳解react、redux、react-redux之間的關係

TAG:程序員小新人學習 |