做者:衛恆(宋國磊),SOFATracer 以及 SOFADashboard 開源負責人。java
本文根據 5月26日 SOFA Meetup#2上海站 《使用 SOFAStack 快速構建微服務》主題分享整理,着重分享如何使用 SOFADashboard 來管控 SOFAArk ,對於 SOFAArk 中的一些基礎概念和知識不過多涉及;建議你們在閱讀以前,先了解下 SOFAArk 的相關基本知識。git
現場回顧視頻以及 PPT 見文末連接。github
SOFAArk 是一款基於 Java 實現的輕量級類隔離容器,主要提供類隔離和應用(模塊)合併部署能力,由螞蟻金服開源貢獻。SOFAArk 在 0.6.0 版本 提供了很是豐富的功能特性,其中最核心的當屬多應用(模塊)合併部署這個能力。SOFAArk 自己提供了多種方式來支持多應用(模塊)合併部署 ,包括基於命令行的管控,基於 API 的管控等。本篇將結合 SOFA 開源的管控端組件 SOFADashboard,來實現 SOFAArk 提供的合併部署和動態模塊推送的功能。web
案例工程地址:https://github.com/sofastack-guides/sofa-dashbaord-samples-parentspring
複雜項目一般須要跨團隊協做開發,各自負責不一樣的組件,而衆所周知,協調跨團隊合做開發會遇到很多問題;好比各自技術棧不統一致使的依賴衝突,又好比往同一個 Git 倉庫提交代碼經常致使 merge 衝突。所以,若是能讓每一個團隊將負責的功能組件當成一個個單獨的應用開發,運行時合併部署,經過統一的編程界面交互,那麼將極大的提高開發效率及應用可擴展性。SOFAArk 提出了一種特殊的包結構 -- Ark Biz,用戶可使用 Maven 插件將應用打包成 Biz,容許多 Biz 在 SOFAArk 容器之上合併部署,並經過統一的編程界面交互。sql
本篇所演示案例是上圖的一個簡化版,從總體上能夠體現 SOFAArk多應用合併部署的能力。主要包括已經幾個工程:編程
sofa-dashboard-ark-hostapp 和 sofa-dashboard-ark-provider 均做爲 SOFAArk 中的 ark-biz 存在;sofa-dashboard-ark-hostapp 做爲宿主應用對外提供服務。 bootstrap
上圖的模型中,在宿主應用不重啓的狀況下,實現 provider 模塊的動態替換,從而實現版本升級。springboot
在宿主應用啓動時,provider 1.0.0 以靜態合併部署方式「寄宿」到宿主應用中,這部分實際上與 SOFADashboard 管控是沒有什麼關係的,爲了案例效果,在下面的案例中,關於靜態合併部署的操做也會涉及到。服務器
最終的工程結構圖以下:
本文須要啓動 SOFADashboard 服務端,具體請參考 : Quick Start ;其餘基礎設施環境如 Zookeeper 、Mysql 等需提早準備。
本篇將經過 step by step 的方式來構建整個工程,爲你們在實際的應用過程當中提供一種簡單的思路,同時也幫助你們更好的理解 SOFAArk 中的一些點。
基礎 API 提供模塊,不須要依賴任何其餘二方或者三方 JAR,這裏僅提供一個接口。
public interface SofaJvmService { String test(); }
這個模塊是 JVM 服務的提供方,也是後面須要在宿主應用中進行替換演示的模塊包,這個模塊自己也是一個 Web 應用。這裏就來一步步分解下,如何將一個普通的 SpringBoot 工程改形成一個 ark-biz 工程。
新建 SpringBoot 工程推薦的方式有兩種,一種是在 https://start.spring.io/ 進行下載,另一種是基於 IDEA 的 Spring 插件來生成;此處不在過多描述過程。
@SofaService @Service public class SofaJvmServiceImpl implements SofaJvmService { @Override public String test() { return "first version biz"; } }
NOTE: SofaService 的做用是將一個 Bean 發佈成一個 JVM 服務, 因此這裏須要加上 Spring 提供的 @Service 註解將 SofaJvmServiceImpl 標註爲一個 Bean。
spring.application.name=biz-ark-test server.port=8800 logging.path=./logs
根據官方文檔,可使用 sofa-ark-maven-plugin 插件將一個普通的工程打包成一個 ark biz 包。這裏直接給出本篇中工程的配置:
<plugin> <groupId>com.alipay.sofa</groupId> <artifactId>sofa-ark-maven-plugin</artifactId> <version>0.6.0</version> <executions> <execution> <!--goal executed to generate executable-ark-jar --> <goals> <goal>repackage</goal> </goals> <!--ark-biz 包的打包配置 --> <configuration> <!--是否打包、安裝和發佈 ark biz,詳細參考 Ark Biz 文檔,默認爲false--> <attach>true</attach> <!--ark 包和 ark biz 的打包存放目錄,默認爲工程 build 目錄--> <outputDirectory>target</outputDirectory> <!--default none--> <arkClassifier>executable-ark</arkClassifier> <!-- ark-biz 包的啓動優先級,值越小,優先級越高--> <priority>200</priority> <!--設置應用的根目錄,用於讀取 ${base.dir}/conf/ark/bootstrap.application 配置文件,默認爲 ${project.basedir}--> <baseDir>../</baseDir> </configuration> </execution> </executions> </plugin>
從前面背景介紹中的設計理念圖中能夠看出,動態合併部署須要依賴的插件核心有兩個,一個是 runtime plugin,一個是 config plugin(沒有涉及到 RPC 服務相關);因爲 provider 並非做爲宿主應用,其自己不須要具有動態配置的能力,所以這裏僅須要引入 runtime plugin 來爲當前 ark-biz 工程提供運行時環境便可。
<!-- runtime plugin --> <dependency> <groupId>com.alipay.sofa</groupId> <artifactId>runtime-sofa-boot-plugin</artifactId> </dependency> <!-- 其餘依賴 --> <dependency> <groupId>com.alipay.sofa</groupId> <artifactId>healthcheck-sofa-boot-starter</artifactId> </dependency> <dependency> <groupId>com.glmapper.bridge.boot</groupId> <artifactId>sofa-dashboard-ark-facade</artifactId> </dependency>
執行 mvn clean package ,以後會在當前模塊的 target 目錄下生成 xxx-ark-biz.jar 的包。
前面已經構建好了所須要的一些基礎工程,sofa-dashboard-ark-host 做爲宿主應用,指望其具有的能力有如下幾個:
基於以上幾點功能,下面來分步驟實現。
sofa-dashboard-ark-host 自己也是一個 Web 應用,因此在這個提供一個 Rest 接口,具體實現是經過@SofaReference 調用 provider ark-biz 包中發佈的 JVM 服務。
@RestController public class TestController { @SofaReference SofaJvmService sofaJvmService; @RequestMapping("test") public String test(){ return sofaJvmService.test(); } }
這部分能夠先參考閱讀 SOFAArk 配置。本案例中簡單配置了一份 ARK 容器的配置文件。
# log 日誌目錄 logging.path=./logs # 指定zookeeper 服務地址 com.alipay.sofa.ark.config.address=zookeeper://localhost:2181 # 指定宿主應用名 com.alipay.sofa.ark.master.biz=host-app
com.alipay.sofa.ark.master.biz 默認狀況下是宿主應用的 artifactId。若是這裏指定了名字,則在宿主應用的插件配置裏面須要使用此名字。
引入 sofa-ark-springboot-starter 、web-ark-plugin 以及 provider ark biz 包。
<!-- 引用ark starter--> <dependency> <groupId>com.alipay.sofa</groupId> <artifactId>sofa-ark-springboot-starter</artifactId> </dependency> <!-- 引用ark web插件--> <dependency> <groupId>com.alipay.sofa</groupId> <artifactId>web-ark-plugin</artifactId> </dependency> <!-- 引入 sofa-dashboard-ark-provider ark-biz ,這裏屬於靜態合併部署狀況--> <dependency> <groupId>com.glmapper.bridge.boot</groupId> <artifactId>sofa-dashboard-ark-provider</artifactId> <version>1.0.0</version> <classifier>ark-biz</classifier> </dependency>
<plugin> <groupId>com.alipay.sofa</groupId> <artifactId>sofa-ark-maven-plugin</artifactId> <version>0.6.0</version> <executions> <execution> <id>default-cli</id> <goals> <goal>repackage</goal> </goals> </execution> </executions> <configuration> <!--指定優先級--> <priority>100</priority> <!--指定baseDir--> <baseDir>../</baseDir> <!--bizName,這裏須要和 bootstrap 中指定的master.biz 配置保持一致,默認爲 artifactId--> <bizName>host-app</bizName> </configuration> </plugin>
SOFAArk 提供了 /bizState 這樣一個 endpoint 用來獲取當前插件的版本及狀態信息。這裏就在宿主應用中引入actuator 依賴並進行相關配置。
<!-- 引用 actuator --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
application.properties 中配置暴露全部端點。
management.endpoints.web.exposure.include=*
SOFAArk 提供了 config-ark-plugin 對接 Zookeeper 配置中心,用於運行時接受配置,達到控制 Biz 生命週期,引入以下依賴:
<!-- 引用ark 配置推送擴展插件--> <dependency> <groupId>com.alipay.sofa</groupId> <artifactId>config-ark-plugin</artifactId> </dependency>
參考 SOFAArk 配置,在 SOFAArk 配置文件 conf/ark/bootstrap.properties 增長以下配置:
com.alipay.sofa.ark.config.address=zookeeper://localhost:2181
基於上述全部的配置,將 host-app 打包,而後運行。
下面能夠經過 SOFAArk 提供的 endpoint 來查看下當前應用的 biz state 信息:
這裏只有宿主應用自身的 ark biz 狀態信息,實際上咱們使用了靜態合併部署。可是貌似 ark-biz 合併部署的包插件沒有在 bizState 中體現出來。訪問下 http://localhost:8085/test 咱們的 check rest 服務:
提示出來沒有可用的 JVM 服務。
這裏有個點是並不會去激活裏面的 ark biz 包,須要經過經過 終端或者 API 的方式來進行激活,實際上只是激活了宿主應用自己的 ark-biz。
SOFADashboard 進行推送的原理能夠參考前面背景介紹中的描述。下面主要來介紹如何使用 SOFADashboard 進行動態模塊切換。
將 sofa-dashboard-ark-provider 這個 ark-biz 插件註冊到 SOFADashboard:
填寫插件的基本信息:
註冊成功以後,模塊列表以下:
點擊添加版本,彈出新增版本表單,輸入版本信息及當前版本對應的 ark biz 包文件地址;支持從文件服務器(http 協議)上拉取,也支持從本地文件(File 協議)系統獲取。下面爲了方便,使用從文件系統中獲取,配置以下:
添加成功以後,插件列表以下:
點擊插件列表後面的 關聯應用案例,將插件與應用進行關聯,以下:
點擊插件列表後面的詳情按鈕,能夠查看當前插件下全部應用信息和應用實例信息。
SOFADashboard 提供兩種維度的命令推送:
下面演示基於 IP 維度的推送:
點擊安裝,安裝過程當中,插件狀態會發生變化, RESOLVED 狀態爲正在解析。
延遲 1~3s 以後,狀態變爲 ACTIVATED 狀態:
再次訪問下 http://localhost:8085/test 咱們的 check rest 服務:
實現了在不重啓宿主應用的狀況下,實現了內部業務邏輯的變動。
模塊版本 1 運行一段時間以後,出現新的需求,但願更改下模塊版本 1 中的一些邏輯。在未使用動態模塊的狀況下,通常就須要新拉一個迭代,而後將原有的邏輯修改,而後發佈上線。多是一個很是小的功能點,可是卻須要走複雜的發佈流程。
這個就能夠藉助動態模塊的方式來實現版本的動態切換。修改 sofa-dashboard-ark-provider 模塊邏輯實現,升級版本,從新打包 sofa-dashboard-ark-provider 。
在 SOFADashboard ,新增 2.0.0 版本,而且配置指定的版本 ark-biz 包的文件地址。添加成功以後以下:
進入詳情界面,切換版本到 2.0.0:
執行安裝,此時版本 2.0.0 狀態將會變爲非激活狀態:
執行點擊激活按鈕進行激活,延遲 1~3s 以後,狀態變動爲激活狀態:
再次訪問下 http://localhost:8085/test 咱們的 check rest 服務:
能夠看到,版本 2.0.0 中的邏輯已經生效了;切回到 1.0.0 ,此時 1.0.0 的狀態變成了非激活狀態:
本文分享了基於 SOFAArk 和 SOFADashboard 實現動態模塊管控的能力。動態模塊在實際業務中有很是豐富的場景,對主應用不發版,不重啓的狀況下實現具體模塊的功能變動;在此基礎上也能夠實現版本灰度的能力。
本案例中,provider 也是一個獨立的應用,其做爲一個子模塊在宿主應用 hostapp 中啓動,所以也能夠基於 SOFABoot 這種能力來實現多 Web 應用的合併部署的能力。
以上就是本次分享的所有內容。
現場回顧視頻以及 PPT 地址:http://t.cn/AiKlmCmE