1、導讀java
Spring Cloud基於Spring Boot開發,提供一套完整的微服務解決方案,具體包括服務註冊與發現,配置中心,全鏈路監控,API網關,熔斷器,遠程調用框架,工具客戶端等選項中立的開源組件,而且能夠根據需求對部分組件進行擴展和替換。git
Service Mesh,這裏以Istio(目前Service Mesh具體落地實現的一種,且呼聲最高)爲例簡要說明其功能。 Istio 有助於下降這些部署的複雜性,並減輕開發團隊的壓力。它是一個徹底開源的服務網格,能夠透明地分層到現有的分佈式應用程序上。它也是一個平臺,包括容許它集成到任何日誌記錄平臺、遙測或策略系統的 API。Istio的多樣化功能集使你可以成功高效地運行分佈式微服務架構,並提供保護、鏈接和監控微服務的統一方法。github
從上面的簡單介紹中,咱們能夠看出爲何會存在要把Spring Cloud體系的應用遷移到Service Mesh這樣的需求,總結下來,有四方面的緣由:docker
1. 功能重疊
來簡單看一下他們的功能對比:安全
從上面表格中能夠看到,若是從功能層面考慮,Spring Cloud與Service Mesh在服務治理場景下,有至關大量的重疊功能,從這個層面而言,爲Spring Cloud向Service Mesh遷移提供了一種潛在的可能性。網絡
2. 服務容器化
在行業當前環境下,還有一個趨勢,或者說是現狀。愈來愈多的應用走在了通往應用容器化的道路上,或者在將來,容器化會成爲應用部署的標準形態。並且不管哪一種容器化運行環境,都自然支撐服務註冊發現這一基本要求,這就致使Spring Cloud體系應用上容器的過程當中,存在必定的功能重疊,有可能爲後期的應用運維帶來必定的影響,而Service Mesh偏偏須要依賴容器運行環境,同時彌補了容器環境所欠缺的內容(後續會具體分析)。架構
3. 術業有專攻
從軟件設計角度出發,咱們一直在追求鬆耦合的架構,也但願作到領域專攻。例如業務開發人員但願我只要關心業務邏輯便可,不須要關心鏈路跟蹤,熔斷,服務註冊發現等支撐工具的服務;而平臺支撐開發人員,則但願個人代碼中不要包含任何業務相關的內容。而Service Mesh的出現,讓這種狀況成爲可能。app
4. 語言壁壘
目前而言Spring Cloud雖然提供了對衆多協議的支持,可是受限於Java技術體系。這就要求應用須要在同一種語言下進行開發(這不必定是壞事兒),在某種狀況下,不必定適用於一些工做場景。而從微服務設計考慮,不該該受限於某種語言,各個服務應該可以相互獨立,你們須要的是遵循通訊規範便可。而Service Mesh剛好能夠消除服務間的語言壁壘,同時實現服務治理的能力。負載均衡
基於以上四點緣由,當下環境,除了部分大多已經提早走在了Service Mesh實踐的道路上互聯網大廠之外(例如螞蟻金服的SOFASTACK),也有大部分企業已經開始接觸Service Mesh,而且嘗試把Spring Cloud構建的應用,遷移到Service Mesh中。框架
Spring Cloud向Service Mesh遷移,從咱們考慮而言大致分爲七個步驟,如圖所示:
1. Spring Cloud架構解析
Spring Cloud架構解析的目的在於肯定須要從當前的服務中去除與Service Mesh重疊的功能,爲後續服務替換作準備。咱們來看一個典型的Spring Cloud架構體系,如圖所示:
從圖中咱們能夠簡要的分析出,一個基於Spring Cloud的微服務架構,主要包括四部份內容:服務網關,應用服務,外圍支撐組件,服務管理控制檯。
服務網關涵蓋的功能包括路由,鑑權,限流,熔斷,降級等對入站請求的統一攔截處理。具體能夠進一步劃分爲外部網關(面向互聯網)和內部網關(面向服務內部管理)。
應用服務是企業業務核心。應用服務內部由三部份內容構成:業務邏輯實現,外部組件交互SDK集成,服務內部運行監控集成。
外圍支撐組件,涵蓋了應用服務依賴的工具,包括註冊中心,配置中心,消息中心,安全中心,日誌中心等。
服務管理控制檯面向服務運維或者運營人員,實現對應用服務運行狀態的實時監控,以及根據狀況須要可以動態玩成在線服務的管理和配置。
這裏面哪些內容是咱們能夠拿掉或者說基於Service Mesh(以Istio爲例)能力去作的?分析下來,能夠替換的組件包括網關(gateway或者Zuul,由Ingress gateway或者egress替換),熔斷器(hystrix,由SideCar替換),註冊中心(Eureka及Eureka client,由Polit,SideCar替換),負責均衡(Ribbon,由SideCar替換),鏈路跟蹤及其客戶端(Pinpoint及Pinpoint client,由SideCar及Mixer替換)。這是咱們在Spring Cloud解析中須要完成的目標:即肯定須要刪除或者替換的支撐模塊。
2. 服務改造
服務單元改造的目的在於基於第一步的解析結果,完成依賴去除或者依賴替換。根據第一步的分析結果服務單元改造分爲三步:
刪除組件,包括網關,熔斷器,註冊中心,負載均衡,鏈路跟蹤組件,同時刪除對應client的SDK;
替換組件,採用httpClient 的SDK支持http協議的遠程調用(原來在Ribbon中),由原來基於註冊中心的調用,轉變成http直接調用;
配置信息變動,修改與刪除組件管理的配置信息以及必要的組件交互代碼(根據實際應用狀況操做);
固然服務單元改造過程當中,還會涉及到不少的細節問題,都須要根據應用特色進行處理,這裏不作深刻分析。
3. 服務容器化
服務容器化是目前應用部署的趨勢所在。服務容器化自己有不少不一樣的方式,例如基於Jenkins的pipeline實現,基於docker-maven-plugin + dockerfile實現,固然還有不少不一樣的方式。這裏以Spring Cloud一個demo服務經過docker-maven-plugin+dockerfile實現說明爲例:
簡易的一個服務的Dockerfile以下所示:
ROM openjdk:8-jre-alpine ENV TZ=Asia/Shanghai \ SPRING_OUTPUT_ANSI_ENABLED=ALWAYS \ JAVA_OPTS="" \ JHIPSTER_SLEEP=0 RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone CMD echo "The application will start in ${JHIPSTER_SLEEP}s..." && \ sleep ${JHIPSTER_SLEEP} && \ java ${JAVA_OPTS} -Djava.security.egd=file:/dev/./urandom -jar /app.jar # java ${JAVA_OPTS} -Djava.security.egd=environment:/dev/./urandom -jar /app.@project.packaging@ EXPOSE 8080 ADD microservice-demo.jar /app.jar
文件中定義了服務端口以及運行命令。
Maven-docker-plugin的插件配置以下所示:
<build> <finalName>microservice-demo</finalName> <plugins> ...... <plugin> <groupId>com.spotify</groupId> <artifactId>docker-maven-plugin</artifactId> <version>1.2.0</version> <executions> <execution> <id>build-image</id> <phase>package</phase> <goals> <goal>build</goal> </goals> </execution> <execution> <id>tag-image</id> <phase>package</phase> <goals> <goal>tag</goal> </goals> <configuration> <image>${project.build.finalName}:${project.version}</image> <newName>${docker.registry.name}/${project.build.finalName}:${project.version}</newName> </configuration> </execution> <!--暫時不添加推送倉庫的配置--> </executions> <configuration> <dockerDirectory>${project.basedir}/src/main/docker</dockerDirectory> <imageName>${project.build.finalName}:${project.version}</imageName> <resources> <resource> <targetPath>/</targetPath> <directory>${project.build.directory}</directory> <include>${project.build.finalName}.${project.packaging}</include> </resource> </resources> </configuration> </plugin> </plugins> </build>
經過增長docker-maven-plugin,在執行mvn package的時候能夠加載Dockerfile,自動構建服務的容器鏡像(須要說明的前提是本地安裝docker運行環境,或者經過環境變量在開發工具中配置Docker的遠程鏈接環境),從而完成服務容器化改造。
4. 容器環境構建
容器環境決定這Service Mesh的部署形態,這裏不詳細描述容器環境的部署過程。感興趣的朋友,能夠參考https://github.com/easzlab/ku... 開源項目,提供了Kubernetes基於ansible的自動化部署腳本。咱們也建議選擇Kubernetes來構建容器環境。這裏說明容器環境構建的考慮因素:
· 集羣部署方案
集羣部署方案主要考慮多集羣,跨數據中心,存儲選擇,網絡方案,集羣內部主機標籤劃分,集羣內部網絡地址規劃等多方面因素。
· 集羣規模
集羣規模主要考慮etcd集羣大小,集羣內運行實例規模(用來配置ip範圍段),集羣高可用節點規模等因素。
基於以上兩點來考慮容器化環境的部署方案,關鍵是合理規劃,避免資源浪費。
5. Service Mesh環境構建
Service Mesh環境構建依賴於容器環境構建,主要考慮兩個方面,以Isito爲例:
· 部署插件
Istio部署插件須要根據須要的場景,考慮採用的插件完整性,例如prometheus,kiali,是否開啓TLS等,具體安裝選項能夠參考https://preliminary.istio.io/...。
· 跨集羣部署
依據容器環境考慮是否須要支持Isito的跨集羣部署方案.
6. 服務注入
服務注入用於將容器化的服務接入到Service Mesh的平臺中,目前主要有兩種方式。以Isito爲例說明,主要包括自動注入和手動入住。選擇手動注入的目的在於能夠根據企業內部上線流程,對服務接入進行人爲控制。而自動注入則可以更加快捷,方便。到此實際上已經完成服務遷移工做。
7. 服務管理控制檯
因爲Service Mesh目前而言,可能是基於聲明式的配置文件,達到服務治理的效果,所以沒法實時傳遞執行結果。基於這種緣由,須要一個獨立的Service Mesh的管理控制檯,一方面可以查看各個服務的運行狀態以及策略執行狀況,另一方面可以支持服務運行過程當中策略的動態配置管理。目前而言,能夠在Isito安裝過程當中選擇kiali做爲一個控制檯實現,固然將來也會有大量的企業提供專門的服務。
經過以上七個步驟,可以在必定程度上幫助企業應用,從Spring Cloud遷移到Service Mesh上,但遷移過程當中必然存在不斷踩坑的過程,須要根據應用特色,事前作好評估規劃。
Spring Cloud遷移到Service Mesh是否是百利而無一害呢?
首先,從容器化的環境出發,後續Knative,Kubernetes,Service Mesh必然會構建出一套相對完整的容器化PaaS解決方案,從而完成容器化PaaS支撐平臺的構建。Service Mesh將爲容器運行態提供保駕護航的做用。
其次,就目前Service Mesh的落地實現而言,對於一些特定需求的監測粒度有所欠缺,例如調用線程棧的監測(固然,從網絡層考慮,或者不在Service Mesh的考慮範圍以內),可是偏偏在不少服務治理場景的要求範圍之中。咱們也須要針對這種狀況,考慮實現方案。
最後,你們一直詬病的性能和安全問題。目前已經有所增強,可是依然被吐槽。
總體而言,Spring Cloud是微服務實現服務治理平臺的現狀,而Service Mesh倒是將來,固然也不能徹底取而代之,畢竟設計思路和側重點不一樣,是否遷移須要根據業務場景而定。
本文由博雲研究院原創發表,轉載請註明出處。