做者:衛恆(宋國磊),SOFATracer 以及 SOFADashboard 開源負責人。
本文根據 5月26日 SOFA Meetup#2上海站 《使用 SOFAStack 快速構建微服務》主題分享整理,着重分享如何使用 SOFADashboard 來管控 SOFAArk ,對於 SOFAArk 中的一些基礎概念和知識不過多涉及;建議你們在閱讀以前,先了解下 SOFAArk 的相關基本知識。
現場回顧視頻以及 PPT 見文末連接。
SOFAArk 是一款基於 Java 實現的輕量級類隔離容器,主要提供類隔離和應用(模塊)合併部署能力,由螞蟻金服開源貢獻。SOFAArk 在 0.6.0 版本 提供了很是豐富的功能特性,其中最核心的當屬多應用(模塊)合併部署這個能力。SOFAArk 自己提供了多種方式來支持多應用(模塊)合併部署 ,包括基於命令行的管控,基於 API 的管控等。本篇將結合 SOFA 開源的管控端組件 SOFADashboard ,來實現 SOFAArk 提供的合併部署和動態模塊推送的功能。java
案例工程地址 :git
github.com/sofastack-g…github
複雜項目一般須要跨團隊協做開發,各自負責不一樣的組件,而衆所周知,協調跨團隊合做開發會遇到很多問題;好比各自技術棧不統一致使的依賴衝突,又好比往同一個 Git 倉庫提交代碼經常致使 merge 衝突。所以,若是能讓每一個團隊將負責的功能組件當成一個個單獨的應用開發,運行時合併部署,經過統一的編程界面交互,那麼將極大的提高開發效率及應用可擴展性。SOFAArk 提出了一種特殊的包結構 -- Ark Biz,用戶可使用 Maven 插件將應用打包成 Biz,容許多 Biz 在 SOFAArk 容器之上合併部署,並經過統一的編程界面交互。web
本篇所演示案例是上圖的一個簡化版,從總體上能夠體現 SOFAArk多應用合併部署的能力。主要包括已經幾個工程:spring
sofa-dashboard-ark-hostapp 和 sofa-dashboard-ark-provider 均做爲 SOFAArk 中的 ark-biz 存在;sofa-dashboard-ark-hostapp 做爲宿主應用對外提供服務。sql
上圖的模型中,在宿主應用不重啓的狀況下,實現 provider 模塊的動態替換,從而實現版本升級。編程
在宿主應用啓動時,provider 1.0.0 以靜態合併部署方式「寄宿」到宿主應用中,這部分實際上與 SOFADashboard 管控是沒有什麼關係的,爲了案例效果,在下面的案例中,關於靜態合併部署的操做也會涉及到。bootstrap
最終的工程結構圖以下:springboot
本文須要啓動 SOFADashboard 服務端,具體請參考 : Quick Start [5] ;其餘基礎設施環境如 Zookeeper 、Mysql 等需提早準備。bash
本篇將經過 step by step 的方式來構建整個工程,爲你們在實際的應用過程當中提供一種簡單的思路,同時也幫助你們更好的理解 SOFAArk 中的一些點。
基礎 API 提供模塊,不須要依賴任何其餘二方或者三方 JAR,這裏僅提供一個接口。
public interface SofaJvmService {
String test();
}複製代碼
這個模塊是 JVM 服務的提供方,也是後面須要在宿主應用中進行替換演示的模塊包,這個模塊自己也是一個 Web 應用。這裏就來一步步分解下,如何將一個普通的 SpringBoot 工程改形成一個 ark-biz 工程。
新建 SpringBoot 工程推薦的方式有兩種,一種是在 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 地址:t.cn/AiKlmCmE