微服務從設計到部署(一)微服務簡介

来源:http://www.cnblogs.com/oopsguy/archive/2017/08/28/7442408.html
-Advertisement-
Play Games

目前微服務受到很多關註:文章、博客、社交媒體上的討論和會議演講。他們正在迅速走向加德納技術成熟度曲線(Gartner Hype cycle)的高峰。與此同時,也有持懷疑態度的軟體社區人員認為微服務沒什麼新鮮可言。反對者聲稱它的思想只是面向服務架構(SOA)的重塑。然而,無論是炒作還是懷疑,不可否認微... ...


鏈接https://github.com/oopsguy/microservices-from-design-to-deployment-chinese
譯者Oopsguy

目前微服務受到很多關註:文章、博客、社交媒體上的討論和會議演講。他們正在迅速走向加德納技術成熟度曲線(Gartner Hype cycle)的高峰。與此同時,也有持懷疑態度的軟體社區人員認為微服務沒什麼新鮮可言。反對者聲稱它的思想只是面向服務架構(SOA)的重塑。然而,無論是炒作還是懷疑,不可否認微服務架構模式具有非常明顯的優勢——特別是在實施敏捷開發和複雜的企業應用交付方面。

本章節是七章之中介紹關於的設計、構建和部署微服務方面的內容。您將瞭解微服務的由來和與傳統單體應用模式的比較。這本電子書描述了許多關於微服務架構方面的內容。無論是對您的項目的意義,或者是如何去應用它,您都將瞭解到微服務架構模式的優點和缺點。

我們先來看看為什麼要考慮使用微服務。

1.1、構建單體應用

我們想一下,您開始製作一個新的打車應用,打算與 Uber 和 Hailo 競爭。經過初步交流與需求收集,您將手動或者使用類似 Rails、Spring Boot、Play或者Maven等平臺來生成一個新項目。

這個新應用是一個模塊化的六邊形架構,如圖 1-1 所示:

圖 1-1、一個簡單的打車應用

應用程式的核心是由模塊實現的業務邏輯,它定義了服務、領域對象和事件。圍繞核心的是與外部世界介面對接的適配器。適配器示例包括了資料庫訪問組件、生產和消費消息的消息組件和 web 組件,它們暴露了 API 或者實現了一個 UI。

儘管有一個邏輯模塊化的架構,但應用程式被作為一個整體進行打包和部署。實際格式取決於應用程式的語言和框架。例如,許多 Java 應用程式被打包成 WAR 文件並部署在如 Tomcat 或者 Jetty 之類的應用伺服器上。其他 Java 應用程式是打包成自包含(self-contained)的可執行 JAR。類似地,Rails 和 Node.js 應用程式被打包為目錄層次結構。

以這種風格編寫的應用是很常見的。他們很容易開發,因為我們的 IDE 和其他工具專註於構建單個應用程式。這些應用程式也很容易測試。您可以通過簡單地啟動並使用如 Selenium 測試包來測試 UI 以輕鬆地實現端到端(end-to-end)測試。單體應用同樣易於部署。你只需拷貝打包好的應用程式到伺服器。您還可以通過運行多個副本和結合負載均衡器來擴展應用。在項目的早期階段,它運作良好。

1.2、走向單體地獄

不幸的是,這種簡單的方法有很大的局限性。成功的應用有一個趨勢,隨著時間推移而變得越來越臃腫。在每個衝刺時期,您的開發團隊實現了更多的用戶需求,這意味著添加了許多行代碼。幾年之後,您的小而簡單的應用將會逐漸成長為龐然大物似的單體。為了給出一個極端的示例,我最近和一位開發者做了交談,他正在編寫一個工具用於從他們的數百萬行代碼(lines of code,LOC)應用中分析數千個 JAR 之間的依賴。我相信這是大量開發者在多年齊心協力下創造了這樣的野獸。

一旦您的應用程式成為了一個龐大、複雜的單體,您的開發組織可能陷入了一個令人痛苦的世界。敏捷開發和交付的任何一次嘗試都將原地徘徊。一個主要問題是應用程式實在是非常複雜。對於任何一個開發人員來說,這是在太大了,這是可以理解的。最終,正確地修複 bug 和實現新功能變得非常困難且耗時。此外,這個趨勢就像是往下的螺旋。如果基本代碼難以理解,那麼改變將不會變得正確。您最終得到的是一個巨大且不可思議的大泥球

