From aa99555fed1191e3041f116d2430379c105ba476 Mon Sep 17 00:00:00 2001 From: linnan Date: Tue, 19 Jul 2022 11:35:29 +0800 Subject: [PATCH 1/4] =?UTF-8?q?SOFAArk=20=E5=8A=A8=E6=80=81=E9=83=A8?= =?UTF-8?q?=E7=BD=B2=E6=BA=90=E7=A0=81=E8=A7=A3=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sofa-ark-dynamic-deploy/index.md | 667 +++++++++++++++++- .../sofa-ark-dynamic-deploy/install.png | Bin 0 -> 125382 bytes .../sofa-ark-dynamic-deploy/lifecycle.png | Bin 0 -> 19299 bytes 3 files changed, 665 insertions(+), 2 deletions(-) create mode 100644 content/zh/projects/sofa-boot/sofa-ark-dynamic-deploy/install.png create mode 100644 content/zh/projects/sofa-boot/sofa-ark-dynamic-deploy/lifecycle.png diff --git a/content/zh/projects/sofa-boot/sofa-ark-dynamic-deploy/index.md b/content/zh/projects/sofa-boot/sofa-ark-dynamic-deploy/index.md index d08dcb10a..ee3bdd272 100644 --- a/content/zh/projects/sofa-boot/sofa-ark-dynamic-deploy/index.md +++ b/content/zh/projects/sofa-boot/sofa-ark-dynamic-deploy/index.md @@ -3,6 +3,669 @@ title: "动态部署" aliases: "/sofa-boot/docs/sofa-ark-dynamic-deploy" --- -## 动态部署 +# 动态部署 -源码解析任务还在进行中,敬请期待! +## 前言 + +在实践中,我们通常会使用业务功能模块化的开发模式,部署时将不同模块合并部署,由于团队间技术栈不统一,此时就有可能出现以来冲突等问题。SOFAArk 定义了一种开发规范,将不同的应用模块打包成 Ark Biz,由一个基座 Biz 和多个 Biz 模块组成部署包,支持两种合并部署的方式,一种是静态合并部署,Ark Biz 以 Maven 依赖的方式引入项目;另一种是在运行时使用 API 或者 配置中心(Zookeeper)动态地安装或卸载 Biz,本文将重点讨论此方式。 + +## Ark Biz 的生命周期 + +![生命周期](lifecycle.png) + +Ark Biz 的生命周期主要包含三条指令: + +* install: 安装 Biz +* uninstall: 卸载 Biz +* switch: 激活 Biz + +在动态的安装和卸载时,Ark Biz 会流转于生命周期的五个阶段,Biz 在不同阶段时的状态如下: + +* unresolved: 未注册,此时 Biz 包未被运行时解析 +* resolved: Biz 包解析完成,且已注册,此时 Biz 包还没有安装或者安装中 +* activated: Biz 包启动完成,且处于激活状态,可以对外提供服务 +* broken: Biz 包启动失败后状态 +* deactivated: Biz 包启动完成,但处于未激活状态。(注意这个状态只对 JVM 服务生效,对 RPC 等其他中间件无效) + +这里我们可以看一下 Ark Biz +的数据模型 BizModel 类: + +```java +public class BizModel implements Biz { + ... + private String bizName; + private String bizVersion; + private BizState bizState; + ... +} +``` + +在 Ark Biz 的数据模型中 bizState 表示的就是当前状态,可以看到数据模型中定义了 Biz 包的名称和版本号,在运行时 SOFAArk 允许部署相同名称不同版本的 Biz,但只能有一个版本处于 activated 激活状态,其他版本的 Biz 状态将自动处于 deactivated 未激活状态。 + +## install + +![intall](install.png) + +在入口方法 ArkClient#installOperation 中,下载 Biz 包到本地临时文件,临时文件命名规则:${bizName}-${bizVersion}-${时间戳}。准备好 Biz 包后,调用 installBiz 方法,进入安装主流程。 + +```java +public static ClientResponse installOperation(BizOperation bizOperation) throws Throwable { + return installOperation(bizOperation, arguments); +} +public static ClientResponse installOperation(BizOperation bizOperation, String[] args) throws Throwable { + ... + if (bizOperation.getParameters().get(Constants.CONFIG_BIZ_URL) != null) { + URL url = new URL(bizOperation.getParameters().get(Constants.CONFIG_BIZ_URL)); + bizFile = ArkClient.createBizSaveFile(bizOperation.getBizName(), bizOperation.getBizVersion()); + FileUtils.copyInputStreamToFile(url.openStream(), bizFile); + } + return installBiz(bizFile, args); +} +``` + +安装 Ark Biz 的主流程: + +1. 解析 Biz 包,创建 BizModel +2. 将 Ark Biz 注册到 Biz Manager 中(如果已经注册过,安装流程将直接结束,并返回提示信息) +3. 启动 Ark Biz +4. 如果启动失败,则关停并卸载 Ark Biz + +```java +public static ClientResponse installBiz(File bizFile, String[] args) throws Throwable { + ... + Biz biz = bizFactoryService.createBiz(bizFile); // 1 + ClientResponse response = new ClientResponse(); + if (bizManagerService.getBizByIdentity(biz.getIdentity()) != null + || !bizManagerService.registerBiz(biz)) { // 2 + return response.setCode(ResponseCode.REPEAT_BIZ).setMessage( + String.format("Biz: %s has been installed or registered.", biz.getIdentity())); + } + + try { + biz.start(args); // 3 + ... + response + .setCode(ResponseCode.SUCCESS) + .setMessage( + String.format("Install Biz: %s success, cost: %s ms, started at: %s", + biz.getIdentity(), end - start, startDate)) + .setBizInfos(Collections. singleton(biz)); + return response; + } catch (Throwable throwable) { + ... + response.setCode(ResponseCode.FAILED).setMessage( + String.format("Install Biz: %s fail,cost: %s ms, started at: %s", + biz.getIdentity(), end - start, startDate)); + ... + try { + biz.stop(); // 4 + } catch (Throwable e) { + ... + throw e; + } finally { + bizManagerService.unRegisterBizStrictly(biz.getBizName(), biz.getBizVersion()); + } + return response; + } +} +``` + +### 解析 Ark Biz + +当开启内嵌模式时,将 Biz 包解压到 ${Biz}-unpack 目录下,生成展开型的 Biz 包;当未开启内嵌模式时,直接使用原始的 Biz Jar 包,生成压缩型的 Biz 包。 +这里生成 Biz 包是为了后续做类隔离做准备,在使用 ClassLoader.loadClass 方法查找类时,需要到不同的目标文件夹内查找。 + +```java +public Biz createBiz(File file) throws IOException { + BizArchive bizArchive; + if (ArkConfigs.isEmbedEnable()) { + File unpackFile = new File(file.getAbsolutePath() + "-unpack"); + if (!unpackFile.exists()) { + unpackFile = FileUtils.unzip(file, file.getAbsolutePath() + "-unpack"); + } + if (file.exists()) { + file.delete(); + } + file = unpackFile; + bizArchive = new ExplodedBizArchive(unpackFile); + } else { + JarFile bizFile = new JarFile(file); + JarFileArchive jarFileArchive = new JarFileArchive(bizFile); + bizArchive = new JarBizArchive(jarFileArchive); + } + BizModel biz = (BizModel) createBiz(bizArchive); + biz.setBizTempWorkDir(file); + return biz; +} +``` + +1. 从 Manifest 清单文件中解析基本信息(如MainClass),根据基本信息创建 BizModel,将 Ark Biz 的状态设置为 resolved +2. 创建 ClassLoader 设置到 BizModel 中 + +```java +public Biz createBiz(BizArchive bizArchive) throws IOException { + ... + // 1 + Attributes manifestMainAttributes = bizArchive.getManifest().getMainAttributes(); + bizModel + .setBizState(BizState.RESOLVED) + .setBizName(manifestMainAttributes.getValue(ARK_BIZ_NAME)) + .setBizVersion(manifestMainAttributes.getValue(ARK_BIZ_VERSION)) + .setMainClass(manifestMainAttributes.getValue(MAIN_CLASS_ATTRIBUTE)) + ... + .setClassPath(bizArchive.getUrls()); + // 2 + BizClassLoader bizClassLoader = new BizClassLoader(bizModel.getIdentity(), + getBizUcp(bizModel.getClassPath()), bizArchive instanceof ExplodedBizArchive + || bizArchive instanceof DirectoryBizArchive); + bizClassLoader.setBizModel(bizModel); + bizModel.setClassLoader(bizClassLoader); + bizClassLoader.setBizModel(bizModel); + return bizModel; +} +``` + +### 启动 Ark Biz + +1. 将当前 ClassLoader 设置为 BizModel 的 ClassLoader,并暂存原 ClassLoader +2. 基于 BizModel ClassLoader 反射查找 MainClass,调用 main 方法 +3. 发布 AfterBizStartupEvent 事件,可以看到源码中的注释表示这里会触发健康检查,我们先记下这个点稍后解答 +4. 如果启动失败,就将 Ark Biz 状态设置为 broken +5. 将 ClassLoader 恢复回去 +6. 当前配置的模式是默认激活新模块,将 Ark Biz 状态设置为 activated。检查当前是否有同名 Biz 处于 activated 状态,如果有就将旧的 Biz 状态设置为 deactivated +7. 当前配置的模式不是默认激活新模块,先检查当前是否有同名 Biz 处于 activated 状态,如果没有,就将本次安装的 Ark Biz 激活;如果有,则将本次安装的 Ark Biz 状态设置为 deactivated + +```java +public void start(String[] args) throws Throwable { + ... + ClassLoader oldClassLoader = ClassLoaderUtils.pushContextClassLoader(this.classLoader); // 1 + EventAdminService eventAdminService = ArkServiceContainerHolder.getContainer().getService(EventAdminService.class); + try { + eventAdminService.sendEvent(new BeforeBizStartupEvent(this)); + resetProperties(); + if (!isMasterBizAndEmbedEnable()) { + ... + // 2 + MainMethodRunner mainMethodRunner = new MainMethodRunner(mainClass, args); + mainMethodRunner.run(); + // this can trigger health checker handler + eventAdminService.sendEvent(new AfterBizStartupEvent(this)); // 3 + ... + } + } catch (Throwable e) { + bizState = BizState.BROKEN; // 4 + throw e; + } finally { + ClassLoaderUtils.popContextClassLoader(oldClassLoader); // 5 + } + BizManagerService bizManagerService = ArkServiceContainerHolder.getContainer().getService(BizManagerService.class); + // 6 + if (Boolean.getBoolean(Constants.ACTIVATE_NEW_MODULE)) { + Biz currentActiveBiz = bizManagerService.getActiveBiz(bizName); + if (currentActiveBiz == null) { + bizState = BizState.ACTIVATED; + } else { + ((BizModel) currentActiveBiz).setBizState(BizState.DEACTIVATED); + bizState = BizState.ACTIVATED; + } + } else { + // 7 + if (bizManagerService.getActiveBiz(bizName) == null) { + bizState = BizState.ACTIVATED; + } else { + bizState = BizState.DEACTIVATED; + } + } +} +``` + +### 关停 Ark Biz + +1. 将当前 ClassLoader 设置为 BizModel 的 ClassLoader,并暂存原 ClassLoader +2. 将 Ark Biz 状态设置为 deactivated +3. 发布 BeforeBizStopEvent 事件,可以看到源码中的注释表示这里会触发 uninstall 卸载操作,我们先记下这个点稍后解答 +4. 从 Biz Manager 移除本次安装的 Ark Biz +5. 将 Ark Biz 状态恢复到初始状态 unresolved +6. 将 ClassLoader 恢复回去 + +```java +public void stop() { + ... + ClassLoader oldClassLoader = ClassLoaderUtils.pushContextClassLoader(this.classLoader); // 1 + bizState = BizState.DEACTIVATED; // 2 + EventAdminService eventAdminService = ArkServiceContainerHolder.getContainer().getService(EventAdminService.class); + try { + // this can trigger uninstall handler + eventAdminService.sendEvent(new BeforeBizStopEvent(this)); // 3 + } finally { + BizManagerService bizManagerService = ArkServiceContainerHolder.getContainer().getService(BizManagerService.class); + bizManagerService.unRegisterBiz(bizName, bizVersion); // 4 + bizState = BizState.UNRESOLVED; // 5 + eventAdminService.sendEvent(new BeforeBizRecycleEvent(this)); + ...// 省略了一部分清理缓存的代码 + ClassLoaderUtils.popContextClassLoader(oldClassLoader); // 6 + eventAdminService.sendEvent(new AfterBizStopEvent(this)); + } +} +``` + +### 事件发布机制 + +上文中介绍了 install 的源码,在动态安装 Ark Biz 的流程中,我们遗留了两个关于事件发布的问题。 + +第一处是当 Ark Biz 启动成功后,发布 AfterBizStartupEvent 事件,触发健康检查: + +```java +public void start(String[] args) throws Throwable { + ... + MainMethodRunner mainMethodRunner = new MainMethodRunner(mainClass, args); + mainMethodRunner.run(); + // this can trigger health checker handler + eventAdminService.sendEvent(new AfterBizStartupEvent(this)); + ... +} +``` + +这里需要结合 SOFABoot 理解,在 SOFABoot 源码中有一个 SofaBizHealthCheckEventHandler 类,是 AfterBizStartupEvent 事件的监听器: + +```java +public class SofaBizHealthCheckEventHandler implements EventHandler { + @Override + public void handleEvent(AfterBizStartupEvent event) { + doHealthCheck(event.getSource()); + } + private void doHealthCheck(Biz biz) { + SofaRuntimeManager sofaRuntimeManager = getSofaRuntimeManager(biz); + if (!sofaRuntimeManager.isReadinessHealth()) { + throw new RuntimeException("Health check failed."); + } + } + ... +} +``` + +SofaBizHealthCheckEventHandler 监听 AfterBizStartupEvent 事件,当事件发布时,就会调用 doHealthCheck 方法,从而实现在 Ark Biz 启动后,自动进行健康检查。当健康检查未通过时,会抛出异常,将进入 Ark Biz 启动失败的流程。 + +第二处是当 Ark Biz 启动失败,关停 Ark Biz 时,发布 BeforeBizStopEvent 事件,触发 uninstall 卸载操作: + +```java +public void stop() { + ... + // this can trigger uninstall handler + eventAdminService.sendEvent(new BeforeBizStopEvent(this)); // 3 + ... +} +``` + +这里同样需要结合 SOFABoot 理解,在 SOFABoot 源码中有一个 SofaBizUninstallEventHandler 类,是 BeforeBizStopEvent 事件的监听器: + +```java +public class SofaBizUninstallEventHandler implements EventHandler { + @Override + public void handleEvent(BeforeBizStopEvent event) { + doUninstallBiz(event.getSource()); + } + private void doUninstallBiz(Biz biz) { + // Remove dynamic JVM service cache + DynamicJvmServiceProxyFinder.getDynamicJvmServiceProxyFinder().afterBizUninstall(biz); + SofaRuntimeProperties.unRegisterProperties(biz.getBizClassLoader()); + SofaRuntimeManager sofaRuntimeManager = getSofaRuntimeManager(biz); + SofaFramework.unRegisterSofaRuntimeManager(sofaRuntimeManager); + sofaRuntimeManager.shutDownExternally(); + } + ... +} +``` + +SofaBizUninstallEventHandler 监听 BeforeBizStopEvent 事件,当事件发布时,调用 doUninstallBiz 方法,清理 JVM 服务、上下文参数等缓存。 + +## uninstall + +入口方法 ArkClient#uninstallOperation 中调用 uninstallBiz 方法,进入卸载流程。 + +```java +public static ClientResponse uninstallOperation(BizOperation bizOperation) throws Throwable { + ... + return uninstallBiz(bizOperation.getBizName(), bizOperation.getBizVersion()); +} +``` + +卸载 Ark Biz 的主流程: + +1. 判断要卸载的 Ark Biz 是否是基座,基座是主进程,不允许卸载 +2. 在 Biz Manager 中查找 Ark Biz +3. 未查找到要卸载的 Ark Biz 时,返回 NOTFOUND 提示信息 +4. [关停 Ark Biz](#关停-ark-biz) +5. 从 Biz Manager 中移除 Ark Biz +6. 卸载成功,返回成功提示 + +```java +public static ClientResponse uninstallBiz(String bizName, String bizVersion) throws Throwable { + ... + // 1 + if (bizName.equals(ArkConfigs.getStringValue(Constants.MASTER_BIZ))) { + return new ClientResponse().setCode(ResponseCode.FAILED).setMessage("Master biz must not be uninstalled."); + } + Biz biz = bizManagerService.getBiz(bizName, bizVersion); // 2 + ClientResponse response = new ClientResponse().setCode(ResponseCode.NOT_FOUND_BIZ) // 3 + .setMessage( + String.format("Uninstall biz: %s not found.", + BizIdentityUtils.generateBizIdentity(bizName, bizVersion))); + if (biz != null) { + try { + biz.stop(); // 4 + } catch (Throwable throwable) { + ... + throw throwable; + } finally { + bizManagerService.unRegisterBizStrictly(biz.getBizName(), biz.getBizVersion()); // 5 + } + // 6 + response.setCode(ResponseCode.SUCCESS).setMessage(String.format("Uninstall biz: %s success.", biz.getIdentity())); + } + return response; +} +``` + +## switch + +入口方法 ArkClient#switchOperation 中调用 switchBiz 方法,进入激活 Biz 流程。 + +```java +public static ClientResponse switchOperation(BizOperation bizOperation) { + ... + return switchBiz(bizOperation.getBizName(), bizOperation.getBizVersion()); +} +``` + +激活 Ark Biz 的主流程: + +1. 在 Biz Manager 中查找 Ark Biz +2. 未查找到 Ark Biz 时,返回 NOTFOUND 提示信息 +3. 当要激活的 Ark Biz 状态不是 activated 或 deactivated,Ark Biz 没有成功安装过,不能直接激活,此时返回 ILLEGAL_STATE 提示信息 +4. 激活 Ark Biz + +```java +public static ClientResponse switchBiz(String bizName, String bizVersion) { + ... + Biz biz = bizManagerService.getBiz(bizName, bizVersion); // 1 + ClientResponse response = new ClientResponse().setCode(ResponseCode.NOT_FOUND_BIZ) // 2 + .setMessage( + String.format("Switch biz: %s not found.", + BizIdentityUtils.generateBizIdentity(bizName, bizVersion))); + if (biz != null) { + if (biz.getBizState() != BizState.ACTIVATED + && biz.getBizState() != BizState.DEACTIVATED) { + // 3 + response.setCode(ResponseCode.ILLEGAL_STATE_BIZ).setMessage( + String.format("Switch Biz: %s's state must not be %s.", biz.getIdentity(), + biz.getBizState())); + } else { + eventAdminService.sendEvent(new BeforeBizSwitchEvent(biz)); + bizManagerService.activeBiz(bizName, bizVersion); // 4 + eventAdminService.sendEvent(new AfterBizSwitchEvent(biz)); + response.setCode(ResponseCode.SUCCESS).setMessage( + String.format("Switch biz: %s is activated.", biz.getIdentity())); + } + } + ... + return response; +} +``` + +激活 Ark Biz 时,需要先查找当前是否有同名 Biz 处于激活状态,如果有需要将状态切换为 deactivated,再将本次要激活的 Ark Biz 状态设置为 activated。 + +```java +public void activeBiz(String bizName, String bizVersion) { + ... + Biz biz = getBiz(bizName, bizVersion); + Biz activeBiz = getActiveBiz(bizName); + if (biz != null && biz.getBizState() == BizState.DEACTIVATED) { + if (activeBiz != null) { + ((BizModel) activeBiz).setBizState(BizState.DEACTIVATED); + } + ((BizModel) biz).setBizState(BizState.ACTIVATED); + } +} +``` + +## Telnet 指令 + +SOFAArk 提供了 telnet 小工具,用于运行时查看容器状态、执行动态部署指令等,接下来介绍下 telnet 小工具是如何实现动态部署的。 + +NettyTelnetHandler 作为 telnet 的入口,监听用户输入信息,委托 ArkCommandHandler 处理,并返回结果输出到控制台中。 + +```java +static class NettyTelnetHandler extends SimpleChannelInboundHandler { + private static ArkCommandHandler arkCommandHandler = new ArkCommandHandler(); + ... + @Override + protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception { + ... + ctx.write(arkCommandHandler.responseMessage(msg)); + ... + } +} +``` + +ArkCommandHandler 中委托 CommandProvider 解析用户输入的命令: + +```java +public String responseMessage(String cmd) { + String commandResult = handleCommand(cmd); + ... + return commandResult; +} +public String handleCommand(String cmdLine) { + ... + for (ServiceReference commandService : commandProviders) { + CommandProvider commandProvider = commandService.getService(); + if (commandProvider.validate(cmdLine)) { + return commandProvider.handleCommand(cmdLine); + } + } + return helpMessage(commandProviders); +} +``` + +在 BizCommandProvider 中委托 BizCommand 处理用户输入的命令: + +```java +public String handleCommand(String command) { + return new BizCommand(command).process(); +} +``` + +在 BizCommand 中,根据用户输入命令调用相应的编程API,以安装 Ark Biz 为例: + +1. 用户输入命令为 i 时,调用 installBiz 方法,进入安装流程 +2. 将用户输入的参数部分组装成 BizOperation +3. 调用 ArkClient.installOperation 进入[安装主流程](#install) + +```java +String process() { + ... + if (options.contains('h')) { + return HELP_MESSAGE; + } else if (options.contains('a')) { + return bizList(); + } else if (options.contains('i')) { + return installBiz();// 1 + } else if (options.contains('u')) { + return uninstallBiz(); + } else if (options.contains('o')) { + return switchBiz(); + } else { + ... + } + return sb.toString(); +} + String installBiz() { + ... + BizOperation bizOperation = new BizOperation().setOperationType(BizOperation.OperationType.INSTALL); + String param = parameters.toArray(new String[] {})[0]; + try { + // 2 + URL url = new URL(param); + bizOperation.putParameter(Constants.CONFIG_BIZ_URL, param); + } catch (Throwable t) { + String[] nameAndVersion = param.split(Constants.STRING_COLON); + if (nameAndVersion.length != 2) { + LOGGER.error("Invalid telnet biz install command {}", param); + return; + } + bizOperation.setBizName(nameAndVersion[0]).setBizVersion(nameAndVersion[1]); + } + try { + ArkClient.installOperation(bizOperation); // 3 + } catch (Throwable throwable) { + LOGGER.error("Fail to process telnet install command: " + param, throwable); + } + ... +} +``` + +> telnet 服务端只是 SOFAArk 提供的方便运行时查看信息工具,不推荐直接通过 telnet 指令在线上执行 Biz 操作指令,推荐使用 API 或者动态配置方式。 + +## Zookeeper 动态配置 + +SOFAArk 提供的动态配置插件,通过 Zookeeper 下发动态部署指令 + +```xml + + com.alipay.sofa + config-ark-plugin + ${sofa.ark.version} + +``` + +在 ConfigProcessor 入口类中,注册定时任务,长轮询拉取配置数据: + +```java +public void start() { + commonThreadPool.getExecutor().execute(new ConfigTask()); +} + +class ConfigTask implements Runnable { + @Override + public void run() { + while (true) { + ... + String config = configDeque.poll(); + if (config == null) { + sleep(200); + continue; + } + ... + OperationProcessor.process(OperationTransformer.transformToBizOperation(config, pluginContext)); + ... + } + } +} +``` + +调用 OperationTransformer#transformToBizOperation 方法将配置数据转换为 BizOperation,此处的源码不做详细说明,感兴趣的同学可以结合[Zookeeper 配置](https://www.sofastack.tech/projects/sofa-boot/sofa-ark-zk-config/)阅读源码 + +在 OperationProcessor#process 方法中,根据指令类型,调用 ArkClient 的不同方法: + +```java +public static List process(List bizOperations) { + List clientResponses = new ArrayList<>(); + try { + for (BizOperation bizOperation : bizOperations) { + ... + switch (bizOperation.getOperationType()) { + case INSTALL: + clientResponses.add(ArkClient.installOperation(bizOperation)); + break; + case UNINSTALL: + clientResponses.add(ArkClient.uninstallOperation(bizOperation)); + break; + case SWITCH: + clientResponses.add(ArkClient.switchOperation(bizOperation)); + break; + case CHECK: + clientResponses.add(ArkClient.checkOperation(bizOperation)); + break; + ... + } + } + } catch (Throwable throwable) { + throw new ArkRuntimeException("Failed to execute biz operations.", throwable); + } + return clientResponses; +} +``` + +### check + +Zookeeper 动态下发指令支持 check指令,check 指令用于查询 Ark Biz 安装情况。 + +入口方法 ArkClient#checkOperation 中调用 checkBiz 方法,进入查询 Biz 流程。 + +```java +public static ClientResponse checkOperation(BizOperation bizOperation) { + ... + return checkBiz(bizOperation.getBizName(), bizOperation.getBizVersion()); +} +``` + +查询 Ark Biz 的主流程: + +1. 在 Biz Manager 中查找 Ark Biz + 1. 当 Ark Biz 名称和版本都传入的情况,在 Biz Manager 中查找指定名称和版本的 Ark Biz + 2. 当传入 Ark Biz 名称的情况,在 Biz Manager 中查找该名称所有版本的 Ark Biz + 3. 当没有传入参数的情况,将在 Biz Manager 中注册的所有 Ark Biz 都查找出来 +2. 将符合条件的 Ark Biz 组装并返回 + +```java +public static ClientResponse checkBiz(String bizName, String bizVersion) { + ... + ClientResponse response = new ClientResponse(); + Set bizInfoSet = new HashSet<>(); + if (bizName != null && bizVersion != null) { + // 1.1 + Biz biz = bizManagerService.getBiz(bizName, bizVersion); + if (biz != null) { + bizInfoSet.add(biz); + } + } else if (bizName != null) { + // 1.2 + bizInfoSet.addAll(bizManagerService.getBiz(bizName)); + } else { + // 1.3 + bizInfoSet.addAll(bizManagerService.getBizInOrder()); + } + // 2 + StringBuilder sb = new StringBuilder(); + sb.append(String.format("Biz count=%d", bizInfoSet.size())).append("\n"); + for (BizInfo bizInfo : bizInfoSet) { + sb.append( + String.format("bizName=%s, bizVersion=%s, bizState=%s", bizInfo.getBizName(), + bizInfo.getBizVersion(), bizInfo.getBizState())).append("\n"); + } + response.setCode(ResponseCode.SUCCESS).setBizInfos(bizInfoSet).setMessage(sb.toString()); + LOGGER.info(String.format("Check Biz: %s", response.getMessage())); + return response; +} +``` + +激活 Ark Biz 时,需要先查找当前是否有同名 Biz 处于激活状态,如果有需要将状态切换为 deactivated,再将本次要激活的 Ark Biz 状态设置为 activated。 + +```java +public void activeBiz(String bizName, String bizVersion) { + ... + Biz biz = getBiz(bizName, bizVersion); + Biz activeBiz = getActiveBiz(bizName); + if (biz != null && biz.getBizState() == BizState.DEACTIVATED) { + if (activeBiz != null) { + ((BizModel) activeBiz).setBizState(BizState.DEACTIVATED); + } + ((BizModel) biz).setBizState(BizState.ACTIVATED); + } +} +``` + +## 总结 + +SOFAArk 通过轻量级的类隔离+动态装载的能力实现了动态合并部署,使开着飞机换引擎成为可能,能够极大的提升开发效率及应用可扩展性。 diff --git a/content/zh/projects/sofa-boot/sofa-ark-dynamic-deploy/install.png b/content/zh/projects/sofa-boot/sofa-ark-dynamic-deploy/install.png new file mode 100644 index 0000000000000000000000000000000000000000..1abd6630cf440a1d53cddad2583c8bc8109c6753 GIT binary patch literal 125382 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 qWv7v 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 LpUyD#>&Q)yM_UIQ;mQ0ws{LY&syRSQ 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 literal 0 HcmV?d00001 diff --git a/content/zh/projects/sofa-boot/sofa-ark-dynamic-deploy/lifecycle.png b/content/zh/projects/sofa-boot/sofa-ark-dynamic-deploy/lifecycle.png new file mode 100644 index 0000000000000000000000000000000000000000..79de9e6b077e67ec70c86f51c1ca8751719c1188 GIT binary patch literal 19299 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 MLtni>)i(5h0i_jnrT_o{ literal 0 HcmV?d00001 From bd58bf08659258f5cdfbeaa9102f4bb2d35fa7e5 Mon Sep 17 00:00:00 2001 From: linnan Date: Tue, 26 Jul 2022 09:56:09 +0800 Subject: [PATCH 2/4] =?UTF-8?q?=E6=A0=BC=E5=BC=8F=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../zh/projects/sofa-boot/sofa-ark-dynamic-deploy/index.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/content/zh/projects/sofa-boot/sofa-ark-dynamic-deploy/index.md b/content/zh/projects/sofa-boot/sofa-ark-dynamic-deploy/index.md index ee3bdd272..f1fb98dfd 100644 --- a/content/zh/projects/sofa-boot/sofa-ark-dynamic-deploy/index.md +++ b/content/zh/projects/sofa-boot/sofa-ark-dynamic-deploy/index.md @@ -1,9 +1,12 @@ - --- title: "动态部署" aliases: "/sofa-boot/docs/sofa-ark-dynamic-deploy" +author: "林楠" +authorlink: "https://github.com/it-linnan" +description: "源码解析 | 动态部署" +categories: "SOFAStack" +tags: [“源码解析”] --- -# 动态部署 ## 前言 From 068ab8eccac48f21016fac0aa3f7c2c4db3a140a Mon Sep 17 00:00:00 2001 From: linnan Date: Fri, 5 Aug 2022 23:23:34 +0800 Subject: [PATCH 3/4] =?UTF-8?q?=E5=AE=8C=E5=96=84=E6=8F=8F=E8=BF=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sofa-boot/sofa-ark-dynamic-deploy/index.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/content/zh/projects/sofa-boot/sofa-ark-dynamic-deploy/index.md b/content/zh/projects/sofa-boot/sofa-ark-dynamic-deploy/index.md index f1fb98dfd..42d7e121e 100644 --- a/content/zh/projects/sofa-boot/sofa-ark-dynamic-deploy/index.md +++ b/content/zh/projects/sofa-boot/sofa-ark-dynamic-deploy/index.md @@ -10,7 +10,7 @@ tags: [“源码解析”] ## 前言 -在实践中,我们通常会使用业务功能模块化的开发模式,部署时将不同模块合并部署,由于团队间技术栈不统一,此时就有可能出现以来冲突等问题。SOFAArk 定义了一种开发规范,将不同的应用模块打包成 Ark Biz,由一个基座 Biz 和多个 Biz 模块组成部署包,支持两种合并部署的方式,一种是静态合并部署,Ark Biz 以 Maven 依赖的方式引入项目;另一种是在运行时使用 API 或者 配置中心(Zookeeper)动态地安装或卸载 Biz,本文将重点讨论此方式。 +在实践中,我们通常会使用业务功能模块化的开发模式,部署时将不同模块合并部署,由于团队间技术栈不统一,此时就有可能出现依赖冲突等问题。SOFAArk 定义了一种开发规范,将不同的应用模块打包成 Ark Biz,由一个基座 Biz 和多个 Biz 模块组成部署包,支持两种合并部署的方式,一种是静态合并部署,Ark Biz 以 Maven 依赖的方式引入项目;另一种是在运行时使用 API 或者 配置中心(Zookeeper)动态地安装或卸载 Biz,本文将重点讨论此方式。 ## Ark Biz 的生命周期 @@ -28,7 +28,7 @@ Ark Biz 的生命周期主要包含三条指令: * resolved: Biz 包解析完成,且已注册,此时 Biz 包还没有安装或者安装中 * activated: Biz 包启动完成,且处于激活状态,可以对外提供服务 * broken: Biz 包启动失败后状态 -* deactivated: Biz 包启动完成,但处于未激活状态。(注意这个状态只对 JVM 服务生效,对 RPC 等其他中间件无效) +* deactivated: Biz 包启动完成,但处于未激活状态(注意这个状态只对 JVM 服务生效,对 RPC 等其他中间件无效) 这里我们可以看一下 Ark Biz 的数据模型 BizModel 类: @@ -170,7 +170,7 @@ public Biz createBiz(BizArchive bizArchive) throws IOException { ### 启动 Ark Biz -1. 将当前 ClassLoader 设置为 BizModel 的 ClassLoader,并暂存原 ClassLoader +1. 将当前线程上下文 ClassLoader 设置为 BizModel 的 ClassLoader,并暂存原 ClassLoader 2. 基于 BizModel ClassLoader 反射查找 MainClass,调用 main 方法 3. 发布 AfterBizStartupEvent 事件,可以看到源码中的注释表示这里会触发健康检查,我们先记下这个点稍后解答 4. 如果启动失败,就将 Ark Biz 状态设置为 broken @@ -224,7 +224,7 @@ public void start(String[] args) throws Throwable { ### 关停 Ark Biz -1. 将当前 ClassLoader 设置为 BizModel 的 ClassLoader,并暂存原 ClassLoader +1. 将当前线程上下文 ClassLoader 设置为 BizModel 的 ClassLoader,并暂存原 ClassLoader 2. 将 Ark Biz 状态设置为 deactivated 3. 发布 BeforeBizStopEvent 事件,可以看到源码中的注释表示这里会触发 uninstall 卸载操作,我们先记下这个点稍后解答 4. 从 Biz Manager 移除本次安装的 Ark Biz @@ -320,7 +320,7 @@ public class SofaBizUninstallEventHandler implements EventHandler Date: Fri, 12 Aug 2022 11:24:48 +0800 Subject: [PATCH 4/4] Update tags. Co-authored-by: seeflood --- content/zh/projects/sofa-boot/sofa-ark-dynamic-deploy/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/zh/projects/sofa-boot/sofa-ark-dynamic-deploy/index.md b/content/zh/projects/sofa-boot/sofa-ark-dynamic-deploy/index.md index 42d7e121e..5471ff201 100644 --- a/content/zh/projects/sofa-boot/sofa-ark-dynamic-deploy/index.md +++ b/content/zh/projects/sofa-boot/sofa-ark-dynamic-deploy/index.md @@ -5,7 +5,7 @@ author: "林楠" authorlink: "https://github.com/it-linnan" description: "源码解析 | 动态部署" categories: "SOFAStack" -tags: [“源码解析”] +tags: ["源码解析"] --- ## 前言