天天看點

SOFA Ark子產品化更新小Demo

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

SOFA Ark子產品化更新小Demo

 父工程裡面的配置

SOFA Ark子產品化更新小Demo

父工程的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裡面定義方法

SOFA Ark子產品化更新小Demo

 在provider裡面實作facade裡的方法

SOFA Ark子產品化更新小Demo

 如果業務經常會涉及controller層的變動,也可以再provider裡面寫controller層

SOFA Ark子產品化更新小Demo

 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包,運作

SOFA Ark子產品化更新小Demo

 通過postman測試master biz的接口

SOFA Ark子產品化更新小Demo

再看看provider biz的接口

SOFA Ark子產品化更新小Demo
SOFA Ark子產品化更新小Demo

test2是被注釋掉的,是以沒有辦法調用。

接下來修改provider

實作的方法改成654321

SOFA Ark子產品化更新小Demo

 把第二個接口放出來

SOFA Ark子產品化更新小Demo

修改pom檔案裡面的version

SOFA Ark子產品化更新小Demo

重新package

擷取provider 1.0.1版本的ark-biz的jar包

SOFA Ark子產品化更新小Demo

 此時我們可以通過telnet指令連接配接到ark

SOFA Ark子產品化更新小Demo
SOFA Ark子產品化更新小Demo

可以看到之前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

SOFA Ark子產品化更新小Demo

系統提示正在uninstall ,我們再看看版本

SOFA Ark子產品化更新小Demo

此時,provider已經解除安裝掉了,再去調用provider提供的接口會報404,去調用sort接口會報500

我們把1.0.1版本給他install上,我在網上看到的教程都是可以通過biz -i 指令進行install,但是我一直install不上去。

SOFA Ark子產品化更新小Demo

 如上畫所示,雖然提示了正在install,但是等了很久,我再去檢視,依然隻有孤零零的一個master biz

SOFA Ark子產品化更新小Demo

 好在我們提供了接口,通過bizController接口調用ark内置的指令來install,也就是我們之前寫的BizController裡面的方法。

SOFA Ark子產品化更新小Demo

 我們來調用一下

SOFA Ark子產品化更新小Demo

 提示成功了,去看一下呢

SOFA Ark子產品化更新小Demo

已經成功install了,我們去看一下接口

SOFA Ark子產品化更新小Demo

sort的業務邏輯已經改變了,傳回的數字變成了654321

SOFA Ark子產品化更新小Demo
SOFA Ark子產品化更新小Demo

1.0.1版本provider提供的兩個controller接口也調用成功。

這裡我們的demo測試基本完成了,但是我還是遇到了一個小問題,當我不需要某個provider biz的jar包的時候,删不掉,提示我正在被占用,有沒有哪位大佬能告訴我怎麼解決啊。