Oinone构建分布式项目一些注意点

1. Oinone如何支持构建分布式项目

参考文档:https://doc.oinone.top/kai-fa-shi-jian/5572.html

2. Oinone远程服务发布范围

泛化服务范围,可选值:module、namespace
module:按模块维度发布远程服务
namespace:按Fun的namespace维度发布远程服务
默认按module维度发布服务

pamirs:
  distribution:
    service:
      #serviceScope: 可选值namespace、module
      serviceScope: module

3.关闭Dubbo服务注册元数据上报日志

logging:
  level:
    root: info
    pro.shushi.pamirs.framework.connectors.data.mapper.PamirsMapper: error
    pro.shushi.pamirs.framework.connectors.data.mapper.GenericMapper: error # mybatis sql日志
    RocketmqClient: error
    org.apache.dubbo.registry.zookeeper.ZookeeperRegistry: error
    org.apache.dubbo.registry.integration.RegistryDirectory: error
    org.apache.dubbo.config.ServiceConfig: error
    com.alibaba.nacos.client.naming: error
    org.apache.dubbo.registry.nacos.NacosRegistry: error
    org.apache.dubbo.registry.support.AbstractRegistryFactory: error
    org.apache.dubbo.registry.integration.RegistryProtocol: error
    org.apache.dubbo.registry.client.metadata.store.RemoteMetadataServiceImpl: off
    org.apache.dubbo.metadata.store.zookeeper.ZookeeperMetadataReport: off
    org.apache.dubbo.metadata.store.nacos.NacosMetadataReport: off

4.Naocs配置列表出现多余配置

dubbo 集成 nacos注册中心,会出现多余的配置,详细参考:
配置列表会自动创建很多无关的配置: https://github.com/apache/dubbo/issues/6645
配置列表出现多余的配置:https://github.com/alibaba/nacos/issues/8843

按照下面的配置可以将其关闭(📢主要是这三项配置use-as-config-center, use-as-metadata-center,metadata-report.failfast),已生成的配置需要手动删除掉。

dubbo:
  application:
    name: pamirs-demo
    version: 1.0.0
    metadata-type: local
  registry:
    id: pamirs-demo-registry
    address: nacos://192.168.0.129:8848
    username: nacos
    password: nacos
    # dubbo使用nacos的注册中心往配置中心写入配置关闭配置
    use-as-metadata-center: false
    use-as-config-center: false
  config-center:
    address: nacos://192.168.0.129:8848
    username: nacos
    password: nacos
  metadata-report:
    failfast: false # 关闭错误上报的功能
    address: nacos://192.168.0.129:8848
    username: nacos
    password: nacos
  protocol:
    name: dubbo
    port: -1
    serialization: pamirs
  scan:
    base-packages: pro.shushi
  cloud:
    subscribed-services:

Oinone社区 作者:望闲原创文章,如若转载,请注明出处:https://doc.oinone.top/kai-fa-shi-jian/6475.html

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

Like (0)
望闲's avatar望闲数式管理员
Previous 2024年1月20日 am9:49
Next 2024年2月2日 am10:25