應用程式的規模也將減緩發展。應用程式越大,啟動的時間越長。我調查過開發者們的單體應用的大小和性能,一些報告的啟動時間為 12 分鐘。我也聽說過應用程式啟動需要 40 分鐘以上的怪事。如果開發人員經常要重啟應用伺服器,那麼很大一部分時間都是在等待中度過,他們的生產力將受到限制。

另一個大問題是,複雜的單體應用本身就是持續部署的障礙。如今,SaaS 應用發展到了每天可將變更推送到生產中多次。這對於複雜的單體非常困難,因為您必須重新部署整個應用程式才能更新其中任何一部分。這對我之前提到的漫長的啟動時間也不會有什麼幫助。此外,因為變化的影響通常不是很清楚,您很可能需要做大量的手工測試。因此,持續部署是不可能做到的。

當不同模塊存在資源需求衝突時,單體應用也可能難以擴展。例如,一個模塊可能會執行 CPU 密集型圖像處理邏輯,理想情況下是部署在 Amazon EC2 Compute Optimized 實例中。另一個模塊可能是記憶體資料庫,最適合 EC2 Memory-optimized 實例。然而,因為這些模塊被部署在一起,您必須在硬體選擇上做出妥協。

單體應用的另一個問題是可靠性。因為所有模塊運行在同一進程。任何模塊的一個 bug,比如記憶體泄漏,可能會拖垮整個進程。此外,由於應用程式的所有的實例都是相同的,該錯誤將影響到整個應用的可用性。

最後但並非是最不重要的,單體應用使得採用新的框架和語言變得非常困難。例如,我們假設您有 200 萬行代碼使用了 XYZ 框架編寫。使用較新的 ABC 框架來重寫整個應用,這將是非常昂貴的(在時間和成本方面),即使那個框架非常好。因此,這對於採用新技術是一個非常大的障礙。您在項目開始時無論選擇何種新技術都將會感到困擾。

總結一下:您有一個成功的關鍵業務應用程式,它已經發展成為一個只有少數開發人員(如果有的話)能夠理解的巨大單體。它使用了過時、非生產性技術編寫的,這使得招聘優秀開發人員變得困難。應用程式難以擴展,不可靠。因此敏捷開發和應用交付是不可能的。

那麼您能做些什麼呢?

1.3、微服務-解決複雜問題

許多組織,如 Amazon、eBay 和 Netflix,已經採用現在所謂的微服務架構模式解決了這個問題,而不是構建一個臃腫的單體應用。它的思路是將您的應用程式分解成一套較小的互連服務。

一個服務通常實現了一組不同的特性或者功能,例如訂單管理、客戶管理等。每一個微服務都是一個迷你應用,它自己的六邊形架構包括業務邏輯以及多個適配器。

一些微服務會暴露一個供其他微服務或應用客戶端消費的 API。其他微服務可能實現了一個 web UI。在運行時,每個實例通常是一個雲虛擬機(virtual machine,VM)或者一個 Docker 容器。

例如,前面描述的系統可能分解成如圖 1-2 所示:

圖 1-2、一個單體應用分解成微服務

應用程式的每個功能區域現在都由自己的微服務實現。此外,Web 應用程式被分為一組更簡單的 Web 應用程式。例如,以我們的出粗車為例,一個專門是乘客的,一個專門是司機的。這使得它更容易地為特定的用戶、司機、設備或者專門的用例部署不同的場景。每個後端服務暴露一個 REST API,大部分的服務消費由其他服務提供的 API。例如,司機管理使用了通知伺服器來告知一個可用司機關於一個潛在路程。UI 服務調用了其他服務來渲染頁面。服務也可以使用非同步、基於消息的通信。本電子書後面將會詳細介紹服務間的通信。

一些 REST API 也暴露給移動端應用供司機和乘客使用。然而,應用不能直接訪問後端服務。相反,他們之間的通信是由一個稱為 API 網關(API Cateway)的中介負責。API 網關負責負載均衡、緩存、訪問控制、API計量和監控,可以通過使用 NGINX 來實現。第 2 章詳細討論 API 網關。

圖 1-3、開發和交付中的縮放立方(Scale Cube)

