Skip to content

Lunarscave/arklet-springboot-demo

Repository files navigation

实验内容

基于sofa-ark-dynamic-guides的实验模板,使用Sofa-Severless的http调用工具Akrlet,通过 SOFAArk 提供的动态模块能力,实现商品列表排序策略的动态变更,以及动态装卸订单查询子应用。能够完成在不重启宿主机,不更改应用配置的情况下实现应用行为改变的任务。

实验准备

  • sofa-serverless-arklet-springboot-demo
  • IntellJ IDEA
  • Postman(可选,作为HTTP API使用工具)

本实验采用SofaBoot启动器,同样地可以使用Springboot完成最基础的应用模块装载,只需要在Maven中取消关于ark web插件中sofa boot的依赖引入即可。比如,下述sofa-boot的依赖即可删除。

<!-- bookstore-manager/pom.xml -->

<dependency>  
    <groupId>com.alipay.sofa</groupId>  
    <artifactId>healthcheck-sofa-boot-starter</artifactId>  
</dependency>

<dependency>  
    <groupId>com.alipay.sofa</groupId>  
    <artifactId>runtime-sofa-boot-starter</artifactId>  
</dependency>

<dependency>  
    <groupId>com.alipay.sofa</groupId>  
    <artifactId>runtime-sofa-boot-plugin</artifactId>  
</dependency>

任务

1、任务准备

从 github 上将 demo 工程克隆到本地

git clone [email protected]:/sofa-serverless-arklet-springboot-demo

然后将工程导入到 IDEA 或者 eclipse,打开工程后,工程目录结构如下:

├── bookstore-manager  
├── bookstore-order-provider
├── bookstore-provider
├── bookstore-service
└── pom.xml  
  • bookstore-manager 宿主应用,提供基础数据,提供用户端的商品展示 web 页面,用于展示实验效果。
  • bookstore-order-provider 子应用,提供订单数展示的行为,独立提供 web 页面,类比单体应用移植。
  • bookstore-provider 实现 bookstore-service 定义的接口,并将实现类作为一个服务,类比服务注册行为。
  • bookstore-service 定义一个 Java 接口 StrategyService,该接口用于对传入的商品列表进排序并返回。

2、相关依赖与打包配置

由于本模块在 demo 中已经实现,若仅复现实验可以跳过本节。本节主要介绍 sofa 相关依赖的配置,针对外部已有工程的 sofa 引入,可以参照本节 maven 配置 sofa 依赖,其余微服务相关配置不在此赘述。

宿主应用确定 sofa 版本及 sofa 依赖,关于 SOFAArk 可以参考SOFABoot 类隔离 一节进行了解。 其中具体添加的依赖如下

<!-- bookstore-manager/pom.xml --> 

<!-- sofa-boot 启动器 -->  
<dependency>  
    <groupId>com.alipay.sofa</groupId>  
    <artifactId>runtime-sofa-boot-starter</artifactId>  
</dependency>  
  
<!-- sofa-boot 健康检查 -->  
<dependency>  
    <groupId>com.alipay.sofa</groupId>  
    <artifactId>healthcheck-sofa-boot-starter</artifactId>  
</dependency>  
  
<!-- sofa-core sofa-ark 主要依赖 -->  
<dependency>  
    <groupId>com.alipay.sofa</groupId>  
    <artifactId>sofa-ark-all</artifactId>  
    <version>${sofa.ark.version}</version>  
    <exclusions>  
        <exclusion>  
            <groupId>ch.qos.logback</groupId>  
            <artifactId>logback-core</artifactId>  
        </exclusion>  
        <exclusion>  
            <groupId>ch.qos.logback</groupId>  
            <artifactId>logback-classic</artifactId>  
        </exclusion>  
    </exclusions>  
</dependency>  
  
<!-- sofa-ark 编译时,ArkContainer装载在Springboot内的配置 -->  
<dependency>  
    <groupId>com.alipay.sofa</groupId>  
    <artifactId>sofa-ark-compatible-springboot2</artifactId>  
    <version>${sofa.ark.version}</version>  
</dependency>  
  
<!-- sofa-ark 在springboot启动时添加上下文配置 -->  
<dependency>  
    <groupId>com.alipay.sofa</groupId>  
    <artifactId>sofa-ark-springboot-starter</artifactId>  
    <version>${sofa.ark.version}</version>  
    <exclusions>  
        <exclusion>  
            <groupId>com.alipay.sofa</groupId>  
            <artifactId>sofa-ark-compatible-springboot1</artifactId>  
        </exclusion>  
    </exclusions>  
