原文:http://www.infoq.com/cn/news/2017/12/why-service-mesh
摘要:
對 Service Mesh 的理解?它的出現最終是為了解決什么問題?
Service Mesh 這個詞本身出現的時間確實不長,但是它所描繪的事情存在的時間可不短,其本質就是分布式系統的動態鏈接過程,眼下最大眾化的分布式系統就是微服務,所以可以簡單地說,Service Mesh 就是微服務的動態鏈接器(Dynamic Linker)。
讓我們回憶一下單機程序的運作方式,源代碼被編譯器編譯為一系列目標文件,然后交由鏈接器將這些目標文件組裝成一個可執行文件,鏈接過程就是將各個目標文件之間對符號(方法、變量、函數、接口等)的引用轉化為對內存地址的引用,由於這個過程在生成可執行文件時就完成了,所以被稱為靜態鏈接。
后來為了程序的模塊化和功能上的解耦與共用,開始把一些常見的公共程序剝離出來,制作成庫文件供其他程序使用,在引用這些庫文件的程序運行時,操作系統上的動態鏈接器會在庫文件中查詢到被引用的符號,然后將這些符號的內存地址映射到該程序的虛擬內存空間之中,由於這個過程是在程序運行時完成的,所以被稱為動態鏈接。
再后來出現了分布式系統,程序被散布在網絡中的不同主機上,那么如何鏈接這些程序呢?業界走過了和鏈接單機程序類似,但是卻艱難得多的一段歷程。因為這個訪談是在微服務的大背景下進行的,為了敘述方便,我們從現在開始把這些程序稱為服務。業界最開始是把這些服務的網絡地址寫在配置文件中,這個方案顯然問題太多、很不靠譜。所以接下來自然而然地出現了服務注冊中心來統一記錄這些服務的網絡地址並維護這些地址的變化,服務通過注冊中心提供的客戶端 SDK 與注冊中心通信並獲得它們所依賴的服務的網絡地址。由於網絡通信遠沒有內存通信穩定,為了保證可靠的服務調用,又出現了用於流量控制的 SDK,提供流量監控、限流、熔斷等能力。
在大型系統中,被依賴的服務往往以多實例的方式運行在多個主機上,有多個網絡地址,所以又出現了用於負載均衡的SDK。現在問題貌似是解決了,但是我們手里多了一堆 SDK,我們手上已有的應用,必須用這些 SDK 重新開發,這顯然可行度不高,而對於新開發的應用,我們又發現這些 SDK 體積過大,以 Netflix OSS 提供的 SDK 為例,依賴包動輒上百兆,在做微服務開發時,經常發現 SDK 的體積比程序本身還大很多倍,如果你使用容器技術,你會發現你的程序和基礎容器的體積加起來還沒 SDK 大,所以經常有人吐槽說現在的這些所謂的微服務框架實際上不是為微服務設計的。另外,SDK 還會帶來性能伸縮性的問題,在性能要求較高的系統中,SDK 往往成為了性能瓶頸。再回頭看一下單機上動態鏈接過程的順暢,這種基於 SDK 的微服務動態鏈接方案簡直是難用的不得了。
這時業界才開始關注已經存在了一段時間的 Service Mesh 方案,Service Mesh 的基礎是一個網絡代理,這個網絡代理會接管微服務的網絡流量,通過一個中央控制面板進行管理,將這些流量轉發到該去的地方,並在這個代理的基礎之上,擴展出一系列的流量監控、限流、熔斷甚至是灰度發布、分布式跟蹤等能力,而不需要應用本身做出任何修改,讓開發者擺脫了SDK 之苦,也避免了由於 SDK 使用不當造成的一系列問題,同時這個代理工作在網絡層,一般情況下也不會成為性能瓶頸。怎么樣,是不是有一些單機上動態鏈接過程的感覺了?
Service Mesh 的開源解決方案
主要就是由 Buoyant 公司推出的 Linkerd 和 Google、IBM 等廠商牽頭的 Istio。Linkerd 更加成熟穩定些,Istio 功能更加豐富、設計上更為強大,社區相對也更加強大一些。
未來展望
在我看來,在三到五年之后,Kubernetes 會成為服務器端的標准環境,就像現在的 Linux,而 Service Mesh 就是運行在 Kubernetes 上的分布式應用的動態鏈接器,屆時開發一個分布式應用將會像開發單機程序一樣簡單,業界在分布式操作系統上長達三十多年的努力將以這種方式告一段落。