微服務架構模式相當於此縮放立方的 Y 軸坐標,此立方是一個來自《架構即未來》的三維伸縮模型。另外兩個坐標軸是由運行多個相同應用程式副本的負載均衡器組成的 X 軸縮放和 Z 軸坐標(或者數據分區),其中請求的屬性(例如,一行記錄的主鍵或者客戶標識)用於將請求路由到特定的伺服器。

應用程式通常將這三種類型的坐標方式一起使用。Y 軸坐標將應用分解成微服務,如圖 1-2 所示。

在運行時,X 坐標軸上運行著服務的多個實例,每一個服務配合負載均衡器以滿足吞吐量和可用性。某些應用程式也有可能使用 Z 坐標軸來進行分區服務。圖 1-4 展示瞭如何用 Docker 將旅途管理(Trip Management)服務部署到 Amazon EC2 上運行。

圖 1-4、使用 Docker 部署旅途管理服務

在運行時,旅途管理服務由多個服務實例組成,每個服務實例是一個 Docker 容器。為了實現高可用,容器是在多個雲虛擬機上運行的。服務實例的前方是一個如 NGINX 的負載均衡器,用於跨實例分發請求。負載均衡器也可以處理其他問題,如緩存訪問控制API 度量監控

微服務架構模式明顯影響到了應用程式與資料庫之間的關係。與與其他共用單個資料庫模式(schema)服務不同,每一個服務都有自己的資料庫模式。一方面,這種做法是與企業級資料庫數據模型的想法不符,此外,它經常導致一些數據冗餘。然而,如果您想從微服務中受益,每一個服務都應該有自己的資料庫模式。因為它做到了松耦合。圖 1-5 展示了資料庫架構示例應用程式。

每個服務都有自己的資料庫。而且,服務可以使用一種最適合其需求、號稱多語言持久架構(polyglot persistence architecture)的資料庫。例如,司機管理,找到與潛在乘客接近的司機必須使用支持高效地理查詢的資料庫。

圖 1-5、打車應用的資料庫架構

從錶面上看,微服務架構模式類似於 SOA。微服務是由一組服務組成。然而,換另一種方式去思考微服務架構模式,它是沒有商業化的 SOA,沒有集成 Web 服務規範(WS-*)和企業服務匯流排(Enterprise Service Bus,ESB)。基於微服務的應用支持更簡單、輕量級的協議,例如,REST,而不是 WS-*。他們也儘量避免使用 ESB,而是實現微服務本身具有類似 ESB 的功能。微服務架構也拒絕了 SOA 的其他部分,例如,數據訪問規範模式概念。

1.4、微服務的優點

微服務架構模式有許多非常好的地方。第一,它解決了複雜問題。它把可能會變得龐大的單體應用程式分解成一套服務。雖然功能數量不變,但是應用程式已經被分解成可管理的塊或者服務。每個服務都有一個以遠程過程調用(RPC)驅動或者消息驅動的 API 明確定義的邊界。微服務架構模式強制一定程度的模塊化,實際上,使用單體基礎代碼來實現是極其困難的。因此,個體服務能被更快地開發,並更容易理解與維護。

第二,這種架構使得每個服務都可以由一個團隊獨立專註開發。開發者可以自由選擇任何符合服務 API 契約的技術。當然,更多的組織是希望通過技術選型限制來避免完全混亂的狀態。然而,這種自由意味著開發人員不再有可能在這種自由的新項目開始時使用過時的技術。當編寫一個新服務時,他們可以選擇當前的技術。此外,由於服務比較小,使用當前技術重寫舊服務將變得更加可行。

第三,微服務架構模式可以實現每一個微服務獨立部署。開發人員根本不需要去協調部署本地變更到它們的服務。這些變更一經測試即可立即部署。比如,UI 團隊可以執行 A|B 測試,並快速迭代 UI 變更。微服務架構模式使得持續部署成為可能。

最後,微服務架構模式使得每個服務能夠獨立擴展。您可以僅部署滿足每個服務的容量和可用性約束的實例數目。此外,您可以使用與服務資源要求最匹配的硬體。例如,您可以在 EC2 Compute Optimized 實例上部署一個 CPU 密集型圖像處理服務,並且在 EC2 Memory-optimized 實例上部署一個記憶體資料庫服務。

1.5、微服務的缺點

