SpringCloud整合Dubbo3实战高并发下的微服务架构设计

#1

download:SpringCloud整合Dubbo3实战高并发下的微服务架构设计

乔克和SPL,基于Java的数据业务逻辑开发技术 很多开源技术都可以在Java下实现以数据库为核心的业务逻辑,其中JOOQ比Hibernate的计算能力更强,比MyBatis的可移植性更好,越来越受到关注。Procspl是一种新的数据计算语言,在计算能力和可移植性方面也有突出的优势。下面两个方面进行比较,找出更高效的数据业务逻辑开发技术。JOOQ商业版主要支持商业数据库和存储过程,这超出了本文的讨论范围。 语言特点 编程风格 JOOQ支持完整的面向对象编程风格,可以组合多个对象(方法)形成类似SQL的语法逻辑。JOOQ可以使用Java的Lambda表达式、函数调用接口和进程控制语法,理论上支持面向函数和面向进程,但是这些表达式\语法不是为JOOQ的结构化数据对象(Result)设计的,使用起来不够方便。 SPL支持面向对象、面向函数和面向过程的编程风格,并大大简化了它们。SPL有对象的概念,可以用点号访问属性,进行多步计算,但不继承和重载这些内容。SPL的Lambda表达式比SQL更简单易用,函数调用接口和流控语法是专门为结构化数据对象(序列表)设计的,使用起来更方便。 运转模 JOOQ是编译执行的Java代码,性能较高,灵活性较小。但是,JOOQ本身没有计算能力。执行后,它只生成SQL语句,然后由数据库进行计算并返回结果。实际性能不高,有些业务逻辑需要反复读写数据库,所以性能更差。SPL是一种解释性语言,它的编码更加灵活,但是同样的代码性能会差一点。而SPL拥有不依赖数据库的独立计算能力,不需要反复读写数据库,内置了大量时间复杂度较低的基本操作。它的计算性能常常可以超过编译语言。 外部类库 JOOQ可以引入其他任意的第三方Java类库来弥补它的不足,比如使用Stream来增加它的独立计算能力。然而,这些类库不是为结构化数据对象设计的,它们的功能是有限的。SPL内置了专业的数据处理功能,提供了大量的基础操作,开发效率更高,时间复杂度更低。通常不需要外部Java类库,特殊情况可以在自定义函数中调用。 和调试。 它们都有图形化的IDE和完整的调试功能。JOOQ使用的是Java IDE,优点是更通用,缺点是没有针对数据处理进行优化,无法方便地观察结构化数据对象。SPL的IDE是专门为数据处理而设计的。结构化数据对象以表格形式呈现,使得观察更加方便。 学习难度 JOOQ需要学习三种语法,SQL,通用Java和JOOQ。其中,SQL的语言能力要高于一般水平,才能转换成JOOQ语法;JOOQ文法主要用于开发,难度不大,但是转换过程比较复杂。Java的一般语言能力可以低于一般水平。SPL的目标是简化Java甚至SQL的编码,初学者学习或者深度开发都不难。但是到了高性能计算,就需要学习更多独特的算法,难度就会加大。 代码数量 SQL擅长结构化数据计算,语法简洁,代码量低。但是为了把SQL翻译成JOOQ,需要引入很多函数,导致过度封装和大量实际代码。JOOQ的进程控制依赖于Java语法,但Java语法不是为结构化数据对象设计的,代码量也不低。 SPL的表达能力比SQL强,远远强于JOOQ,可以用更低的代码量实现结构化数据计算。SPL的流处理语句是专门为结构化数据对象设计的,代码量低于Java。 结构化数据对象 结构化数据对象用于对象化数据库表,这是数据处理和业务逻辑开发的基础。专业的结构化数据对象可以方便地与数据库交换数据,支持丰富的计算功能,简化流程处理的难度。 定义 JOOQ的结构化数据对象由记录和记录集组成。记录有很多种。第一种是记录对象,适用于字段的个数、类型、名称都是动态生成的情况。虽然Record很灵活,但是它不太面向对象,使用起来也很麻烦。比如需要通过getValue(M)得到第M个字段。第二种是Record[N]对象,其中N为1到22,如Record3,适用于字段类型和编号已知但不超过22,字段名动态生成的情况。Record[N]不太灵活,但稍微更面向对象,所以使用起来更方便。例如,您可以通过valueM获取第m个字段。第三种记录对象是JOOQ的代码工具根据库表结构生成的。几个表中有几个对象,字段的个数、类型、名称与库表中的严格对应,比如OrdersRecord、EmployeesRecord。这种记录对象不灵活,高度面向对象,使用方便,直接通过字段名就可以得到字段。第三类对应的是数据库表,可以称为具有固定数据结构的记录对象。前两类通常来自于数据库表的查询和计算,可以称为具有动态数据结构的记录对象。这三种类型都是常用的,还有一些不常用的记录对象,比如用户定义的记录类型UDT,这里就不讨论了。JOOQ中记录的对象种类繁多,用法差异较大,增加了开发难度。这主要是因为业务逻辑中有大量的动态数据结构,而Java是编译语言,只擅长表达固定的数据结构。如果坚持表示动态数据结构,只能设计复杂的接口规则,或者根据字段数量预定义大量对象。 JOOQ记录集的种类相对较少,比如原生对象结果及其父ArrayList,有时还有Stream。 SPL的结构化数据对象也由记录和记录集(序列表)组成。SPL只有一个记录对象,主要是因为SPL是一种解释性语言。动态数据结构和固定数据结构同样方便表达,接口也很简单,不需要分成多个。此外,记录对象和单个记录集虽然性质不同,但业务含义相似,使用时容易混淆。SPL是一种解释性语言,它的外部用法可以通过灵活的接口保持一致,从而进一步提高其可用性。相反,JOOQ是一种编译语言,所以很难设计出如此灵活的接口。它只能提供两种不同的接口,分别用于处理记录对象和单个记录集。 读取数据库 JOOQ读取外部数据库表并生成一个固定的记录集: Java . SQL . connection conn = driver manager . get connection(URL,用户名,密码); DSLContext context = DSL . using(conn,SQLDialect。MYSQL); 结果R1=context.select()。来自(订单)。fetchInto(订单); 复制代码 查询外部数据库表以生成动态记录集: result 2 = context . select(ORDERS。塞利德,命令。客户,订单。金额)。来自(订单)。fetch(); 复制代码 动态记录集的后续使用有点麻烦,但是可以兼容固定记录集。以下文章主要使用动态记录集。 SPL读取或查询外部数据库表以生成序列表:

