Java项目有可能做到所有的代码逻辑均可热部署吗?
前言
首先我们明确下什么叫做热部署,热部署是在不重启java虚拟机的前提下,自动更新class的行为,从而更新整个运行时的逻辑。
在java开发领域,热部署一直是一个难以解决的问题,java虚拟机理论上只能实现方法体的修改热部署,对于整个类结构的更改,仍然需要重启虚拟机,对类重新加载才能完成更新操作。
OSGI
其实java业界有一些解决方案,比如osgi架构,这玩意时间比较长了,但一直没火起来。osgi架构的出现,可以让java系统变成模块化的形式,让模块重启成为可能。从一定程度上也算是个热部署的方案。可惜这玩意以前开发起来就觉得很反人类,配置文件一大堆不说,学习成本也很大。和spring结合起来,居然是一个模块一个spring上下文体系。并且如果模块之间有调用关系的话,重启相关的模块会让应用出现短暂的功能性休克,也就说,整个热启动过程不平滑。
这项技术现在估计很多小伙伴都没听说过,目前也渐渐的退出历史舞台,用的企业估计很少。
ASM
ASM是一款修改字节码的框架,同类型的框架还有Cglib。这些框架能加载一个class信息,用户可以按照自己的需求增强修改这些信息,最后输出成一个新的class。
具体实现过程,这里就不展开了。大家可以百度下,相关技术实现文章不少。
但单纯修改字节码一般要和其他技术结合起来,单靠这个也无法完成热更新,虽然ASM类的框架能够修改类,但是这些ASM的修改逻辑也是用java写的,这段代码也需要执行的。如果你把ASM的代码写在java里,也无法实现从外部
来热更新。
Javaagent&Attach API结合ASM
这就是上面一段说的ASM要结合其他技术才能实现热更新的方案,也是目前很多开源框架采用的方案。
比如大名鼎鼎的Arthas,就是利用javaagent通过Attach API运行时加载目标Java程序,最终利用Instrumention API或者ASM增强class,来实现代码跟踪,以及代码热修改的特性。
但笔者认为用Arthas来完成线上代码的热更新,只能用于一些很紧急的场景。不能替代日常业务逻辑修改。而且操作起来也挺复杂。
你需要先修改java代码,然后把java代码放到服务器上,在arthas里查找这个类的类加载器的hashcode,然后利用arthas提供的命令编译java代码输出成新的class文件,最用利用redefine
命令进行热更新。
试想下,如果大量逻辑的更改。这得有多麻烦。
所以更多的是利用arthas对线上应用进行诊断,追踪,热更改代码其实就是arthas众多功能中其中一个,并不是主要功能。
换一种思路
以上方案都是基于修改class本身,然后让JVM的类加载器重新加载来实现的。
那么有没有更好的方案呢?
其实java代码可以运行一些脚本的,jdk本身就支持调用脚本,从JDK 1.6开始,java就支持JSR223,可以用一致的形式在JVM上执行一些脚本语言,而且可实时编译,运行的效率和java不相上下的。
有的同学看到这里可能会拍砖了:利用脚本只能更改部分逻辑,不可能把所有的逻辑都用脚本写吧,你这篇文章探讨的不是“有没有可能所有的逻辑
都可热更新”么?
别急,首先我们来确定一个事情。你的java应用系统需不需要所有的
逻辑都是可以热更新的?很多代码都是大致固定不变的,比如util类,一些vo的定义也不大变更的,一些固定的业务也不需要热更新需求的。只有一些经常变更的决策部分,可能需要热更新。
那么我们只要把需要经常变的部分用脚本来定义不就可以了么。
业界有没有类似的开源框架呢?
还真有,而且是高star的热门开源项目,能够帮你做到用脚本进行热更新业务。
开源编排规则引擎
可能有小伙伴又要说了:你不是介绍java代码热部署么,怎么话题转到规则引擎上去了?
这里要说下,规则引擎的一大特性就是把决策部分逻辑剥离到外面,能够实现逻辑的变动快速热变更。
而这次介绍的规则引擎框架则更为强大,除了能剥离逻辑,还能解耦系统,让你的所有的逻辑块均可随意变更。理论上能实现所有
的逻辑都可变更,不是部分
哦。
这就是业界现在 很火的编排式规则引擎框架:LiteFlow
。
LiteFlow的理念很简单,就是把系统中的各个逻辑切分成一小块一小块的,称之为组件
,这些组件可以由java代码来写,也可以用脚本来写。然后一个完整业务就是把各个组件组搭一起,形成一个完整业务链。
这种模式的好处就是,不需要热更新的部分可以用java组件来写,需要经常变的部分可以用脚本来写。所有的组件均可混搭成为一个业务。如何编排这些组件,LiteFlow独创了ELF语法,拥有非常好上手的编排语法。程序员的话,十分钟就可以上手。上图粉色部分就是最简单的一种串联形式。
业务链路中组件可实时更换,也可实时增加,形成一个新的业务链。同时定义好的组件也可复用在其他的链路中。
LiteFlow的脚本方案也是利用JSR223来实现的,目前已经实现的脚本有三种:
为什么说利用LiteFlow编排引擎框架,你的所有逻辑都是可以变更的呢。因为你完全可以把所有的逻辑都用脚本组件来实现,LiteFlow提供了非常强大的脚本支持,完全和Java底层打通,你可以在脚本中import java的类,也可以调用java的类方法,甚至于可以在脚本中去定义方法,定义类,一切写法和java中完全一样。
更夸张的是,LiteFlow允许你在脚本中调用spring上下文的bean,你可以在脚本中调用DAO取数据,可以在脚本中发送rpc给其他微服务。只要你愿意,你可以一行java业务代码不写,完全把业务搬到脚本组件中去。
而且连逻辑块的顺序你也可以随意变动,因为LiteFlow的编排规则和脚本均可实现热变更。
LiteFlow为经常用的存储中间件也提供了原生支持:
LiteFlow支持所有的关系型数据库,另外zk,etcd,nacos均可支持,还提供了额外的扩展接口,供你自己扩展成其他的存储方式。
有想过么,你所有的逻辑和规则编排语法,都是存在于系统之外的。只要更改其脚本和逻辑,你所有节点的系统不需要做任何事,实时的进行热变更。
而这一切,LiteFlow做到了非常平滑,所谓平滑的意思是,不用担心在热变更的时候你的业务会受到任何的中断,也不会因为热变更造成正在执行的链路产生任何的异常。
LiteFlow编排能力有多强大呢,简单的几个关键字就可以编排出超乎想象的效果:
结语
在java的业务热部署领域,LiteFlow作为一款规则引擎,给出了一种新的解决思路。
除以上文中介绍的之外,LiteFlow框架还拥有众多的高级特性,从各个方位提升你系统的灵活性。
并且作为开源软件,LiteFlow拥有国内非常好的社区氛围和文化。
最后放出LiteFlow的官网和仓库地址,如果你觉得这款开源框架对你的业务有帮助,赶紧来了解一下吧
项目官网:
gitee托管仓库:
https://gitee.com/dromara/liteFlow
github托管仓库:
Java项目有可能做到所有的代码逻辑均可热部署吗?的更多相关文章
- java混淆工具 字符串加密 程序加密 代码逻辑混淆 防止反编译
混淆工具使用文档 ht-confusion-project1.0.0 目 录 1.功能介绍... 1 2.安装说明... 3 2.1Window查询jdk版本(点击开始菜单,输入cmd, 输入java ...
- Java项目源码为什么要做代码混淆(解释的很好)
代码混淆,是将计算机程序的代码转换成一种功能上等价,但是难于阅读和理解的形式的行为.代码混淆可以用于程序源代码,也可以用于程序编译而成的中间代码.执行代码混淆的程序被称作代码混淆器.目前已经存在许多种 ...
- 基于VS Code快速搭建Java项目
有时候随手想写一点Java测试代码,以控制台程序为主,还会用到一些其它框架,并基于Maven构建. 1.Java Extension Pack一定要安装. 2.VS Code打开一个指定目录,创建相应 ...
- maven 学习---使用Maven创建Java项目
在本教程中,我们将向你展示如何使用 Maven 来创建一个 Java 项目,导入其到Eclipse IDE,并打包 Java 项目到一个 JAR 文件. 所需要的工具: Maven 3.3.3 Ecl ...
- [转]基于VS Code快速搭建Java项目
有时候随手想写一点Java测试代码,以控制台程序为主,还会用到一些其它框架,并基于Maven构建. 1.Java Extension Pack一定要安装. 2.VS Code打开一个指定目录,创建相应 ...
- 利用 jrebel 热部署\远程调试\远程热部署 springboot项目 服务器上的代码
首先要在eclipse 中启用 启用以后在 resource 中生成了 rebel-remote.xml 然后build,把生成的jar包放到服务器上. 然后用下面的命令启动 java -agentp ...
- Java 调式、热部署、JVM 背后的支持者 Java Agent
我们平时写 Java Agent 的机会确实不多,也可以说几乎用不着.但其实我们一直在用它,而且接触的机会非常多.下面这些技术都使用了 Java Agent 技术,看一下你就知道为什么了. -各个 J ...
- Scala:Java 项目中混入scala代码
Spark 是用Scala代码写的.为了调试Spark,做了如下尝试. 1.Eclipse下:Java 项目 ,Using Maven,编写了一个java 版Spark应用. Spark的代码(sca ...
- Jenkins+Gradle+Sonar进行Java项目代码分析
Jenkins+Maven+Sonar与Jenkins+Gradle+Sonar配置方法很相似,区别就是Java项目所用的编译工具不同,一个是maven,一个是gradle 使用maven编译工具的可 ...
- 统计Java项目的代码行数
Java项目谈论行数多少有点无聊,但是有的时候就想看看一个开源的代码的量级,用Shell命令统计再合适不过了 去掉空行和注释: find . -name "*.java" |xar ...
随机推荐
- 第二十五篇:vue-cli
好家伙,感觉好像摸到一点核心了, 什么是vue-cli? 1.vue-cli官方提供的一个脚手架,用于快速生成一个vue模板, 预先定义好目录结构以及基础代码 2.什么是脚手架? (1)做电梯井抹灰. ...
- Sync包
sync同步包 Mutex互斥锁: 能够保证在同一时间段内仅有一个goroutine持有锁,有且仅有一个goroutine访问共享资源,其他申请锁的goroutine将会被阻塞直到锁被释放.然后重新争 ...
- Github-CLI
Github-CLI Github 的官方命令行工具 Github CLI.Mac 系统可以通过 homebrew 安装或者直接下载免安装包来使用. 命令 Github CLI 的所有命令均以gh开头 ...
- .NET 7 来了!!!
.NET 7 首个RC(发布候选)版本 最近 .Net 的大事件,就是微软发布了.NET 7的首个RC(发布候选)版本,而据微软发布的消息,这是 .NET 7 的最后一个预览版,下一个版本将是第一个候 ...
- mpdf导出pdf,中文符号乱码
改源码: 打开vendor/mpdf/mpdf/src/Config/FontVariables.php 在最后一行加入: "gb" => [ 'R' => 'gb.t ...
- jmeter性能测试之正则提取响应头或者响应体
准备工作做好,先发送请求 然后察看结果树中的响应消息 比如我们要提取这个cookie,先调试一下,看能不能提取到 看蓝色的线条,我们提取到了,然后我们把这句话写入到后置处理器中的正则表达式提取里 再次 ...
- Gitea 与 Drone 集成实践:完全基于 Docker 搭建的轻量级 CI/CD 系统
Drone 是一个使用 Go 语言编写的自助式的持续集成平台,和 Gitea 一样可以完全基于容器部署,轻松扩展流水线规模.开发者只需要将持续集成过程通过简单的 YAML 语法写入 Gitea 仓库目 ...
- k8s 中的 Pod 细节了解
k8s中Pod的理解 基本概念 k8s 为什么使用 Pod 作为最小的管理单元 如何使用 Pod 1.自主式 Pod 2.控制器管理的 Pod 静态 Pod Pod的生命周期 Pod 如何直接暴露服务 ...
- Service概述
为何需要 Service Kubernetes 中 Pod 是随时可以消亡的(节点故障.容器内应用程序错误等原因).如果使用 Deployment 运行您的应用程序,Deployment 将会在 Po ...
- vue3 vite2 封装 SVG 图标组件 - 基于 vite 创建 vue3 全家桶项目续篇
在<基于 vite 创建 vue3 全家桶>一文整合了 Element Plus,并将 Element Plus 中提供的图标进行全局注册,这样可以很方便的延续 Element UI 的风 ...