就像 Fred Brooks 近 30 年前寫的《人月神話》說的,沒有銀彈。像其他技術一樣,微服務架構模式也是如此,存在著缺點。其中一個缺點就是名稱本身。微服務這個術語的重點過多偏向於服務的規模。事實上,有些開發者主張構建極細粒度的 10-100 LOC(代碼行) 服務雖然小型服務可能比較好,但重要的是要記住,小型服務只是一種手段,而不是主要目標。微服務的目標在於充分分解應用程式以方便應用敏捷開發和部署。

微服務另一個主要的缺點是由於微服務是一個分散式系統而變得複雜。開發者需要選擇和實現基於消息或者 RPC 的進程間通信機制。此外,由於目標請求可能很慢或者不可用,他們還必須編寫代碼來處理部分故障。雖然這些都不是很複雜高深的事,但模塊間通過語言級方法/過程調用相互調用,這比單體應用要複雜得多。

微服務的另一個挑戰是分區資料庫架構。更多多個業務實體的業務事務是相當普遍的。這些事務在單體應用中的實現顯得微不足道,因為只有一個單獨的資料庫。在基於微服務的應用程式中,您需要更新不同服務所有用的資料庫。通常不會選擇分散式事務,不僅僅是因為 CAP 定理。他們根本不支持如今高度可擴展的 NoSQL 資料庫和消息代理。您最後不得不使用最終基於一致性的方法,這對於開發人員來說更具挑戰性。

測試微服務應用程式也很複雜。例如,使用現代的框架如 Sprig Boot,只需要編寫一個測試類來啟動一個單體 web 應用程式並測試其 REST API。相比之下,一個類似的測試類對於微服務來說需要啟動該服務及其所依賴的任何服務,或者至少為這些服務配置存根。再次聲明,雖然這不是一件高深的事情,但不要低估了這樣做的複雜性。

微服務架構模式的另一個主要的挑戰是實現了跨越多服務變更。例如,我們假設您正在實現一個變更服務 A、B 和 C 的需求,其中 A 依賴於 B,並且 B 依賴於 C。在單體應用程式中,您可以簡單地修改相應的模塊、整合變更並一次性部署他們。相反,在微服務中您需要仔細規劃和協調出現的變更到每一個服務。例如,您需要更新服務 C,然後更新服務 B,最後更新服務 A。幸運的是,大多數變更只會影響一個服務;需要協調的多服務變更相對較少。

部署基於微服務的應用程式也是非常地複雜。一個單體應用可以很容易地部署到基於傳統負載均衡器的一組相同的伺服器上。每個應用程式實例都配置有基礎設施服務的位置(主機和埠),比如資料庫和消息代理。相比之下,微服務應用程式通常由大量的服務組成。例如,據 Adrian Cockcroft,Hailo 擁有 160 個不同的服務,Netflix 擁有超過 600 個服務。

每個服務都有多個運行時實例。還有更多的移動部件需要配置、部署、擴展和監控。此外,您還需要實現服務發現機制,使得服務能夠發現需要與之通信的任何其他服務的位置(主機和埠)。傳統比較麻煩的基於票據(ticket-based)和手動操作方式無法擴展到如此複雜程度。因此,成功部署微服務應用程式要求開發人員能高度控制部署方式和高度自動化。

一種自動化的方式是使用現成的平臺即服務(PaaS),如 Cloud Foundry。PaaS 為開發人員提供了一種簡單的方式來部署和管理他們的微服務。它讓開發人員避開了諸如採購和配置 IT 資源等煩惱。同時,配置 PaaS 的系統與網路專業人員可以確保最佳實踐和落實公司策略。

自動化微服務部署的另一個方式是開發自己的 PaaS。一個普遍的起點是使用集群方案,如 Kubernetes,與 Docker 等容器技術相結合。在本書最後我們將看到基於軟體的應用交付方式如 NGINX 是如何在微服務級別處理緩存、訪問控制、API 計量和監控,可以幫助解決這個問題。

1.6、總結

構建複雜的微服務應用程式本質上是困難的。單體架構模式只適用於簡單、輕量級的應用程式,如果您使用它來構建複雜應用,您最終會陷入一個痛苦的世界。微服務架構模式是複雜、持續發展應用的一個更好的選擇。儘管它存在著缺點和實現挑戰。

