Java项目有可能做到所有的代码逻辑均可热部署吗?

   2023-02-09 学习力0
核心提示:前言首先我们明确下什么叫做热部署,热部署是在不重启java虚拟机的前提下,自动更新class的行为,从而更新整个运行时的逻辑。在java开发领域,热部署一直是一个难以解决的问题,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的官网和仓库地址,如果你觉得这款开源框架对你的业务有帮助,赶紧来了解一下吧

项目官网:

https://liteflow.yomahub.com

gitee托管仓库:

https://gitee.com/dromara/liteFlow

github托管仓库:

https://github.com/dromara/liteflow

 
标签: java 开源
反对 0举报 0 评论 0
 

免责声明:本文仅代表作者个人观点,与乐学笔记(本网)无关。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
    本网站有部分内容均转载自其它媒体,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责,若因作品内容、知识产权、版权和其他问题,请及时提供相关证明等材料并与我们留言联系,本网站将在规定时间内给予删除等相关处理.

  • #新闻拍一拍# Oracle 调研如何避免让 Java 开发者投奔 Rust 和 Kotlin | Linux 中国
    #新闻拍一拍# Oracle 调研如何避免让 Java 开发
     导读:• 英特尔对迟迟不被 Linux 主线接受的 SGX Enclave 进行了第 38 次修订 • ARM 支持开源的 Panfrost Gallium3D 驱动本文字数:977,阅读时长大约:1分钟作者:硬核老王Oracle 调研如何避免让 Java 开发者投奔 Rust 和 KotlinOracle 委托分析公司 Omd
    03-08
  • oogle的“ JavaScript杀手” Dart 与JavaScript的比较
    oogle的“ JavaScript杀手” Dart 与JavaScript
    JavaScript通常被称为浏览器脚本语言,但它也已扩展到许多服务器端和移动应用程序开发环境。JS已经存在了将近20年,可以肯定地说它确实是一种成熟且稳定的编程语言。在Facebook发布React和React Native框架之后,JS变得越来越流行。JavaScript具有自己的软件
    03-08
  • sf02_选择排序算法Java Python rust 实现
    Java 实现package common;public class SimpleArithmetic {/** * 选择排序 * 输入整形数组:a[n] 【4、5、3、7】 * 1. 取数组编号为i(i属于[0 , n-2])的数组值 a[i],即第一重循环 * 2. 假定a[i]为数组a[k](k属于[i,n-1])中的最小值a[min],即执行初始化 min =i
    02-09
  • Delphi XE6 通过JavaScript API调用百度地图
    Delphi XE6 通过JavaScript API调用百度地图
    参考昨天的内容,有朋友还是问如何调用百度地图,也是,谁让咱都在国内呢,没办法,你懂的。 首先去申请个Key,然后看一下百度JavaScript的第一个例子:http://developer.baidu.com/map/jsdemo.htm下一步,就是把例子中的代码,移动TWebBrower中。 unit Unit
    02-09
  • JavaScript面向对象轻松入门之抽象(demo by ES5
    抽象的概念  狭义的抽象,也就是代码里的抽象,就是把一些相关联的业务逻辑分离成属性和方法(行为),这些属性和方法就可以构成一个对象。  这种抽象是为了把难以理解的代码归纳成与现实世界关联的概念,比如小狗这样一个对象:属性可以归纳出“毛色”、
    02-09
  • Java与Objective-C的渊源 objective-c和c++的区
    java创始成员Patrick Naughton回忆,通常人们会认为Java是学Modula-3和C+,其实这些都是谣传,而对Java影响比较大的则是Objective-C:单 继承、动态绑定和加载、类对象、纯虚函数、反射、原始类型包装类等。Java的接口直接抄自OC的协议。  Objective-C是扩
    02-09
  • Java项目导出数据为 PDF 文件的操作代码
    Java项目导出数据为 PDF 文件的操作代码
    目录Java项目如何导出数据为 PDF 文件?一、代码结构如下二、代码说明1、添加依赖 pom.xml2、HTML模板文件 audit_order_record.html3、添加字体4、PDF 导出工具类5、导出接口6、打开浏览器测试三、效果图Java项目如何导出数据为 PDF 文件?一个小需求,需要将
  • 盘点Java中延时任务的多种实现方式 java 延时队列怎么实现
    盘点Java中延时任务的多种实现方式 java 延时队
    目录场景描述实现方式一、挂起线程二、ScheduledExecutorService 延迟任务线程池三、DelayQueue(延时队列)四、Redis-为key指定超时时长,并监听失效key五、时间轮六、消息队列-延迟队列场景描述①需要实现一个定时发布系统通告的功能,如何实现? ②支付超时
  • Java Semaphore信号量使用分析讲解
    Java Semaphore信号量使用分析讲解
    目录前言介绍和使用API介绍基本使用原理介绍获取许可acquire()释放许可release()总结前言大家应该都用过synchronized 关键字加锁,用来保证某个时刻只允许一个线程运行。那么如果控制某个时刻允许指定数量的线程执行,有什么好的办法呢? 答案就是JUC提供的信
  • 【Java并发入门】03 互斥锁(上):解决原子性问题
    【Java并发入门】03 互斥锁(上):解决原子性
    原子性问题的源头是线程切换Q:如果禁用 CPU 线程切换是不是就解决这个问题了?A:单核 CPU 可行,但到了多核 CPU 的时候,有可能是不同的核在处理同一个变量,即便不切换线程,也有问题。所以,解决原子性的关键是「同一时刻只有一个线程处理该变量,也被称
    02-09
点击排行