相关推荐

  • 问题排查调试工具使用手册

    当前端发起对应用的访问时,如果出现错误,那么我们可以通过以下方式进行简易排查,如果排查不出来,则也可以把排查工具给出的信息发送给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月21日
    3.1K00
  • 灵活敏捷开发,高效交付项目的6个关键

    项目工程管理 项目工程顶层分层 项目分层设计,划分出 CDM层、 标准业务层 、定制业务层; 沉淀领域业务模型至CDM层; 沉底业内通用功能至标准业务层; 客户定制化功能在定制业务层; 项目内部的层级划分 项目包结构管理及规范 pamirs-demo-api constant【常量的包路径】 enums【枚举类的包路径】 model【该领域核⼼模型的包路径】 pmodel【该领域代理模型的包路径】 tmodel【该领域传输模型的包路径】 service【存放该领域的⾮存储模型如:⽤于传输的临时模型】 utils【工具类】 XXModule【该类是Demo模块的定义】 pamirs-demo-core service【接口实现类】 init【模块初始化⼯作的包路径】 manager 【manager是 service的⼀些公共逻辑,不会定义为独⽴的function的类】 pamirs-demo-view(可选) action【模型对外交互的⾏为的包路径】 项目中模块间依赖 禁止出现api模块依赖core模块的情况,api模块只允许依赖api模块; 根据当前项目结构进行模块划分,避免循环依赖; 规划项目模块 项目阶段,代码开发前,业务架构师需充分的理解需求和蓝图,对系统进行业务域, 功能域的划分;例如:对一个电商系统: 提高系统的可维护性:通过将系统拆分为不同的业务域,每个业务域都有清晰的边界和职责,可以独立开发、测试和维护; 提升开发效率:业务域划分可以使开发团队更加专注于自己负责的业务,减少不必要的沟通和协调,提升开发效率; 促进团队合作:通过业务域划分,每个团队可以负责一个或多个业务域,团队成员之间可以有更高效的合作和协同。 支持系统的扩展和演化:业务域划分可以使系统更加灵活和可扩展。当需要新增一个新的业务功能或调整现有的业务逻辑时,只需要修改对应的业务域,而不需要对整个系统进行改动。 项目文档管理 项目文档管理对于项目的实施,项目进度管理,项目后期维护等都是至关重要的。系统详细的产品文档,测试文档,运维文档,开发文档,项目管理文档等。 协同合作:团队成员可以共享和访问项目文档,促进协同合作和信息共享,避免信息孤岛和重复工作。 知识管理:项目中所获得的知识,对项目的成功和后续的知识积累至关重要。通过良好的文档管理,可以确保项目知识的保存和传承,提高组织的知识管理能力。 问题解决:项目文档中记录了项目的需求、决策、问题和解决方案等信息。当出现问题或需要做决策时,可以通过查阅文档来获取相关信息,加快问题解决的速度,并减少错误和重复。 项目追踪:通过文档管理,可以跟踪项目的进展和状态。可以记录项目的里程碑、任务分配、进度更新等信息,帮助团队了解项目的整体情况,及时发现和解决问题。 知识共享:好的文档管理可以促进知识共享和传播。通过将项目文档进行分类、索引和存档,可以使团队成员更容易找到所需的信息,并从中学习和借鉴经验,提高工作效率和质量。 数据库和事务 多表联合查询 减少需要join的操作出现 用多次查询替代 索引相关 核心业务访问DB的Sql 要命中或者覆盖索引,保存核心业务的响应时间; 控制单表的索引数量,注意联合索引 数据一致性:乐观锁控制,unique�等 事务代码示例 事务相关注意点参考【Oinone如何支持构建分布式项目】:https://doc.oinone.top/kai-fa-shi-jian/5572.html

    2024年2月20日
    1.4K00
  • 树形下拉组件数据查询覆写

    一、背景与问题 Oinone 的树形下拉组件(TreeSelect)和树视图(Tree)在查询数据时,最终调用的是树节点所配置模型的数据管理器函数: 树接口 调用的数据管理器函数 场景 fetchAll queryListByWrapper 一次性全量加载 fetchChildren queryPage 按层级懒加载(默认) queryKeywords4Tree queryListByWrapper 关键字搜索 reverselyQuery queryListByWrapper 已选数据回填 官方文档原文:「所有树查询接口都会调用模型对应的数据管理器函数,可以通过重写的方式修改其查询结果。」 直接覆写的风险 如果直接在原模型(如 business.PamirsDepartment)上覆写 queryPage: // ⚠️ 危险写法:会影响所有使用 PamirsDepartment.queryPage 的场景 @Component @Model.model(PamirsDepartment.MODEL_MODEL) public class DeptQueryAction { @Function.Advanced(type = FunctionTypeEnum.QUERY, category = FunctionCategoryEnum.QUERY_PAGE) @Function.fun(FunctionConstants.queryPage) @Function(openLevel = {FunctionOpenEnum.LOCAL, FunctionOpenEnum.REMOTE, FunctionOpenEnum.API}) public Pagination<PamirsDepartment> queryPage(Pagination<PamirsDepartment> page, IWrapper<PamirsDepartment> queryWrapper) { // 追加过滤条件… return new PamirsDepartment().queryPage(page, queryWrapper); } } 该覆写会全局生效——不仅是树形下拉,所有调用 PamirsDepartment 的 queryPage 的地方(组织架构页面、人员管理列表、权限分配、框架内部关联查询等)都会受到影响,容易引发难以排查的副作用。 二、推荐方案:代理模型(PROXY)隔离 核心思路 创建一个继承原模型的代理模型(ModelTypeEnum.PROXY),拥有独立的模型命名空间 在代理模型中重新声明自关联字段(如 parent),将关联目标指向代理模型自身 在代理模型的 Action 中覆写数据管理器函数,追加树形场景专属的过滤逻辑 树形下拉的视图 DSL 中,<node> 的 model 指向代理模型 代理模型与原模型共享同一张数据表,但函数注册在各自独立的命名空间下,互不干扰。 框架官方示例 Oinone 框架自身就采用了这一模式:ResourceRegionProxyModel 继承 ResourceRegion,用于地区页面的代理展示,其扩展点 ResourceRegionProxyModelExtPoint 中的 queryPageAfter 只影响代理模型自身的查询。 三、完整实现步骤(以 PamirsDepartment 为例) 场景假设 业务需求:某个表单页面的「部门」树形下拉只需要展示当前公司(companyCode == 当前用户公司)且启用状态(dataStatus == ENABLED)的部门,而系统中其他使用 PamirsDepartment 的地方(组织架构、权限管理等)不受影响。 步骤 1:定义代理模型 package com.example.demo.model; import pro.shushi.pamirs.meta.annotation.Field; import pro.shushi.pamirs.meta.annotation.Model; import pro.shushi.pamirs.meta.enmu.ModelTypeEnum; import pro.shushi.pamirs.business.api.model.PamirsDepartment; import java.util.List; /** * 部门树形下拉专用代理模型 * <p> * 继承 PamirsDepartment,共享同一张数据表, * 但拥有独立的函数命名空间,覆写 queryPage 不影响原模型。 */ @Model.model(DeptTreeProxy.MODEL_MODEL) @Model.Advanced(type = ModelTypeEnum.PROXY) @Model(displayName = "部门(树选择)", labelFields = "name") public class DeptTreeProxy extends PamirsDepartment { public static final String MODEL_MODEL = "demo.DeptTreeProxy"; /** * 【必须重新声明】上级部门(自关联字段) * <p> * 基类 PamirsDepartment 中 parent 的类型是 PamirsDepartment, * 代理模型必须将其覆盖为指向自身(DeptTreeProxy), * 否则设计器/树组件无法在代理模型命名空间内构成完整的自关联关系, * 导致树形下拉无法正确展开层级。 */ @Field.many2one @Field.Relation(relationFields = {"parentCode"}, referenceFields = {"code"}) @Field(displayName = "上级部门")…

    后端 2026年7月27日
    27800
  • 项目中常用的 Tools 工具类

    模型拷贝工具类 KryoUtils.get().copy(modelData); ArgUtils.convert(DataReport.MODEL_MODEL, DataDesignerReport.MODEL_MODEL, report); pro.shushi.pamirs.framework.common.utils.ObjectUtils#clone(T) Rsql工具类 RsqlParseHelper.parseRsql2Sql(queryWrapper.getModel(), rsql); RSQLHelper.getRsqlValues(sql.getOriginRsql(), fieldSet); 序列化工具类 后端使用的JSON序列化 JsonUtils.toJSONString(nodes); 前端使用的JSON序列化 PamirsJsonUtils.toJSONString(nodes, SerializerFeature.DisableCircularReferenceDetect, SerializerFeature.WriteDateUseDateFormat, SerializerFeature.BrowserCompatible); 生成ID //根据模型生成id Long generate = (Long) Spider.getDefaultExtension(IdGenerator.class).generate(PamirsTableInfo.fetchKeyGenerator(Teacher.MODEL_MODEL)); //生成id Long l = Long.valueOf(UidGeneratorFactory.getCachedUidGenerator().getUID()); 权限相关 // 获取权限路径path AccessResourceInfoSession.getInfo().getOriginPath(); 其他 PamirsSession相关 PamirsSession.isAdmin() # 是否admin用户 PamirsSession.getUserId() # 获取登录用户ID PamirsSession.getRequestVariables() PamirsSession.getContext().getModelCache().get(PetShop.MODEL_MODEL).getTable(); # 获取模型信息 PamirsSession.getContext().getExtendCache(ActionCacheApi.class).get(Teacher.MODEL_MODEL, "importArchivesInfo") # 获取函数信息

    2025年5月8日
    1.3K01
  • GQL GET 请求生成图片文件流 — 技术实现方案

    GQL GET 请求生成图片文件流 — 技术实现方案 基于 Oinone/Pamirs GQL GET 文件流机制,参考 FileAction#downloadFormData(查询型)与 ExcelExportTaskAction#createExportTask(同步写流),实现「按业务 ID 动态生成图片并输出文件流」的通用指南。 1. 背景与目标 1.1 需求 在业务场景中,需要根据业务 ID(如订单 ID、模板 ID、单据 ID)在后端动态渲染图片(条码、标签、证书、预览图等),并将结果以文件流形式返回给前端。 1.2 约束 复用 Oinone 既有鉴权、会话、模块路由体系,不新增独立 REST 下载接口。 与 Excel 同步导出保持一致的调用方式:通过 GET 访问 /pamirs/{module}?query=…&variables=…。 前端仅两种消费方式: 页面预览:<img :src="imageUrl" /> 触发下载:window.open(imageUrl, '_blank') 2. 参考实现 2.1 查询型文件流(图片查看应对齐此模式) 图片查看属于只读查询,应使用 query + @Function(type = QUERY),与 CDN 文件下载一致: // @oinone/kunlun-vue-ui-common/…/UploadService.ts const gql = `query{resourceFileFormQuery{downloadFormData(resourceFileForm:{downloadUrl:"${url}"}){filename}}}`; window.open(UrlHelper.appendBasePath(`/pamirs/file?query=${encodeURIComponent(gql)}`), '_blank'); // pamirs-core/pamirs-file2/…/FileAction.java @Function.Advanced(displayName = "前端下载数据", type = FunctionTypeEnum.QUERY) public ResourceFileForm downloadFormData(ResourceFileForm resourceFileForm) { // 直接写 HttpServletResponse 输出流 response.setContentType("application/octet-stream"); response.setHeader("Content-Disposition", "attachment; filename=" + …); IOUtils.copy(inputStream, response.getOutputStream()); return new ResourceFileForm(); } 图片查看用 GQL.query,不用 GQL.mutation。 2.2 同步写流机制(共用) 无论 query 还是 mutation,文件流输出的底层机制相同:在 Function/Action 执行过程中直接写 HttpServletResponse。 2.2.1 HTTP 网关:RequestController GET /pamirs/{moduleName}?query={gql}&variables={json} POST /pamirs/{moduleName} body: { query, variables } GET 与 POST 走同一执行链路: // pamirs-framework/pamirs-gateways-graph-java/…/RequestController.java @RequestMapping(value = "/pamirs/{moduleName}", method = RequestMethod.GET) public DeferredResult<String> pamirsGet( @PathVariable("moduleName") String moduleName, @RequestParam("query") String gql, @RequestParam(value = "variables", required = false) String variables, …) { PamirsClientRequestParam gqlRequest = new PamirsClientRequestParam(); gqlRequest.setQuery(gql); if (!StringUtils.isBlank(variables)) { gqlRequest.setVariables(JsonUtils.parseMap(variables)); } return pamirsPost(moduleName, gqlRequest, request, response); } variables.path 在 RequestHelper.preparePamirsRequestParam 中经 SessionPrepareApi.prepare 注入会话上下文,与前端 getSessionPath() 对应。 2.2.2 Excel 导出对照:ExcelFileServiceImpl#doExportSync Excel 同步导出使用 mutation(createExportTask),因为会创建导出任务记录;图片查看无此副作用,故用 query。 同步导出的关键:劫持 FileClient.upload,将字节直接写入当前…

    2026年7月2日
    28600

Leave a Reply

Please Login to Comment