建立一個工程,包含3個子產品

父工程裡面的配置
父工程的Pom檔案,管理版本
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<packaging>pom</packaging>
<modules>
<module>dynamic-stock-mng</module>
<module>dynamic-provider</module>
<module>dynamic-facade</module>
</modules>
<parent>
<groupId>com.alipay.sofa</groupId>
<artifactId>sofaboot-dependencies</artifactId>
<version>3.2.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>io.sofastack</groupId>
<artifactId>sofachannel-demo</artifactId>
<version>1.0.0</version>
<name>sofachannel-demo</name>
<description>Demo project for SofaStack Dynamic Module</description>
<properties>
<java.version>1.8</java.version>
<ark.version>1.0.0</ark.version>
<dashboard.client>1.0.0</dashboard.client>
<curator.version>2.9.1</curator.version>
<mybatis.version>1.3.2</mybatis.version>
<mysql.version>5.1.46</mysql.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alipay.sofa</groupId>
<artifactId>sofa-dashboard-client</artifactId>
<version>${dashboard.client}</version>
</dependency>
<!-- 引用ark web插件-->
<dependency>
<groupId>com.alipay.sofa</groupId>
<artifactId>web-ark-plugin</artifactId>
<version>${ark.version}</version>
</dependency>
<!-- 引用ark 配置推送擴充插件-->
<dependency>
<groupId>com.alipay.sofa</groupId>
<artifactId>config-ark-plugin</artifactId>
<version>${ark.version}</version>
</dependency>
<dependency>
<artifactId>curator-client</artifactId>
<groupId>org.apache.curator</groupId>
<version>${curator.version}</version>
</dependency>
<dependency>
<artifactId>curator-framework</artifactId>
<groupId>org.apache.curator</groupId>
<version>${curator.version}</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>${mybatis.version}</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<dependency>
<groupId>io.sofastack</groupId>
<artifactId>dynamic-facade</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.21.0</version>
</plugin>
</plugins>
</build>
</project>
在facade裡面定義方法
在provider裡面實作facade裡的方法
如果業務經常會涉及controller層的變動,也可以再provider裡面寫controller層
provider的pom檔案,代碼如下
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>sofachannel-demo</artifactId>
<groupId>io.sofastack</groupId>
<version>1.0.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>dynamic-provider</artifactId>
<version>1.0.1</version>
<dependencies>
<!--facade子產品依賴-->
<dependency>
<groupId>io.sofastack</groupId>
<artifactId>dynamic-facade</artifactId>
</dependency>
<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>-->
<!-- <artifactId>curator-client</artifactId>-->
<!-- <groupId>org.apache.curator</groupId>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <artifactId>curator-framework</artifactId>-->
<!-- <groupId>org.apache.curator</groupId>-->
<!-- </dependency>-->
<!--增加web依賴-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--子子產品如果要添加了web依賴,必須要添加這個類隔離的依賴,否則項目啟動不了,-->
<dependency>
<groupId>com.alipay.sofa</groupId>
<artifactId>sofa-ark-springboot-starter</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<!--這裡添加ark 打包插件-->
<plugin>
<groupId>com.alipay.sofa</groupId>
<artifactId>sofa-ark-maven-plugin</artifactId>
<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>
</plugins>
</build>
</project>
最後是master biz
BizController可以通過接口來install 和 uninstall ark biz
package io.sofastack.stockmng.controller;
import com.alipay.sofa.ark.api.ArkClient;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.io.File;
@RestController
@Slf4j
public class BizController {
@RequestMapping(value = "/installBiz", method = RequestMethod.POST)
public String installBiz(@RequestParam(value = "url") String url) throws Throwable {
log.info("url為:{}",url);
File file = new File(url);
ArkClient.installBiz(file);
return "調用成功";
}
@RequestMapping(value = "/uninstallBiz", method = RequestMethod.POST)
public void uninstallBiz(String bizName, String bizVersion) throws Throwable {
ArkClient.uninstallBiz(bizName, bizVersion);
}
@RequestMapping(value = "/switchBiz", method = RequestMethod.POST)
public void switchBiz(String bizName, String bizVersion) {
ArkClient.switchBiz(bizName, bizVersion);
}
}
indexController來測試改變provider裡面的實作方法能否改變已經運作的項目的業務邏輯
package io.sofastack.stockmng.controller;
import com.alipay.sofa.runtime.api.annotation.SofaReference;
import io.sofastack.dynamic.facade.StrategyService;
import io.sofastack.dynamic.model.ProductInfo;
import io.sofastack.stockmng.data.DatabaseSeed;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.ArrayList;
import java.util.List;
@Controller
public class IndexController {
@SofaReference
private StrategyService strategyService;
@RequestMapping("/")
public String index(Model model) {
model.addAttribute("productList", strategyService.strategy(initProducts()));
return "index";
}
@ResponseBody
@RequestMapping("/sort")
public String sort() {
String test = strategyService.test();
return test;
}
/**
* 初始化預設展示清單,為了實驗效果,此處初始化的清單與實際清單是相反的,但是實際排序結果與現場購買訂單直接挂鈎
*
* @return
*/
private List<ProductInfo> initProducts() {
List<ProductInfo> products = new ArrayList<>(5);
for (int i = 4; i >= 0; i--) {
ProductInfo productInfo = new ProductInfo();
productInfo.setName(DatabaseSeed.name[i]);
productInfo.setOrderCount(DatabaseSeed.orderCount[i]);
productInfo.setSrc(DatabaseSeed.imageUrls[i]);
productInfo.setAuthor(DatabaseSeed.authors[i]);
products.add(productInfo);
}
return products;
}
}
pom檔案
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>sofachannel-demo</artifactId>
<groupId>io.sofastack</groupId>
<version>1.0.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>dynamic-stock-mng</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--此元件提供異步初始化 Spring Bean 能力-->
<dependency>
<groupId>com.alipay.sofa</groupId>
<artifactId>runtime-sofa-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>io.sofastack</groupId>
<artifactId>dynamic-facade</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!-- 這裡添加動态子產品相關依賴 -->
<!--類隔離元件 sofa-ark-springboot-starter-->
<dependency>
<groupId>com.alipay.sofa</groupId>
<artifactId>sofa-ark-springboot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.alipay.sofa</groupId>
<artifactId>web-ark-plugin</artifactId>
</dependency>
<!--引入子子產品的biz-->
<dependency>
<groupId>io.sofastack</groupId>
<artifactId>dynamic-provider</artifactId>
<version>1.0.0</version>
<classifier>ark-biz</classifier>
</dependency>
</dependencies>
<build>
<plugins>
<!-- 這裡配置動态子產品打包插件 -->
<plugin>
<groupId>com.alipay.sofa</groupId>
<artifactId>sofa-ark-maven-plugin</artifactId>
<executions>
<execution>
<id>default-cli</id>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
<configuration>
<priority>100</priority>
<baseDir>../</baseDir>
<bizName>stock-mng</bizName>
</configuration>
</plugin>
</plugins>
</build>
</project>
測試,直接package整個項目,拿到master biz的ark-excutable.jar這個jar包,運作
通過postman測試master biz的接口
再看看provider biz的接口
test2是被注釋掉的,是以沒有辦法調用。
接下來修改provider
實作的方法改成654321
把第二個接口放出來
修改pom檔案裡面的version
重新package
擷取provider 1.0.1版本的ark-biz的jar包
此時我們可以通過telnet指令連接配接到ark
可以看到之前provider的版本是1.0.0,如果你的provider沒有web依賴,不提供controller層,隻是負責實作service的具體方法,可以在直接install上去再切換provider的版本。但如果你的provider要提供controller接口,那麼必須先把之前的1.0.0版本的provider uninstall之後才能install上去。因為隻要install上去之後,controller層就會加載好。而你1.0.1版本的server.servlet.context-path 跟1.0.0版本是相同的,會導緻失敗,是以需要先uninstall。如果你把1.0.1版本的server.servlet.context-path修改一下,install上去之後,就算不處于激活狀态,1.0.1版本的接口也是可以通路的。
在這裡我們先uninstall
系統提示正在uninstall ,我們再看看版本
此時,provider已經解除安裝掉了,再去調用provider提供的接口會報404,去調用sort接口會報500
我們把1.0.1版本給他install上,我在網上看到的教程都是可以通過biz -i 指令進行install,但是我一直install不上去。
如上畫所示,雖然提示了正在install,但是等了很久,我再去檢視,依然隻有孤零零的一個master biz
好在我們提供了接口,通過bizController接口調用ark内置的指令來install,也就是我們之前寫的BizController裡面的方法。
我們來調用一下
提示成功了,去看一下呢
已經成功install了,我們去看一下接口
sort的業務邏輯已經改變了,傳回的數字變成了654321
1.0.1版本provider提供的兩個controller接口也調用成功。
這裡我們的demo測試基本完成了,但是我還是遇到了一個小問題,當我不需要某個provider biz的jar包的時候,删不掉,提示我正在被占用,有沒有哪位大佬能告訴我怎麼解決啊。