百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术教程 > 正文

Java框架研发思考(java做框架)

csdh11 2025-03-28 16:02 26 浏览

这次应CSDN之邀为Java20周年写稿,多谢大家能够记得我,本是想写一篇具体实战技术的文章,但这些技巧也许在其20岁成年之时已经代表不了什么新潮流,尽管20岁年龄的人类还是属于追求潮流的一代。回顾这些年的Java之路,特别是开发Jdon这个Java开源框架的前后经历,我想也许有必要和大家分享其中的得与失,供后来者借鉴。

彭晨阳

下面我大概谈谈Jdon框架的开发经历和我的思想转变发展过程。

最初开发Jdon框架的想法是因为Web流行导致的三层直至多层架构对开发流程的影响。现代多层架构将后端架构分解为多个层次,灵活性得到提高,因为你维护拓展任何一个层都很少影响其他层,这也是设计模式或面向对象思想的最初初衷吧。但灵活性也是有副作用的,副作用是带来了复杂性,简单的数据增删改查四个功能需要经过三层,那么就可能产生12道工序的开发。

因此,我希望能够在不牺牲多层架构基础上提高快速开发的能力,于是需要集成表现层、业务层和持久层等现有框架的集成整合能力,当时表现层框架是Struts1.x,业务层框架是Spring,Spring其实是一个业务容器,集成了依赖注入DI和AOP;而当时我对另外一个轻量反转注入微容器PicoContainer比较熟悉;在持久层选择上,当时有Hibernate等ORM选择,但考虑到这些ORM可能会绑架业务实体对象,而我设计的业务层框架容器不应该像Spring那样只包含服务,而且也应该业务实体对象。

这种想法也让我开发的Jdon框架完全不同于当时各种开发框架,同时可能走上另类的道路,就是今天大部分开发路线都是服务和实体分离,实体由数据库管理,而我的设计思路是让实体对象常驻在内存Inmemory中,虽然在性能上有很大提升,但是在数据完整性与一致性方面完全脱离了关系数据库的ACID支持。

为了体现这种业务服务和业务实体合并在一个容器中的特点,我还需要寻找理论上的支持,当时恰逢DDD领域驱动设计思想的诞生,通过简单接触,发现其分析设计理念完全符合我理想中的设计,DDD对业务需求的分析是从面向对象OO分析方法开始,与传统的基于关系数据库的E-R模型分析方法不同,DDD强调从需求中找出有界上下文与微服务,还有实体与值对象两种数据模型,DDD的实体模型对象不同于关系数据库的实体,它不但包含数据,还包含改变这些数据的方法行为,也就是将可变的状态用对象方法封装起来,将改变状态的方法行为暴露给外界,这种设计理念与后来并发模型Actor模型非常类似。

基于并发的Actor模型在Erlang和Scala中都有实现,我非常想将这种Actor模型引入到框架中,用来作为DDD实体模型的落地实现,这时发现了Disruptor框架,其内部RingBuffer模型能够实现两个线程之间无锁通信,而之前Java世界基本都是基于有锁实现,Disruptor在LMAX系统中实现每秒600万的交易。于是我将Disruptor作为框架的业务层容器核心基础组件,服务与实体之间可以通过发送异步消息通信,不再使用传统的方法直接调用,因为这会造成两者的耦合,当然引入接口,也会和接口耦合,现在实体与服务之间通过消息通道耦合,发送者无论哪个消费者接收只管发送消息,消费者也无论哪个发送者发送的消息只管接收就可以了。后来我发现,其实这个并发模型更类似Go语言的Channel并发模型。

框架的并发性能通过引入常驻内存和异步消息机制得到了最大化提升,下一步需要关心数据的完整性和一致性。因为摆脱了关系数据库的ACID支持。这方面参考了分布式系统的CAP定理。有人可能会说,你只是一个开发框架,又不是分布式框架,怎么会使用到CAP呢?其实因为我们的实体模型数据常驻内存,而存储层如关系数据库或NoSQL也有一份同样的数据,很显然,数据已经被分布了,那么这两个地方的同一数据如何保证一致性?这个原理类似两台服务器之间同一种数据如何保证一致性一样,这就需要CAP定理了。

