十年阿里頂級架構師教你怎么使用Java來搭建微服務


 

微服務背后的大理念是將大型、復雜且歷時長久的應用在架構上設計為內聚的服務,這些服務能夠隨着時間的流逝而演化。本文主要介紹了利用 Java 生態系統構建微服務的多種方法,並分析了每種方法的利弊。

 

快速預覽

在 Java 生態系統中構建微服務的策略主要有:container-less, self-contained 和 in-container;

 Container-less 微服務把應用程序及其所有依賴打包成單一的 jar 文件;

 Self-contained 微服務也會將應用及其依賴打包成單一的Jar文件,但它還包含可能含有第三方庫的嵌入式框架;

 In-container 微服務會打包一個完整的 Java EE 容器,並且它的服務是在 Docker image 中實現。

 基於微服務的架構設計是架構師和程序員們面臨的一項新挑戰。然而,隨着語言及工具的不斷更新,架構師們完全有能力征服這樣的挑戰。Java 也不例外,本文探討了使用Java生態系統來構建微服務的幾種不同方式。

 

介紹

本文不會討論微服務的好與壞,也不會建議你提前為微服務設計應用程序,或當它們出現在你龐大的應用中時,是否應該剝離這些微服務。

 本文介紹的方法並不是唯一的,但應該可以達到拋磚引玉的效果。盡管本文的重點是使用 Java 生態系統來構建微服務,但這些概念同樣可以轉移到其它語言和技術中。

 筆者把本文用到的方法命名為 container-less、self-contained 和 in-containe。這些名稱或許不是非常正式,但足以區分相互間的差別。接下來,筆者會詳細描述每種方法。

 

Container-less

在此方法中,開發者會將 JVM 之上的任何事物視為應用程序的一部分。

 container-less 方法會啟用所謂的單 jar 部署(也可稱作“fat jar部署”),這也就意味着,應用程序及其所有依賴都會被打包成單一的jar文件,並且作為獨立的Java進程運行。

 

 

$java -jar myservice.jar

該方法的第一個優點就是當對應用的規模進行伸縮時,服務很容易按需求快速啟動和停止;另一優點是方便部署,你只需要傳遞一個 jar 文件即可。

 該方法的缺點就是庫的兼容性。對於事務支持這類問題,你需要自己來實現,或必須引入第三方庫才能實現。而后,如果你需要更多支持,例如持續性問題的支持,你就需要解決第三方庫之間的兼容性問題。

 

Self-contained

另一種單 jar 部署就是使用一個嵌入式框架來構建服務。在此方法中,框架提供了所需服務的實現方法,開發者可以選擇在項目中包括哪些服務。

 你可能會認為這個方法與 container-less 完全一樣,但筆者認為,兩者的區別在於,self-contained 方法會提供一套相互兼容的第三方庫。所以,該方法不存在庫兼容性問題。

 

 該方法可能涉及 Spring Boot、Wildfly Swarm 之類的工具。

 

Spring Boot

在Java中, Spring Boot 和 Spring Cloud Netflix 項目對構建微服務提供了很好的支持。 Spring Boot 允許你選擇各種 Spring 工具和其它流行的工具,然后把它們和你的應用打包成一個 jar 文件。 Spring Initializr 提供了一個簡單的復選框列表來完成上面這些事。一個簡單的Hello World服務示例如下: Gist Snippet

 

Wildfly Swarm

在 Java EE 中,和 Spring Boot 相對應是 Wildfly Swarm 。它允許你根據自己的需求挑選 Java EE 規范,然后把它們和你的應用程序打包成一個 jar 文件。這里有一個簡單的 Hello World 示例: Gist Snippet 。

 self-contained 方法的優點是你可以自主選擇用於服務運行的項目。

 這種方法的缺點是配置更加復雜,由於它在實際的服務中構建所需的容器功能,由此產生的 jar 文件也會稍大一些。

 

In-container

雖然在 Java EE 容器中部署微服務的開銷似乎很大,然而,一些開發者認為,微服務中的“微”並不表示該服務的小或者簡單。

 

 在這些案例中,將 Java EE 容器作為所需平台似乎是合適的。因此,你唯一需要的依賴就是 Java EE API 。注意,由於該依賴的實現是由容器提供的,因此該依賴項已經滿足了,這也就意味着所產生的 war 文件是非常精簡的,該服務的實現與上面 Wildfly Swarm 的例子是一樣的: Gist Snippet 。

 該方法的優點是,容器通過標准 API 提供了經過測試和驗證的標准功能的實現。因此,開發者可以完全聚焦於業務功能,並在應用代碼之外維護底層代碼。

 另一個優點是,應用程序代碼不依賴 Java EE 應用服務器,無論該應用部署到 GlassFish 、 WildFly 、 WebLogic 、 WebSphere 還是任何與 Java EE 兼容的其他實現系統。

 該方法的缺點是你需要把服務部署到容器中,這樣就增加了部署的復雜性。

 

Docker

現在來談談 Docker 。通過把 Java EE 容器和服務實現打包到 Docker 鏡像,你可以得到與單一 jar 部署相似的結果。唯一的不同是服務打包在 Docker 鏡像中,而不是在 jar 文件中。

 DockerfileFROM jboss/wildfly:9.0.1.FinalADD myservice.war/opt/jboss/wildfly/standalone/deployments

 在 Docker 引擎中啟動 Docker 鏡像可以喚醒服務:

 $ dockerrun-it-p8081:8080myorganization/myservice

 

Snoop

細心的讀者可能已經在先前的 Spring Boot 代碼段中注意到了 @EnableEurekaClient 注解。該注解在 Eureka 中注冊服務,使其能夠被服務消費者發現。 Eureka 是 Spring Cloud Netflix 包的一部分,並且是一個極易使用和配置服務發現的解決方案。

 Java EE 在外部並沒有提供這樣的功能,但是有一些開源解決方案可以使用,其中一個就是 Snoop , 它的功能與Eureka相似 。要使 Java EE 微服務支持任務查找,唯一要做的是使用 @EnableSnoopClient 注解,如本例所示: Gist Snippet 。

 

總結

在構建微服務時, Java 是一個非常好的選擇。本文中介紹的任何一種方法都可以實現微服務。當然,最好的方法還是根據服務需求而定。對於簡單的服務, container-less 或者 self-contained 服務就是不錯的選擇。不過,借助 in-container ,開發者可以更快更簡單地實現更高級的服務。無論針對哪種服務,Java 生態系統都能提供行之有效的實現方法。

 

寫在最后:歡迎留言討論,歡迎關注,持續更新!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM