天天看點

基于 SOFAArk 和 SOFADashboard 實作動态子產品管控 | Meetup#2 回顧

作者:衛恒(宋國磊),SOFATracer 以及 SOFADashboard 開源負責人。

本文根據 5月26日 SOFA Meetup#2上海站 《使用 SOFAStack 快速建構微服務》主題分享整理,着重分享如何使用 SOFADashboard 來管控 SOFAArk ,對于 SOFAArk 中的一些基礎概念和知識不過多涉及;建議大家在閱讀之前,先了解下 SOFAArk 的相關基本知識。

現場回顧視訊以及 PPT 見文末連結。

基于 SOFAArk 和 SOFADashboard 實作動态子產品管控 | Meetup#2 回顧

前言

SOFAArk

 是一款基于 Java 實作的輕量級類隔離容器,主要提供類隔離和應用(子產品)合并部署能力,由螞蟻金服開源貢獻。

 在 

0.6.0 版本

提供了非常豐富的功能特性,其中最核心的當屬多應用(子產品)合并部署這個能力。

 本身提供了多種方式來支援多應用(子產品)合并部署 ,包括基于指令行的管控,基于 API 的管控等。本篇将結合 SOFA 開源的管控端元件 

SOFADashboard

,來實作 

 提供的合并部署和動态子產品推送的功能。

案例工程位址:

https://github.com/sofastack-guides/sofa-dashbaord-samples-parent

背景

複雜項目通常需要跨團隊協作開發,各自負責不同的元件,而衆所周知,協調跨團隊合作開發會遇到不少問題;比如各自技術棧不統一導緻的依賴沖突,又比如往同一個 Git 倉庫送出代碼常常導緻 merge 沖突。是以,如果能讓每個團隊将負責的功能元件當成一個個單獨的應用開發,運作時合并部署,通過統一的程式設計界面互動,那麼将極大的提升開發效率及應用可擴充性。SOFAArk 提出了一種特殊的包結構 -- Ark Biz,使用者可以使用 Maven 插件将應用打包成 Biz,允許多 Biz 在 SOFAArk 容器之上合并部署,并通過統一的程式設計界面互動。

基于 SOFAArk 和 SOFADashboard 實作動态子產品管控 | Meetup#2 回顧

案例模型

本篇所示範案例是上圖的一個簡化版,從整體上可以展現 SOFAArk多應用合并部署的能力。主要包括已經幾個工程:

  • sofa-dashboard-ark-hostapp : 宿主應用
  • sofa-dashboard-ark-facade   : 提供接口 API
  • sofa-dashboard-ark-provider :提供接口 API 的具體實作,将釋出一個 JVM 服務

sofa-dashboard-ark-hostapp 和 sofa-dashboard-ark-provider 均作為 SOFAArk 中的 ark-biz 存在;sofa-dashboard-ark-hostapp 作為宿主應用對外提供服務。

基于 SOFAArk 和 SOFADashboard 實作動态子產品管控 | Meetup#2 回顧

上圖的模型中,在宿主應用不重新開機的情況下,實作  provider 子產品的動态替換,進而實作版本更新。

在宿主應用啟動時,provider 1.0.0 以靜态合并部署方式“寄宿”到宿主應用中,這部分實際上與 SOFADashboard 管控是沒有什麼關系的,為了案例效果,在下面的案例中,關于靜态合并部署的操作也會涉及到。

最終的工程結構圖如下:

基于 SOFAArk 和 SOFADashboard 實作動态子產品管控 | Meetup#2 回顧

環境準備

本文需要啟動 SOFADashboard 服務端,具體請參考 : 

Quick Start

 ;其他基礎設施環境如 Zookeeper 、Mysql 等需提前準備。

工程建構

本篇将通過 step by step 的方式來建構整個工程,為大家在實際的應用過程中提供一種簡單的思路,同時也幫助大家更好的了解 SOFAArk 中的一些點。

sofa-dashboard-ark-facade

基礎 API 提供子產品,不需要依賴任何其他二方或者三方 JAR,這裡僅提供一個接口。

public interface SofaJvmService {
    String test();
}           

sofa-dashboard-ark-provider