在後面的章節中,我將介紹微服務架構的方方面面並探討諸如服務發現、服務部署方案以及將單體應用重構為服務的策略。

微服務實戰:NGINX Plus 作為反向代理伺服器

By Floyd Smith

10000 個網站中有超過 50% 使用 NGINX,這主要是因為它具有作為反向代理伺服器的能力。您可以 NGINX 放在當前應用程式前面甚至是資料庫伺服器以獲取各種功能 —— 更高的性能、更高的安全性、可擴展性、靈活性等。你現有的應用程式只需要配置代碼和作出很少或無需改變。對於存在性能壓力的站點,或者預計未來存在高負荷,效果看起來似乎沒那麼神奇。

那麼這與微服務有什麼關係呢?實現一個反向代理伺服器,並使用 NGINX 的其他功能來為您提供架構靈活性。反向代理伺服器、靜態和應用文件緩存、SSL/TLS 和 HTTP/2 都會從您的應用程式剔除。讓應用程式只做它該做的事,NGINX 還可作為負載均衡器,微服務實施過程中的一個關鍵角色。先進的 NGINX Plus 的功能包含了複雜的負載均衡演算法、多種方式的會話持久和管理監控,這些對微服務尤其有用(NGINX 最近還增加了使用 DNS SRV 記錄的服務發現支持,這是一個頂尖的功能)。而且,如本章所述,NGINX 可以自動化部署微服務。

此外,NGINX 還提供了必要的功能來支撐 NGINX 微服務參考架構中的三大模型。代理模型使用 NGINX 作為 API 網關;網格路由模型使用了一個額外的 NGINX 作為進程間通信中樞;Fabric 模型中每個微服務使用一個 NGINX 來控制 HTTP 流量,在微服務之間實現 SSL/TLS,這非常具有突破性。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 主要是想給想學習Flask框架的小伙伴一些完整的教程,幫助其更好的學習和掌握Flask框架。 ...
  • 工具類: ...
  • Phton3使用print輸出帶顏色的彩色字體 實現過程: 終端的字元顏色是用轉義序列控制的,是文本模式下的系統顯示功能,和具體的語言無關。 轉義序列是以ESC開頭,即用\033來完成(ESC的ASCII碼用十進位表示是27,用八進位表示就是033)。 書寫格式: 開頭部分:\033[顯示方式;前景 ...
  • 虛繼承主要用於菱形 形式的繼承形式 虛繼承是為了在多繼承的時候避免引發歧義, 比如類A有個就是a,B繼承了A,C也繼承了A,當D多繼承B,C時,就會有歧義產生了,所以要使用虛擬繼承避免重覆拷貝。 虛函數繼承是解決多態性的,當用基類指針指向派生類對象的時候,基類指針調用虛函數的時候會自動調用派生類的虛 ...
  • spring boot / cloud (六) 開啟CORS跨域訪問 前言 什麼是CORS? Cross origin resource sharing(跨域資源共用),是一個W3C標準,它允許你向一個不同源的伺服器發出XMLHttpRequest請求,從而剋服了ajax只能請求同源服務的限制.並且 ...
  • 為什麼將單例模式排名第一,很簡單,面試的時候聊到設計模式,大概率就從單例模式開始入手,循循漸進。 當然,我們學習單例模式不是為了去應付面試,而是學好設計模式後,融匯貫通,應用於我們的設計,開發,項目中。 單例模式是最簡單的設計模式之一 單例模式【Singleton Pattern】:保證一個類僅有一 ...
  • ## 業務場景寫一個數據層的loader,loader的數據拉取有可能走本地或者走網路,所以肯定需要通過回調來返回數據,而且兩種情況在view層的表現不一樣(一個顯示載入框一個不顯示),也需要通過回調來告知。## 優化前最簡單的做法是寫一個這樣的介面,把所有可能要做的事情都各寫一個方法,比如這樣:`... ...
  • 裝飾者模式類似於代理,你將一個對象傳進去裝飾類,它將此對象的同名方法做一些加強 1.要被修飾的父類 2.裝飾的父類 3.創建兩種被修飾的類 4.創建裝飾類 5.組合(把被修飾的類進行裝飾加強) 結果是這樣的: tip:這裡,你可以說,幹嘛這麼麻煩,繼承不就搞定了,但是,你有沒有想過,如果萬一有一點, ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...