A
一个
=conn=connect("mysql8 ")

2
=conn.query("select * from Orders ")


=conn.query("select SellerID,Client,Amount from Orders ")

SPL不分固定记录集和动态记录集,生成方法相同,后续用法相同。
写入数据库
为了将处理过的结构化数据对象持久化到数据库中,JOOQ提供了三个函数,即插入、更新和删除。修改记录r并将其更新到数据库:
r.setValue(订单。金额,r.getValue(订单。金额)。double value()+100);
r . update();
复制代码
以上是单个记录的更新。应该注意,数据库表必须有一个主键,这样自动生成的记录类将继承UpdatableRecordImpl。只有继承了UpdatableRecordImpl的record类支持update函数。
写批量数据库是数据业务逻辑的常见场景,JOOQ也可以实现。修改批记录集T并将其更新到数据库:
R1 . foreach(r–> { r . setvalue(ORDERS。金额,r.getValue(订单。金额)。double value()+100);});
R1 . foreach(r–> { r . update();});
复制代码
上面的代码循环记录集,手动更新每条记录,从而实现了整集的更新。如你所见,JOOQ通过硬写代码实现批量编写,没有封装,往往不方便。如果修改、增加或删除一批记录,需要区分三类记录,然后用不同的函数循环写入。常见的方法是继承record类,添加一个新的“ID”属性来区分它们,或者保存一个未修改的原始记录集T,手工比较修改后的集NT和原始集。无论哪种方式,手工实现的过程都很麻烦。
SPL封装了数据库的编写,添加、修改、删除单个和批量记录只使用一个更新函数,支持混合更新。比如原来的序列表是T,经过一系列增删改后的序列表是NT,变更结果持久化到数据库的orders表中:
连接更新(NT:T,订单)
复制代码
访问字段
JOOQ读取单个记录的客户端字段:
R1.get(0)。getClient();
R1.get(0)。获取(订单。客户端);
复制代码
上面的代码体现了JOOQ的核心优势:它支持纯面向对象的字段访问,并且不混合字符串、数值常量或其他非Java表达式。代码风格高度统一。不幸的是,上面的代码只适用于固定的结构化数据对象。如果是查询计算生成的动态记录对象,只能使用字符串字段名或数字序列号来访问字段:
R2.get(0)。get(" Client “);
R2.get(0)。get(1);
复制代码
动态记录对象更常见。以上字段的访问方式不是纯面向对象的,代码风格不一致,不支持自动补全,编写一般比较麻烦。
SPL支持纯面向对象的字段访问,不管是固定的还是动态的,一般写起来都很方便:
T(1)。客户
复制代码
当然,也支持字符串字段名或数字序列号来访问字段:
T(1)。字段(2)
T(1)。现场(“客户”)
复制代码
SPL在面向对象方面更纯粹,风格更统一,写代码更方便。此外,SPL提供了许多JOOQ不支持的便捷函数:默认字段名,可以直接用点号访问,比如取第二个字段:t (1)。# 2;取多个字段,返回一组集合:t .([客户端,金额])
有序访问
有序访问是业务逻辑开发的难点之一。JOOQ的记录集继承了Java的有序集ArrayList,具有一定的有序访问能力,支持按下标和按区间取记录:
R.get(3)
R.subList(3,5);
复制代码
进一步的函数需要硬编码,例如最后三个:
collections . reverse®;
R.subList(0,3);
复制代码
至于根据位置集取记录、向前步进记录等功能。,硬编码就更麻烦了。
SPL顺序表也是一个有序集,提供了与顺序相关的基本功能,如按下标取数、按区间取数等:
T(3)
转换到(3,5)
复制代码
序列表是专业的结构化数据对象,不支持很多与sequence JOOQ结果相关的高级函数,而序列表是直接提供的。例如,按照倒序号取记录,可以直接用负号表示:
T.m(-3)//倒数第二条
T.m (to (-3,-5))//倒数间隔
复制代码
例如,根据位置设置进行记录,并逐步记录:
T.M (1,3,5,7:10)//序列号为1,3,5,7-10的记录
T.M (-1,-3,-5)//倒数第二条1,3,5
T.step (2,1)//每两个取第一个(相当于奇数位置)
复制代码
结构化数据计算
结构化数据计算能力是数据业务逻辑的核心功能。下面是一些常见的话题,从简单到复杂,比较JOOQ和SPL的计算代码。
重新命名
//等效的SQL
选择卖方ID eid,订单金额
//JOOQ
context.select(订单。seller id . as(“Eid”),订单。AMOUNT.as(“金额”)。来自(订单)。获取()
//SPL
Orders.new(SellerID:EID,Amount:amt)
复制代码
JOOQ的语法逻辑和SQL基本相同,可以达到用面向对象的方式模拟SQL的目的,这是JOOQ的重要优势。也有不利之处。JOOQ的一个操作需要几个函数的组合。每个函数都有自己的参数和语法规则,学习和编写都比较困难。此外,许多函数中的字段名必须伴有表名,即使对于单表计算也是如此。这说明JOOQ的语法还不够专业,还有很大的提升空间。
SPL直接使用面向对象的语法来实现计算。一个操作对应一个函数,引用字段不一定要带表名。语法更专业,代码更短。
条件查询
//等效的SQL
select * from Orders where
((SellerID=2,Amount=2000,Amount2010
//JOOQ
context.select()。来自(订单)
。其中(
((订单。SELLERID.equal(2)。和(订单。金额小于(3000.0)))
。或者((订单。SELLERID.equal(3)。和(订单。amount . greater requal(2000.0)。和(订单。金额小于(5000.0))))))
。和(年(目。订单日期)。greaterThan(2012)))
。fetch();
//SPL
订单.选择(
((SellerID = = 2 & & Amount = 2000 & & Amount 2010)
复制代码
SQL本身的条件表达式足够简单。JOOQ虽然是模拟SQL,但是过度封装了条件表达式,函数太多,多括号难读,远不如SQL易懂。SPL使用函数实现条件查询,条件表达式简短易读。
分组摘要
//等效的SQL:
选择客户,提取(从订单日期开始的年份)y,计数(1) cnt
来自订单
按客户分组,提取(从订购日期开始的年份)
having AMT result = context . select(max(T2 . field(” continuous days "))。来自(T2)。fetch();
复制代码
这个问题比较难,需要多种简单计算的综合应用。JOOQ很难直接表达连续上涨的概念,只能通过技巧变相实现,即通过累计未上涨天数来计算连续上涨天数。具体来说,按时间顺序用上升标志标记每个记录。如果下跌,标记为1,如果上涨,标记为0;然后按时间顺序累加每条记录不涨的天数,norisingdays。只有当当前记录下降时,这个数字才会增加;如果目前的记录上升,这个数字将保持不变;根据不再上升的norisingdays数,找出每组的记录数。很明显,一批连续下降的记录的norisingdays的数量是不同的,每个记录会被划分到不同的组中。这个组算1,不是解决问题的目标,而是连续上升的一批记录的norisingdays数相同,可以分到同一个组。这组统计连续上涨的天数,这个数值就是解决问题的目标。最后用max函数计算最大连续上涨天数。
JOOQ的编程过程是先写SQL,然后翻译成JOOQ。对于简单的计算,SQL更容易写,翻译也不太难。但对于这种综合计算,计算逻辑更有技巧性,SQL不好写,所以翻译难度更大。另外,JOOQ是表面上很容易调试的Java,但本质是SQL,和SQL一样难调试,而这为以后的维护埋下了一个大坑。
SPL电码简单得多:
APPL.sort(天)。group@i(价格1000)
复制代码
选项也可以组合,例如:
Orders.select@1b(金额> 1000)
复制代码
一些函数的参数很复杂,可以分为多个层次。JOOQ对此没有特殊的语法方案。只能拆分成多个函数相互嵌套,尽力模拟SQL语法,导致代码冗长繁琐。SPL创造性地发明了分层参数来简化复杂参数的表达,用分号、逗号、冒号从高到低将参数分为三层。例如,关联两个表:
加入(订单:o,SellerId员工:e,EId)
复制代码
过程
JOOQ支持一些存储过程语法,包括循环语句和判断语句,但属于商业版,由于权限要求高,存在潜在的安全风险,移植起来比较困难,所以很少使用。除了存储过程,JOOQ还可以使用Java实现流程处理。对数据库没有权限要求,安全隐患小,可以无缝移植。例如,根据规则计算奖金:
orders . foreach(r–> {
Double amount=r.getValue(订单。金额);
如果(金额> 10000) {
r.setValue(订单。奖金),金额* 0.05);
}else if(金额> =5000 &&金额=2000 &&金额10000,金额*0.05,
如果(金额> 5000 &&金额=2000 &&金额