</dependency>  
  
<!-- sofa-ark-plugin -->  
<dependency>  
    <groupId>com.alipay.sofa</groupId>  
    <artifactId>web-ark-plugin</artifactId>  
</dependency>  
<dependency>  
    <groupId>com.alipay.sofa</groupId>  
    <artifactId>runtime-sofa-boot-plugin</artifactId>  
</dependency>  
  
<!-- end to add sofa-ark-plugin -->  
<dependency>  
    <groupId>com.alipay.sofa</groupId>  
    <artifactId>hessian</artifactId>  
</dependency>  
  
<!-- arklet springboot 启动器 -->  
<dependency>  
    <groupId>com.alipay.sofa</groupId>  
    <artifactId>arklet-springboot-starter</artifactId>  
    <version>1.0.0-SNAPSHOT</version>  
</dependency>

在打包配置中,sofa-ark 2.0之后宿主应用可以直接启动。但是更早的版本需要宿主应用需要本身打包一个 masterbiz,在 build 内部添加如下配置。

<build>  
    <plugins>  
        <plugin>  
            <groupId>org.springframework.boot</groupId>  
            <artifactId>spring-boot-maven-plugin</artifactId>  
            <configuration>  
                <outputDirectory>target</outputDirectory>  
                <classifier>ark-biz</classifier>  
            </configuration>  
            <executions>  
                <execution>  
                    <id>package</id>  
                    <goals>  
                        <goal>repackage</goal>  
                    </goals>  
                </execution>  
            </executions>  
        </plugin>  
    </plugins>  
</build>

在使用 sofaboot 启动的前提下,若需要对biz包(服务实例)进行健康检查,则需要在相应的服务模块内部加入 healthcheck-sofa-boot-starter 依赖

<!-- bookstore-provider/pom.xml --> 

<dependency>  
    <groupId>com.alipay.sofa</groupId>  
    <artifactId>healthcheck-sofa-boot-starter</artifactId>  
    <scope>provided</scope>  
</dependency>

另外在宿主应用中考虑到服务的注册,需要提前加入相应的 provider 依赖。

3、将 dynamic-provider 打包成 ark biz

在 bookstore-provider/pom.xml 中,增加 ark 打包插件,该模块实现了宿主应用的一个接口,同时暴露一个 rest 服务,添加如下配置。

image.png

<plugins>  
    <!--这里添加ark 打包插件-->  
    <plugin>  
        <groupId>com.alipay.sofa</groupId>  
        <artifactId>sofa-ark-maven-plugin</artifactId>  
        <version>2.1.3</version>  
        <executions>  
            <execution>  
                <id>default-cli</id>  
                <goals>  
                    <goal>repackage</goal>  
                </goals>  
            </execution>  
        </executions>  
        <configuration>  
            <skipArkExecutable>true</skipArkExecutable>  
            <outputDirectory>./target</outputDirectory>  
            <bizName>bookstore-provider</bizName>  
            <webContextPath>provider</webContextPath>  
            <declaredMode>true</declaredMode>  
        </configuration>  
    </plugin>  
</plugins>

4、打包 & 启动宿主应用

sofa-ark 2.0之后宿主应用可以直接启动,命令行与IDEA内部均可以启动,需要额外增设虚拟机选项 -Dsofa.ark.embed.enable=true,然后直接启动 BookStoreManagerApplication 类。

image.png

  • sofa-ark 启动成功之后的日志信息如下。

image.png

  • sofa-boot 启动成功之后的日志信息如下。

image.png

  • arklet 启动成功之后的日志信息如下。

image.png

5、 引入默认的排序策略模块

bookstore-provider 提供的 bookstore.services.StrategyService 实现类返回了默认的价格降序排序模块,现在需要实现在宿主应用启动的情况下完成 biz 模块动态装卸。 执行 mvn clean package 进行打包,此时可以额外地打出新版本(需要在 pom.xml 中给出版本号) bookstore-provider ark biz 包,其中后续需要对 *-ark-biz.jar 的包进行部署与卸载,如下。

image.png