這個子產品是 JVM 服務的提供方,也是後面需要在宿主應用中進行替換示範的子產品包,這個子產品本身也是一個 Web 應用。這裡就來一步步分解下,如何将一個普通的 SpringBoot 工程改造成一個 ark-biz 工程。

1、建立一個 SpringBoot 工程

建立 SpringBoot 工程推薦的方式有兩種,一種是在 

https://start.spring.io/

  進行下載下傳,另外一種是基于 IDEA 的 Spring 插件來生成;此處不在過多描述過程。

2、工程基本能力實作

  • 引入 sofa-dashboard-ark-facade 依賴,先将需要提供的 JVM 服務實作:
@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           

3、配置打包插件,将應用打包成 ark-biz

根據官方文檔,可以使用 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>           

4、工程依賴

從前面背景介紹中的設計理念圖中可以看出,動态合并部署需要依賴的插件核心有兩個,一個是 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>
           

5、編譯打包

執行 mvn clean package ,之後會在目前子產品的 target 目錄下生成 xxx-ark-biz.jar 的包。

基于 SOFAArk 和 SOFADashboard 實作動态子產品管控 | Meetup#2 回顧

sofa-dashboard-ark-host

前面已經建構好了所需要的一些基礎工程,sofa-dashboard-ark-host 作為宿主應用,期望其具備的能力有以下幾個:

  • 提供可以直覺的 check 子產品變更後的結果
  • 提供能夠給 provider 1.0.0 版本 ark-biz 包運作的宿主環境
  • 能夠通過 SOFAArk 提供的狀态 endpoint 檢視插件狀态
  • 能夠支援 Zookeeper 下發指令,控制 Biz 的生命周期

基于以上幾點功能,下面來分步驟實作。

1、提供一個簡單的 Rest 接口來 check 結果

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();
    }
}
           

2、作為宿主應用

  • ARK 容器配置

這部分可以先參考閱讀 

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>           

3、狀态檢視

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=*           

4、提供動态配置插件能力

SOFAArk 提供了 config-ark-plugin 對接 Zookeeper 配置中心,用于運作時接受配置,達到控制 Biz 生命周期,引入如下依賴:

<!-- 引用ark 配置推送擴充插件-->
<dependency>
        <groupId>com.alipay.sofa</groupId>
        <artifactId>config-ark-plugin</artifactId>
</dependency>           

參考 

,在 SOFAArk 配置檔案 conf/ark/bootstrap.properties 增加如下配置:

com.alipay.sofa.ark.config.address=zookeeper://localhost:2181           

靜态合并部署示範

基于上述所有的配置,将 host-app 打包,然後運作。

  • mvn clean install 
  • java -jar sofa-dashboard-ark-hostapp-1.0.0.jar

下面可以通過 SOFAArk 提供的 endpoint 來檢視下目前應用的 biz state 資訊:

基于 SOFAArk 和 SOFADashboard 實作動态子產品管控 | Meetup#2 回顧

這裡隻有宿主應用自身的 ark biz 狀态資訊,實際上我們使用了靜态合并部署。但是貌似 ark-biz 合并部署的包插件沒有在 bizState 中展現出來。通路下 

http://localhost:8085/test

 我們的 check  rest 服務:

基于 SOFAArk 和 SOFADashboard 實作動态子產品管控 | Meetup#2 回顧

提示出來沒有可用的 JVM 服務。

這裡有個點是并不會去激活裡面的 ark biz 包,需要通過通過 終端或者 API 的方式來進行激活,實際上隻是激活了宿主應用本身的 ark-biz。

通過 SOFADashboard 進行動态推送

SOFADashboard 進行推送的原理可以參考前面背景介紹中的描述。下面主要來介紹如何使用 SOFADashboard 進行動态子產品切換。

注冊插件

将 sofa-dashboard-ark-provider 這個 ark-biz 插件注冊到 SOFADashboard:

基于 SOFAArk 和 SOFADashboard 實作動态子產品管控 | Meetup#2 回顧

填寫插件的基本資訊:

基于 SOFAArk 和 SOFADashboard 實作動态子產品管控 | Meetup#2 回顧

注冊成功之後,子產品清單如下:

基于 SOFAArk 和 SOFADashboard 實作動态子產品管控 | Meetup#2 回顧

增加版本