在这种数据分区分布的情况下,只能在高一致性和可用性之间作平衡,如果你使用在高可用性场合,比如追求高性能,低延迟,快速响应,大的吞吐量,那么可以牺牲一点高一致性,通过最终一致性来实现;当然如果你很注重数据一致性完整性,那么可以牺牲一点可用性的性能问题。

那么具体开发中如何平衡呢?

CQRS架构提供了这种动态平衡,CQRS是一种读写分离的架构,数据的读取查询需要快速高性能,因此可用性为第一;而数据的保存修改等写操作,数据安全为第一;数据完整性很重要,那么高一致性为第一。

上面讨论了Jdon框架的并发性能和数据一致性问题,那么,Jdon框架的扩展性如何?所谓扩展性Scalable或称为可伸缩性是指水平分布扩展的能力,通过增加后端服务器就能线性提高系统的处理能力,这时引入了EventSourcing概念(简称ES)。

ES是一种不同于传统数据存储的思路。通常,我们是将实体对象中可变的状态直接保存到关系数据库对应的数据表中,比如订单实体模型的状态有未付款已付款和已出货三种状态,这些可变的状态保存在数据表字段中。

前面我们提到,实体模型对象与由数据表翻译过来的实体数据对象是有区别的,关键是前者包含改变状态的方向行为,也就是说,订单对象包含付款与出货两个方法,如果这两个方法被调用,那么订单的状态就会改变,比如付款方法一旦被调用完成,那么订单状态从未付款变为了已付款。这时问题来了,因为传统数据保存的是订单的当前状态,那么数据表中订单表的状态用已付款覆盖了未付款,曾经存在过的未付款这个状态就被覆盖了,如果订单状态一旦出错,我们无法追踪当前状态是由之前哪个状态切换过来,那么这时如果我们将订单对象的付款方法调用行为作为数据保存起来,就会能够追溯状态变化的历史。

前面说过,订单实体对象的方法调用是通过异步消息触发的,而不是使用普通代码直接调用的,这点Jdon框架已经通过内置的Disruptor实现了,因此,在ES架构中,我们只要将异步消息事件作为数据保存到数据库中即可。当然,ES架构不只是为了方便调试追溯历史,更重要的是易于分布扩展,如果我们将异步消息事件保存到一个消息系统中,比如ApacheKafka中,那么通过Kafak能够在分布式服务器之间执行原始节点相同的操作,从而保证整个分布式系统中相同数据类型的数据的高一致性。LinkedIn成功案例见:http://www.jdon.com/47156。

通过以上我个人对Jdon框架开发设计规划经历,我们发现Java世界已经形成了一个巨大生态系统,从“量子世界”(CPU并发)统一到整个“宇宙世界”(分布式架构),我们能够通过一个小小的框架直接贯穿。

作者简介:彭晨阳Jdon.com创办者和版主。软件开发设计咨询从业20年,10余年Java开发经验,拥有ERP、大型游戏、互动电视三网合一等架构经验。独立咨询顾问,个人擅长复杂系统的软件架构和领域建模。流行新技术思想的传道者,主持解道网站跟踪国际最新软件架构思想和设计技术。首个国内Java开源框架项目Jdon框架的设计者。

本文选自程序员电子版2015年5月B刊,该期更多文章请查看这里。2000年创刊至今所有文章目录请查看程序员封面秀。欢迎订阅程序员电子版(含iPad版、Android版、PDF版)。

相关推荐

NUS邵林团队发布DexSinGrasp基于强化学习实现物体分离与抓取统一