原来的sofa-ark可以使用 telnet 连接来检测 biz 安装情况,现在可以使用 arklet 提供的一套 http API 完成 biz 装卸,关于telnet使用详见 sofa-ark-dynamic-guides的第5节

这里使用 Postman 进行 http 请求发送,其中具体使用 http://localhost:1238/... 格式 POST 请求,具体请求体如下。

使用 http://localhost:1238/installBiz 路由安装 bookstore-provider 的 biz 包,其中需要使用 JSON 给出 Request Body(arkBizFilePath,bizname,bizversion 参数必填),并查询响应结果。

{
	// Win 下文件路径
  "arkBizFilePath": "\\{盘符}:\\{文件路径}\\sofa-serverless-arklet-springboot-demo\\bookstore-provider\\target\\bookstore-provider-1.0.0-ark-biz.jar",
  // Mac 下文件路径
  // "arkBizFilePath": "/{文件路径}/sofa-serverless-arklet-springboot-demo/bookstore-provider/target/bookstore-provider-1.0.0-ark-biz.jar",
  "bizname": "bookstore-provider",
  "bizversion": "1.0.0"
}

image.png

  • 从响应码可以看出宿主应用已经安装了 bookstore-provider 模块,此时使用路由 http://localhost:1238/queryAllBiz 查询应用内所有 ark-biz 包,如下。

image.png

  • 发现已经成功安装两个访问 http://localhost:8080 ,现在展示的是默认的降序排列顺序,如下所示:

image.png

6、新建按照销量排序策略模块

bookstore-provider 提供的 bookstore.services.StrategyService 实现类返回了默认的价格降序排序模块,现在需要开发一个新版本模块,这个新版本模块会按照价格升序商品列表

首先,修改 bookstoreprovider.serviceImpl.StrategyServiceImpl 实现类如下:

@Service  
@SofaService  
public class StrategyServiceImpl implements StrategyService {  
    @Override  
    public List<BookInfo> strategy(List<BookInfo> bookList) {  
        // ascending order        
        bookList.sort((i, j) -> (int) (i.getPrice() - j.getPrice()));  
        return bookList;  
    }  
    
    @Override  
    public String getStrategyName() {  
        return "按价格升序";  
    }  
}  

然后,修改 bookstore-provider 版本号 2.0.0:

<version>2.0.0</version>  

最后,由于本 demo 引入 web-ark-plugin,所以每个模块会复用同一个 tomcat 实例,所以需要更改server 的 webContextPath,搜索并修改 bookstore-provider 的 pom.xml

--- <webContextPath>provider1</webContextPath>  
+++ <webContextPath>provider2</webContextPath>  

配置完成之后,执行 mvn clean package 进行打包,此时可以打包出新版本 bookstore-provider ark biz包,如下。

image.png

通过 arklet 中 http://localhost:1238/installBiz 完成安装请求,安装新版本 bookstore-provider,Request Body 如下,并查询响应结果。

 {
	// Win 下文件路径
    "arkBizFilePath": "\\{盘符}:\\{文件路径}\\sofa-serverless-arklet-springboot-demo\\bookstore-provider\\target\\bookstore-provider-2.0.0-ark-biz.jar",
    // Mac 下文件路径
    // "arkBizFilePath": "/{文件路径}/sofa-serverless-arklet-springboot-demo/bookstore-provider/target/bookstore-provider-2.0.0-ark-biz.jar",
    "bizname": "bookstore-provider",
    "bizversion": "2.0.0"
}

image.png

由于应用中已经有了 bookstore-provider 的 biz 包了,因此 2.0.0 版本是未激活的状态,需要将宿主应用切换到最新的模块,使用路由 http://localhost:1238/switchBiz 切换到对应版本的 biz 模块,具体Request Body 如下,并查询响应结果。

{
    "bizname": "bookstore-provider",
    "bizversion": "2.0.0"
}

image.png

成功切换完模块后,使用路由 http://localhost:1238/queryAllBiz 查看当前所有模块的状态,发现 bookstore-provider 2.0.0 版本已经激活。

image.png

访问 http://localhost:8080/index ,现在展示的是列表编程按照价格升序进行排序,如下。

image.png

7、安装与卸载展示销量策略的独立子应用