點選添加版本,彈出新增版本表單,輸入版本資訊及目前版本對應的 ark biz 封包件位址;支援從檔案伺服器(http 協定)上拉取,也支援從本地檔案(File 協定)系統擷取。下面為了友善,使用從檔案系統中擷取,配置如下:

基于 SOFAArk 和 SOFADashboard 實作動态子產品管控 | Meetup#2 回顧

添加成功之後,插件清單如下:

基于 SOFAArk 和 SOFADashboard 實作動态子產品管控 | Meetup#2 回顧

關聯應用

基于 SOFAArk 和 SOFADashboard 實作動态子產品管控 | Meetup#2 回顧

點選插件清單後面的 關聯應用案例,将插件與應用進行關聯,如下:

基于 SOFAArk 和 SOFADashboard 實作動态子產品管控 | Meetup#2 回顧

詳情檢視

點選插件清單後面的詳情按鈕,可以檢視目前插件下所有應用資訊和應用執行個體資訊。

基于 SOFAArk 和 SOFADashboard 實作動态子產品管控 | Meetup#2 回顧

指令推送

SOFADashboard 提供兩種次元的指令推送:

  • 基于應用次元,目前應用所有的執行個體都會監聽到此指令變更;
  • 基于 IP 次元,分組次元的單 IP 場景。

下面示範基于 IP 次元的推送:

1、安裝

點選安裝,安裝過程中,插件狀态會發生變化, RESOLVED 狀态為正在解析。

基于 SOFAArk 和 SOFADashboard 實作動态子產品管控 | Meetup#2 回顧

延遲 1~3s 之後,狀态變為  ACTIVATED 狀态:

基于 SOFAArk 和 SOFADashboard 實作動态子產品管控 | Meetup#2 回顧

再次通路下 

 我們的 check rest 服務:

基于 SOFAArk 和 SOFADashboard 實作動态子產品管控 | Meetup#2 回顧

實作了在不重新開機宿主應用的情況下,實作了内部業務邏輯的變更。

2、版本切換

子產品版本 1 運作一段時間之後,出現新的需求,希望更改下子產品版本 1 中的一些邏輯。在未使用動态子產品的情況下,一般就需要新拉一個疊代,然後将原有的邏輯修改,然後釋出上線。可能是一個非常小的功能點,但是卻需要走複雜的釋出流程。

這個就可以借助動态子產品的方式來實作版本的動态切換。修改 sofa-dashboard-ark-provider  子產品邏輯實作,更新版本,重新打包 sofa-dashboard-ark-provider 。

在 SOFADashboard ,新增 2.0.0 版本,并且配置指定的版本 ark-biz 包的檔案位址。添加成功之後如下:

基于 SOFAArk 和 SOFADashboard 實作動态子產品管控 | Meetup#2 回顧

進入詳情界面,切換版本到 2.0.0:

基于 SOFAArk 和 SOFADashboard 實作動态子產品管控 | Meetup#2 回顧

執行安裝,此時版本 2.0.0 狀态将會變為非激活狀态:

基于 SOFAArk 和 SOFADashboard 實作動态子產品管控 | Meetup#2 回顧

執行點選激活按鈕進行激活,延遲 1~3s 之後,狀态變更為激活狀态:

基于 SOFAArk 和 SOFADashboard 實作動态子產品管控 | Meetup#2 回顧
基于 SOFAArk 和 SOFADashboard 實作動态子產品管控 | Meetup#2 回顧

可以看到,版本 2.0.0 中的邏輯已經生效了;切回到 1.0.0 ,此時 1.0.0 的狀态變成了非激活狀态:

基于 SOFAArk 和 SOFADashboard 實作動态子產品管控 | Meetup#2 回顧

小結

本文分享了基于 SOFAArk 和 SOFADashboard 實作動态子產品管控的能力。動态子產品在實際業務中有非常豐富的場景,對主應用不發版,不重新開機的情況下實作具體子產品的功能變更;在此基礎上也可以實作版本灰階的能力。

本案例中,provider 也是一個獨立的應用,其作為一個子子產品在宿主應用 hostapp 中啟動,是以也可以基于 SOFABoot 這種能力來實作多 Web 應用的合并部署的能力。

以上就是本次分享的全部内容。

SOFA Meetup 上海站回顧資料

現場回顧視訊以及 PPT 位址:

http://t.cn/AiKlmCmE

繼續閱讀