2.4.1 Oinone独特性之单体与分布式的灵活切换

企业数字化转型需要处理分布式带来的复杂性和成本问题。尽管这些问题令人望而却步,但分布式架构对于大部分企业仍然是必须的选择。如果一个低代码平台缺乏分布式能力,那么它的性能就无法满足客户的要求。相比之下,Oinone平台通过对部署的创新(如图2-6所示),成功实现了分布式架构的支持,而且能够按照客户的业务发展需求,灵活选择不同的部署模式,同时节约企业成本,提升创新效率。这一创新是Oinone平台与其他低代码平台的重要区别,能够满足客户预期发展并兼顾成本效益。

2.4.1 Oinone独特性之单体与分布式的灵活切换

图2-6 传统部署方式VS Oinone部署方式

实现原理

要实现灵活部署的特性,必须满足两个基本要求:

  1. 开发过程中不需要过多关注分布式技术,就像开发单体应用一样简单。代码在运行时应该能够根据模块是否在运行容器中,来决定路由走本地还是远程。这样可以大大减少研发人员的工作量和技术复杂度。

  2. 研发与部署要分离,即"开发单体应用一样开发分布式应用,而部署形式由后期决定"。为此,我们的工程结构支持多种启动模式,并逐一介绍了针对不同场景的工程结构类型(如下图2-7所示)。这样可以让客户在后期根据业务发展情况和需求,选择最适合的部署模式,从而达到灵活部署的目的。

2.4.1 Oinone独特性之单体与分布式的灵活切换

图2-7 Oinone工程结构梳理

在整个工程结构上,我们秉承了Spring Boot的规范,不会改变大家的工程习惯。而Oinone的部署能力则可以让我们更灵活地应对各种情况。现在,我们来逐一介绍几种常规的工程结构以及它们适用的场景:

  1. 单模块工程结构(常规操作)

    a. 这是非常标准的Spring Boot工程,适用于简单的应用场景开发以及入门学习。

  2. 多模块工程结构(常规操作)

    a. 这是非常标准的多Spring Boot工程,可以实现分布式独立启动,适用于常规的分布式应用场景开发。

  3. 多模块工程结构-独立boot工程模式

    a. 这种工程结构在多模块工程的基础上,通过独立的boot工程来支撑多部署方式。适用于中大型分布式应用场景开发。

    b. 然而,随着工程越来越多,我们也会面临一些问题:

    ⅰ研发:环境准备非常困难,每个模块都要单独启动,研发调试跟踪困难。

    ⅱ部署:分布式的高可靠性保证需要每个模块至少有两个部署节点,但在模块较多的情况下,起步成本非常高。同时,企业初期业务不稳定且规模较小,使用多模块工程的第二种模式会增加问题排查难度和成本。

    c. 此时,Oinone的多模块工程下的独立boot工程模式部署就可以发挥其灵活性,让研发和业务起步阶段可以选择all-in-one模式,等到业务发展到一定规模的时候,只需要把线上部署模式切换成模块独立部署,而研发还可以保留all-in-one模式的优势。

    d. 值得注意的是,分分合合的部署模式在传统互联网架构和低代码或无代码平台上都是有代价的,但是Oinone却可以灵活适配,只需要在boot工程的yml文件中写入需要加载的模块就可以解决。此处我们仅介绍多模块加载配置,选择性忽略其他无关配置,具体配置(如下图2-8所示)。

    pamirs: 
    boot:
    init: true
    sync: true
    modules:
      - base
      - resource
      - sequence
      - user
      - auth
      - web
    tenants:
      - pamirs

    图2-8 Oinone yml配置图
  4. 大型多场景工程结构-独立boot工程模式:

    a. 在多模块工程结构基础上的加强版,增加CDM层设计,让不同场景即保持数据统一,又保持逻辑独立。这种工程结构特别适用于大型企业软件开发,其中涉及到多个场景的情况,例如B端和C端的应用,或者跨不同业务线的应用,能够保证数据的一致性,同时也能够保持逻辑独立,避免不同场景间的代码冲突。

    b. 这种工程结构是我们Oinone支撑“企业级软件生态”的核心,我们可以把场景A当作我们官方应用,场景B当作其他第三方伙伴应用。在这个工程结构下,我们的客户可以定制化开发自己的应用,同时我们也可以通过这种模式来支持我们的伙伴们进行开发,实现多方共赢。

    c. 基于独立boot工程模式,我们同样对应多种部署模式应对不同情况,并统一管理所有伙伴应用。这种工程结构的优点是扩展性好,可以支持不同规模的应用,并且可以根据需要进行快速扩展或缩小规模,具有很高的灵活性。

  5. 基于标准产品的二开工程结构,是指基于标准产品进行二次开发,满足客户特定需求的工程结构。这种模式下,Oinone提供标准产品,客户可以根据自己的需求进行二次开发,实现定制化需求,同时可以利用我们的模块化开发特性,将每一个需求作为一个模块进行开发和管理。这种工程结构的优点是能够快速满足客户特定需求,同时也具有很好的可维护性和可扩展性,因为每个需求都是一个独立的模块,可以方便地进行维护和扩展。在下一篇“Oinone独特性之每一个需求都是一个模块”文章中有详细介绍。