现在需要开发一个新版本模块,提供关于销量的展示模块,bookstore-order-provider 提供了关于销量的展示模块,另如果要访问模块中的rest请求,请带上模块 sofa-ark-maven-plugin 里定义的webContextPath。 如同上述安装步骤一样,执行 mvn clean package 进行打包,注意在打包的时候需要将原先加入的Spring 等启动器依赖使用 provided ,防止与宿主应用冲突,如下。

image.png

通过 arklet 中 http://localhost:1238/installBiz 完成安装请求,安装新版本 bookstore-provider,Request Body 如下,并查询响应结果。

{
	// Win 下文件路径
    "arkBizFilePath": "\\{盘符}:\\{文件路径}\\sofa-serverless-arklet-springboot-demo\\bookstore-provider\\target\\bookstore-order-provider-1.0.0-ark-biz.jar",
    // Mac 下文件路径
    // "arkBizFilePath": "/{文件路径}/sofa-serverless-arklet-springboot-demo/bookstore-provider/target/bookstore-order-provider-1.0.0-ark-biz.jar",
    "bizname": "bookstore-order-provider",
    "bizversion": "1.0.0"
}

image.png

安装成功后,使用路由 http://localhost:1238/queryAllBiz 查看当前所有模块的状态,发现 bookstore-order-provider 1.0.0 已经激活

image.png

访问 http://localhost:8080/order-provider/api-order/index 发现成功展示子应用的 web 页面,同理也可以使用 rest 服务。

image.png

现展示模块卸载工作,调用 http://localhost:1238/uninstallBiz 完成 bookstore-order-provider biz 的卸载任务,Request Body 如下,并查询响应结果。

{
    "bizname": "bookstore-order-provider",
    "bizversion": "1.0.0"
}

image.png

卸载成功后,使用路由 http://localhost:1238/queryAllBiz 查看当前所有模块的状态,发现 bookstore-order-provider 1.0.0 已经删除

image.png

8、使用健康检查查询所有信息

arklet 额外支持指令与 endpoint 拓展完成基于模块的健康检查,这里简单地示范部分查询结果,具体健康检查详见API

  • arklet 指令查询 使用路由 http://localhost:1238/health 在 POST 方法下查询健康状态,如下

image.png

从上述返回 response 看出,健康检查可以查询到 jvm,cpu,masterBizHealth,masterBiz信息,Biz模块信息与Plugin模块信息六个指标,同样地,下表其中可以组合的条件和查询内容的判定表如下:

参数 具体值
type - "system" "system" "biz" "biz" "biz" "plugin" "plugin"
metrics - - ["cpu", "jvm"] - - - - -
moduleName - - - - "bizName" "bizName" - "pluginName"
moduleVersion - - - - - "bizVersion" - -
指标 response
jvm
cpu
masterBizHealth
masterBizInfo
bizListInfo
pluginListInfo
bizInfo
  • endpoint 拓展查询

arklet 基于 SpringBoot-Actuator 提供了两种 endpoint 查询方式,其中默认配置了 actuator 的基本属性:

  • endpoints exposure include: *
  • endpoints base path: /
  • endpoints sever port: 8080

第一种查询所有健康的指标GET 方法下使用路由 http://localhost:8081/arkHealthz 可以查询所有健康信息(同上六个指标),并额外返回健康的状态与 HealthCode,如下

image.png

其中 HealthCode 如下:

  • HEALTHY(200): 健康检测通过
  • UNHEALTHY(400): 出现不健康的指标
  • ENDPOINT_NOT_FOUND(404): 当前 endpoint 不存在
  • ENDPOINT_PROCESS_INTERNAL_ERROR(500): 在获取健康检测中出错

arkHealthz 支持三种查询:

  • http://localhost:8081/arkHealthz 查询所有健康信息
  • http://localhost:8081/arkHealthz/{moduleType} 查询相应类型的健康信息
  • http://localhost:8081/arkHealthz/{moduleType}/{moduleName}/{moduleVersion} 查询具体模块的信息

第二种查询相应是否健康,返回 HealthCodeGET 方法下使用路由 http://localhost:8081/arkHealthCode 可以查询健康代码(HealthCode),如下

image.png

arkHealthCode 同样支持三种查询:

  • http://localhost:8081/arkHealthz 查询所有健康信息,并返回 HealthCode
  • http://localhost:8081/arkHealthz/{moduleType} 查询相应类型的健康信息
  • http://localhost:8081/arkHealthz/{moduleType}/{moduleName}/{moduleVersion} 查询具体模块的信息

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published