本文的作者均来自新加坡国立大学LinSLab。本文的共同第一作者为新加坡国立大学实习生许立昕和博士生刘子轩,主要研究方向为机器人学习和灵巧操纵,其余作者分别为硕士生桂哲玮、实习生郭京翔、江泽宇以及...

「PLC进阶」如何通过编写SCL语言程序实现物料分拣?

01、前言SCL作为IEC61131-3编程语言的一种,由于其高级语言的特性,特别适合复杂运算、复杂数学函数应用的场合。本文以FactoryIO软件中的物料分拣案例作为硬件基础,介绍如何通过SCL来实...

zk源码—5.请求的处理过程一(http1.1请求方法)

大纲1.服务器的请求处理链...

自己动手从0开始实现一个分布式 RPC 框架

前言为什么要自己写一个RPC框架,我觉得从个人成长上说,如果一个程序员能清楚的了解RPC框架所具备的要素,掌握RPC框架中涉及的服务注册发现、负载均衡、序列化协议、RPC通信协议、Socket通信、异...

MLSys’25 | 极低内存消耗:用SGD的内存成本实现AdamW的优化性能

AIxiv专栏是机器之心发布学术、技术内容的栏目。过去数年,机器之心AIxiv专栏接收报道了2000多篇内容,覆盖全球各大高校与企业的顶级实验室,有效促进了学术交流与传播。如果您有优秀的工作想要分享,...

线程池误用导致系统假死(线程池会自动销毁吗)

背景介绍在项目中,为了提高系统性能使用了RxJava实现异步方案,其中异步线程池是自建的。但是当QPS稍微增大之后却发现系统假死、无响应和返回,调用方出现大量超时现象。但是通过监控发现,系统线程数正常...

大型乘用车工厂布局规划(六大乘用车基地)

乘用车工厂的布局规划直接影响生产效率、物流成本、安全性和未来扩展能力。合理的布局应确保生产流程顺畅、物流高效、资源优化,并符合现代化智能制造和绿色工厂的要求。以下是详细的工厂布局规划要点:1.工厂布...

西门子 S7-200 SMART PLC 连接Factory IO的方法

有很多同学不清楚如何西门子200smart如何连接FactoryIO,本教程为您提供了如何使用西门子S7-200SMARTPLC连接FactoryIO的说明。设置PC和PLC之间的...

西门子博图高级仿真软件的应用(西门子博途软件仿真)

1.博图高级仿真软件(S7-PLCSIMAdvancedV2.0)S7-PLCSIMAdvancedV2.0包含大量仿真功能,通过创建虚拟控制器对S7-1500和ET200SP控制器进行仿真...

PLC编程必踩的6大坑——请对号入座,评论区见

一、缺乏整体规划:面条式代码问题实例:某快递分拣线项目初期未做流程图设计,工程师直接开始编写传送带控制程序。后期增加质检模块时发现I/O地址冲突,电机启停逻辑与传感器信号出现3处死循环,导致项目延期2...

统信UOS无需开发者模式安装软件包
统信UOS无需开发者模式安装软件包

原文链接:统信UOS无需开发者模式安装软件包...

2025-05-05 14:55 csdh11

100个Java工具类之76:数据指纹DigestUtils

为了提高数据安全性,保证数据的完整性和真实性,DigestUtils应运而生。正确恰当地使用DigestUtils的加密算法,可以实现数据的脱敏,防止数据泄露或篡改。...

麒麟KYLINIOS软件仓库搭建02-软件仓库添加新的软件包

#秋日生活打卡季#原文链接:...

Java常用工具类技术文档(java中工具类的作用)

一、概述Java工具类(UtilityClasses)是封装了通用功能的静态方法集合,能够简化代码、提高开发效率。本文整理Java原生及常用第三方库(如ApacheCommons、GoogleG...

软路由的用法(自动追剧配置)(软路由教学)

本内容来源于@什么值得买APP,观点仅代表作者本人|作者:值友98958248861环境和需求...