Oinone社区 作者:史, 昂原创文章,如若转载,请注明出处:https://doc.oinone.top/oio4/9220.html

访问Oinone官网:https://www.oinone.top获取数式Oinone低代码应用平台体验

(0)
史, 昂的头像史, 昂数式管理员
上一篇 2024年5月23日 am10:02
下一篇 2024年5月23日 am10:04

相关推荐

  • 3.1.2 环境准备(windows版)

    一、后端基础环境准备 安装JDK1.8 ,高于1.8_221以上(下载地址见书籍【附件一】) 打开Windows环境变量配置页 此电脑 => 右键属性 => 系统高级设置 => 环境变量 配置环境变量 在用户环境变量中新建变量为JAVA_HOME的项,值为JDK安装之后的路径 图3-1-27 新建环境变量JAVA_HOM 编辑变量为Path的项添加一个值%JAVA_HOME%\bin 图3-1-28 添加一个环境变量值%JAVA_HOME%\\bin PowerShell或者CMD中验证,输出类似信息为安装配置成功 图3-1-29 验证JAVA是否安装成功 安装 Apache Maven 3.8+ (下载地址见书籍【附件一】) 删除Maven安装目录下的conf/settings.xml 配置mvn的settings,下载附件settings-open.xml,并重命名为settings.xml,建议直接放在【C:\Users\你的用户名.m2】下面。下载地址见oinone开源社区群公告,也可以联系oinone合作伙伴或服务人员 配置环境变量 在用户环境变量中新建变量为M2_HOME的项,值为Maven安装路径 图3-1-30 新建变量M2_HOME 编辑变量为Path的项添加一个值%M2_HOME%\bin 图3-1-31 添加一个值%M2_HOME%\\bin 验证 图3-1-32 验证Maven是否安装成功 安装 Jetbrains IDEA (下载地址见书籍【附件一】) 插件安装 下载地址 密码: mdji 如果IDEA安装了Lombok插件,请禁用Lombok插件 点击菜单项File => Settings => Plugins 图3-1-33 插件管理页面操作示意 下载插件包 (联系Oinone官方客服) 图3-1-35 操作指引 图3-1-36 操作指引 安装MySQL 8 (下载地址见书籍【附件一】) 解压下载的ZIP安装包, 复制到自定义安装目录 设置环境变量 MYSQL_BASE_DIR 提换成MySQL安装目录路径 把 %MYSQL_BASE_DIR%\bin 加入到系统环境变量中 在PowerShell中可以使用 Get-Command mysqld 命令验证环境变量是否配置成功,执行成功输出mysqld的所在路径 初始化 在命令行中执行 mysqld –initialize-insecure –user=mysql 安装 mysqld -install 启动MySQL服务 mysqld -install 设置root用户密码 alter user \’root\’@\’localhost\’ identified with mysql_native_password by \’oinone\’; flush privileges; 安装DB GUI工具 Datagrip、MySQLWorkbench、DBEaver 选其一 ### 安装Git (下载地址见书籍【附件一】) 安装GraphQL测试工具Insomnia(下载地址见书籍【附件一】) 安装RocketMQ(下载地址见书籍【附件一】) 修改安装目录下bin中对应文件的默认配置 a. runserver.cmd文件内容 -Xms2g -Xmx2g为 -Xms1g -Xmx1g b. runbroker.cmd文件内容 -Xms2g -Xmx2g为 -Xms1g -Xmx1g,以及-XX:G1HeapRegionSize=1m 启动RocketMQ NameServer命令 RocketMQ安装目录\bin\mqnamesrv.cmd start 启动RocketMQ Broker命令 RocketMQ安装目录\bin\mqbroker.cmd -n localhost:9876 停止 RocketMQ命令 mqshutdown.cmd broker mqshutdown.cmd namesrv 安装ElasticSearch 版本 8.4.1(下载地址见书籍【附件一】) (非必须) ES运行时需要JDK18及以上版本JDK运行环境, ES安装包中包含了一个JDK18版本 set JAVA_HOME=ES安装路径\jdk 启动 ES安装路径\bin\elasticsearch.bat 停止 ctrl+c 或者关闭cmd、PowerShell的窗口 安装Redis (下载地址见书籍【附件一】) 解压安装包到安装目录 在PowerShell进入到Redis安装目录 在PowerShell中执行.\redis-server.exe,输出图中类似信息(如下图3-35所示): 图3-1-37 验证redis是否安装成功 新开PowerShell窗口, 进入到Redis安装目录, 执行 .\redis-cli.exe回车,输入 ping 回车输出 PONG即表示Redis安装成功 图3-1-38 验证redis是否安装成功 Zookeeper安装(下载地址见书籍【附件一】) 解压安装, 在 PowerShell中执行 tar zxvf 安装包路径(tar.gz包) -C Zk安装目录 进入 Zk安装目录\conf\ 复制 zoo_sample.cfg文件为 zoo.cfg 修改zoo.cfg文件的内容 (其中dataDir需要自己设定) tickTime=2000…

    2024年5月23日
    2.8K00
  • 流程类

    1.流程类 1.1 审批 审批节点配置步骤: 添加审批节点 选择审批的模型和视图 设置审批人和通过方式 设置审批人在审批时的操作权限和数据权限 1.1.1 审批节点 审批节点只能放置在有数据可审批的流程链路上,审批分支只能放置在审批节点后。 1.1.2 审批模型和视图 可选的审批模型包含添加的审批节点之前的所有能获取到数据的模型。可选视图为该选择的数据模型关联的界面设计器中视图类型为表单的页面。 1.1.3 审批人和通过方式 审批人可在个人、部门、角色和模型中的字段里复选。当某人在不同类型人员选择中被重复选中,只会收到一次审批的代办。若为多人审批,审批是同步进行的。 单人审批: 通过方式:唯一通过方式,同意通过,拒绝否决 多人审批: 通过方式:或签/会签(默认或签) a. 或签(一名审批人同意或拒绝即可) 任意一位审批人操作通过或否决后流程就结束,其他审批人无法进入审批操作,但是会弹出消息提示审批结果。 场景:紧急且影响不大的审批可以由任意一位领导层或签。 b. 会签(需所有审批人同意才为同意,一名审批人拒绝即为拒绝) 场景:影响比较重大的审批,一票否决的形式决定是否通过。 c. 会签(一名审批人同意即为同意,需所有审批人拒绝才为拒绝) 场景:需要评估项目可操作性时,若有领导觉得有意义就通过,进入下一步评估,全员否决就否决项目。 1.1.4 操作&数据权限 操作权限 可设置是否必填拒绝原因、是否允许转交、是否允许加签、是否允许退回。 选择允许转交或允许加签之后,可选择添加人员的候选名单,不填默认所有人都可选。 选择允许退回后,可以选择退回到该审批节点之前的任意审批节点。ps:需所有审批人拒绝才为拒绝的会签不允许退回。 数据权限 选择视图后自动显示该视图下的数据字段,可选择的权限为查看、编辑、隐藏数据字段,默认可查看全部字段。 1.1.5 参与人重复 勾选参与人重复的场景时,满足场景的审批流程会由系统自动审批通过。 1.2 填写 当流程需要某些人提交数据才能继续时,可以使用填写这个动作。区别于数据类中的操作,填写这个动作只能修改当前触发模型中关联的视图表单,而数据类中的更新数据可以修改其他模型中的数据。 和审批动作相似,填写动作需要选择填写的模型和视图表单,需要选择填写人,可以选择添加转交权限。另外,填写动作必须包含一个及以上的可编辑的数据权限供操作人填写。

    2024年5月23日
    1.6K00
  • 3.5.6.3 布局的配置

    布局是将页面拆分成一个一个的小单元,按照上下中左右进行排列。 前沿 在前端领域中,布局可以分为三大块「Float、Flex、Grid 」,Float可以说的上是上古时期的布局了,如今市面还是很少见的,除了一些古老的网站。 目前,平台主要支持通过配置XML上面的cols和span来进行布局。平台也同样支持自由布局,合理的使用row、col、containers和container四个布局容器相关组件,将可以实现各种类型的布局样式,换句话说,平台实现的自由布局功能是Flex和Grid的结合体。 这里主要是讲解Flex和Grid布局,以及目前新的模板布局实现的思路。 Flex布局 Flex布局采用的是一维布局,那么什么是一维布局呢,所谓的一维布局就是只有一个方向、没有体积、面积,比如一条直线。它适合做局部布局,就像我们原来的顶部菜单、面包屑导航,以及现在的主视图字段配置。 图3-5-6-19 Flex布局示意 图3-5-6-20 Flex布局示意 图3-5-6-21 Flex布局示意 从上图可以看看出,Flex布局只能在X、Y轴进行转换,它无法对上下左右四个方向同时处理,因为它没“面积”的概念。所以它最适合做局部布局。 优点 图3-5-6-22 Flex兼容性 Flex的兼容性,可以看得出来,目前主流的浏览器都支持该属性。所以Flex兼容性强,如果你想对局部做布局处理,Flex是最好选择。 缺陷 刚刚也提到了,用户想要的布局是千奇百怪的,如果他想要的布局在现有的功能中无法实现怎么办?让用户放弃?还是说服他使用现在的布局。 Grid布局 Grid布局系统采用的是二维布局,二维布局有四个方向:上、下、左、右,它只有面积没有体积,比如一张纸、网格。 Grid布局 <div id="grid-container-one"> <div class="one-1">Grid Item 1</div> <div>Grid Item 2</div> <div>Grid Item 3</div> <div>Grid Item 4</div> <div>Grid Item 5</div> <div class="one-6">Grid Item 6</div> </div> <div id="grid-container-two"> <div class="tow-1">Grid Item 1</div> <div class="tow-2">Grid Item 2</div> <div>Grid Item 3</div> <div>Grid Item 4</div> <div>Grid Item 5</div> <div>Grid Item 6</div> </div> <div id="grid-container-three"> <div>Grid Item 1</div> <div>Grid Item 2</div> <div class="grid">Grid Item 3</div> <div class="grid-column">Grid Item 4</div> <div>Grid Item 5</div> <div>Grid Item 6</div> <div>Grid Item 7</div> <div class="grid-column">Grid Item 8</div> </div> HTML CSSResult Skip Results Iframe EDIT ON * { box-sizing: border-box; padding: 0; margin: 0; line-height: 1.5; font-weight: bold; text-align: center; } #grid-container-one{ background-color: black; display: grid; grid-template-columns: repeat(3, 1fr); grid-template-rows: repeat(2, 50px); gap: 10px; border: solid black 2px; margin-bottom: 20px; color: salmon; } #grid-container-one div { border: solid white 2px; padding: 10px; } #grid-container-one .one-1 { grid-area: span 1/span 3; text-aligin: center } #grid-container-one .one-6 { grid-column: 3 /4; } #grid-container-two{ background-color: CADETBLUE; display: grid; grid-template-columns: 15% repeat(2, 1fr);…

    2024年5月23日
    1.4K00
  • 3.6 问题排查工具

    当前端发起对应用的访问时,如果出现错误,那么我们可以通过以下方式进行简易排查,如果排查不出来,则也可以把排查工具给出的信息发送给Oinone官方售后进行进一步分析。本文将通过模拟异常信息,来介绍排查工具,提供了哪些辅助信息帮我们来快速定位问题。 排查工具基础介绍 通过前端页面的 /debug 路由路径访问调试工具的页面,假设我们的前端页面访问地址为http://localhost:6800,那么我们的排查工具请求路径就是 http://localhost:6800/debug排查工具可以帮我们排查前端页面元数据异常和后端接口的异常 排查前端页面元数据 将问题页面浏览器地址栏内 page 后的部分复制到调试工具的 debug 路由后重新发起请求,如图可以看到调试工具展示的信息,可以根据这些信息排查问题。 排查后端接口 后端接口出现问题后,打开(在原页面)浏览器的调试工具,切换到“网络”的标签页,在左侧的历史请求列表中找到需要调试的请求,右键会弹出菜单,点击菜单中的 “复制”,再次展开该菜单,点击二级菜单中的“以 fetch 格式复制”,这样可以复制到调试所需要的信息 2.复制调试信息到“接口调试”标签页内的文本框内,点击“发起请求”按钮获取调试结果 我们可以看到页面展示了该接口的各种调试信息,我们可以据此排查问题。 场景化的排查思路 业务代码中存在代码bug 报错后发起调试请求,我们可以看到,调试工具直接给出了异常抛出的具体代码所在位置,此时再切换到“全部堆栈”下,可以看到是业务类的233行导致的空指针异常,查看代码后分析可得是data.getName().eqauls方法在调用前未做条件判断补全该判断后代码可以正常执行 业务代码中没有直接的错误,异常在平台代码中抛出 报错后发起调试请求可以看到异常不在业务代码内再切换到“全部堆栈”,可以看到具体异常信息,提示core_demo_item表出现了重复的主键,该表是DemoItem模型的我们还可以切换到“sql调试”的标签页,可以看到出错的具体sql语句经过分析可以得知是240行的data.create()�重复创建数据导致的。 三、排查工具无法定位怎么办 当我们通过排查工具还是没有定位到问题的时候,可以通过调试页面的“下载全部调试数据”和“下载调试数据”按钮将调试信息的数据发送给官方售后人员帮助我们定位排查问题。 点击页面最顶部的“下载全部调试数据”按钮,可以下载页面调试数据和接口调试数据点击“调试接口”标签页内的“下载调试数据”按钮,可以下载接口调试数据 四、排查工具细节

    2024年5月23日
    1.7K00
  • 3.3.7 字段之序列化方式

    本文核心是带大家全面了解oinone的序列方式,包括支持的序列化类型、注意点、如果新增客户化序列化方式以及字段默认值的反序列化。 一、数据存储的序列化 (举例) 使用@Field注解的serialize属性来配置非字符串类型属性的序列化与反序列化方式,最终会以序列化后的字符串持久化到存储中。 ### Step1 新建PetItemDetail模型、并为PetItem添加两个字段 PetItemDetail继承TransientModel,增加两个字段,分别为备注和备注人 package pro.shushi.pamirs.demo.api.tmodel; import pro.shushi.pamirs.meta.annotation.Field; import pro.shushi.pamirs.meta.annotation.Model; import pro.shushi.pamirs.meta.base.TransientModel; import pro.shushi.pamirs.user.api.model.PamirsUser; @Model.model(PetItemDetail.MODEL_MODEL) @Model(displayName = "商品详情",summary = "商品详情",labelFields = {"remark"}) public class PetItemDetail extends TransientModel { public static final String MODEL_MODEL="demo.PetItemDetail"; @Field.String(min = "2",max = "20") @Field(displayName = "备注",required = true) private String remark; @Field(displayName = "备注人",required = true) private PamirsUser user; } 图3-3-7-1 PetItemDetail继承TransientModel 修改PetItem,增加两个字段petItemDetails类型为List和tags类型为List,并设置为不同的序列化方式,petItemDetails为JSON(缺省就是JSON,可不配),tags为COMMA。同时设置 @Field.Advanced(columnDefinition = varchar(1024)),防止序列化后存储过长 package pro.shushi.pamirs.demo.api.model; import pro.shushi.pamirs.demo.api.tmodel.PetItemDetail; import pro.shushi.pamirs.meta.annotation.Field; import pro.shushi.pamirs.meta.annotation.Model; import pro.shushi.pamirs.meta.enmu.NullableBoolEnum; import java.math.BigDecimal; import java.util.List; @Model.model(PetItem.MODEL_MODEL) @Model(displayName = "宠物商品",summary="宠物商品",labelFields = {"itemName"}) public class PetItem extends AbstractDemoCodeModel{ public static final String MODEL_MODEL="demo.PetItem"; @Field(displayName = "商品名称",required = true) private String itemName; @Field(displayName = "商品价格",required = true) private BigDecimal price; @Field(displayName = "店铺",required = true) @Field.Relation(relationFields = {"shopId"},referenceFields = {"id"}) private PetShop shop; @Field(displayName = "店铺Id",invisible = true) private Long shopId; @Field(displayName = "品种") @Field.many2one @Field.Relation(relationFields = {"typeId"},referenceFields = {"id"}) private PetType type; @Field(displayName = "品种类型",invisible = true) private Long typeId; @Field(displayName = "详情", serialize = Field.serialize.JSON, store = NullableBoolEnum.TRUE) @Field.Advanced(columnDefinition = "varchar(1024)") private List<PetItemDetail> petItemDetails; @Field(displayName = "商品标签",serialize = Field.serialize.COMMA,store = NullableBoolEnum.TRUE,multi = true) @Field.Advanced(columnDefinition = "varchar(1024)") private…

    2024年5月23日
    1.3K00

Leave a Reply

登录后才能评论