1. 项目概述LoongFlow一个为龙芯生态量身定制的开源工作流引擎最近在开源社区里我注意到一个挺有意思的项目——LoongFlow。这个名字本身就很有指向性“Loong”显然指的是龙芯LoongArch架构而“Flow”则直指工作流。简单来说这是一个专门为龙芯平台设计和优化的开源工作流引擎。对于正在龙芯生态里耕耘的开发者或者对国产化技术栈有部署需求的企业技术团队来说这无疑是一个值得深入研究的工具。工作流引擎听起来可能有点抽象但它在企业级应用开发中扮演着“中枢神经”的角色。想象一下一个复杂的业务流程比如请假审批、订单处理、数据报表生成往往涉及多个步骤、多个角色和复杂的流转逻辑。如果全靠硬编码来实现代码会变得极其臃肿且难以维护。工作流引擎的作用就是将业务流程中的步骤、规则、参与者抽象出来通过可视化的方式或领域特定语言DSL进行定义然后由引擎来驱动执行、管理状态和分配任务。这样一来业务逻辑和流程控制逻辑就实现了分离系统的灵活性和可维护性大大提升。那么为什么需要一个专门为龙芯优化的LoongFlow呢这背后反映的是国产化替代浪潮下的真实需求。随着龙芯中科自主研发的LoongArch指令集架构日益成熟基于龙芯CPU的服务器、PC终端开始在各个关键领域部署。然而软件生态的迁移并非简单的“拿来主义”。许多主流的开源工作流引擎如Activiti、Flowable、Camunda等其核心代码和依赖库尤其是涉及JNI本地调用、特定汇编优化的部分在x86/ARM架构上经过了长期优化直接移植到LoongArch架构上可能会遇到性能瓶颈、兼容性问题甚至根本无法编译运行。LoongFlow的出现正是为了解决这个“最后一公里”的问题。它并非从零造轮子而是在充分理解工作流核心范式BPMN 2.0标准的基础上针对LoongArch架构的特点进行深度适配和优化。这意味着从底层的任务调度算法、内存模型访问到上层的API设计和与龙芯平台常见中间件如达梦数据库、东方通中间件的集成都做了针对性考量。对于需要在纯国产化环境中部署复杂业务流程系统的团队而言LoongFlow提供了一个经过验证的、性能可预期的底层支撑避免了在通用引擎上“踩坑”和二次适配的巨大成本。2. 核心架构与设计哲学为何选择BPMN与微内核2.1 拥抱标准以BPMN 2.0为基石LoongFlow在设计之初就明确将BPMN 2.0Business Process Model and Notation业务流程模型与标记法作为其流程定义的核心标准。这是一个非常关键且明智的选择。BPMN 2.0是对象管理组织OMG维护的开放标准它定义了一套丰富的图形化符号和XML模式用于描述业务流程。为什么坚持标准如此重要首先降低学习与迁移成本。对于已经熟悉Activiti、Flowable等引擎的开发者BPMN 2.0是他们共同的语言。LoongFlow支持标准的BPMN元素如开始/结束事件、用户任务、服务任务、网关、边界事件等意味着开发者已有的流程设计知识和建模工具如Eclipse BPMN2 Modeler、Camunda Modeler可以很大程度上复用。他们不需要学习一套全新的流程定义语言只需关注LoongFlow在龙芯平台上的特定扩展和配置。其次保障流程定义的互操作性。一个用标准BPMN 2.0 XML描述的流程模型理论上可以在不同引擎间进行交换尽管引擎对高级特性的支持度可能不同。这为未来可能的系统迁移或异构环境集成提供了便利。最后工具生态的可用性。围绕BPMN 2.0有丰富的可视化设计器、模拟器、分析工具。LoongFlow可以借助这些现有生态让用户专注于用图形化方式设计流程而引擎则负责准确执行这些标准化的定义。注意虽然LoongFlow以BPMN 2.0为核心但在实现上可能会对某些非常复杂或使用频率低的BPMN特性进行裁剪或提供简化实现以优先保障核心路径在龙芯平台上的性能和稳定性。在选择高级特性如复杂事件子流程、补偿处理器时需要仔细查阅LoongFlow的文档确认其支持程度。2.2 微内核与可插拔架构LoongFlow采用了微内核架构这是其适应国产化环境多样性的关键。微内核架构意味着引擎有一个非常精简、稳定的核心Kernel只负责最基础、最通用的流程驱动逻辑比如流程实例的创建与推进、活动实例的生命周期管理、基本的事件派发等。而其他所有特定功能都被实现为围绕核心的插件Plugin或扩展点Extension Point。这包括持久化插件负责将流程定义、运行实例、历史数据存储到数据库。LoongFlow默认可能提供针对MySQL/PostgreSQL的适配但更重要的是它应该易于扩展以支持国产数据库如达梦DM、人大金仓Kingbase、南大通用Gbase等。插件需要处理不同数据库在方言SQL语法、事务隔离级别、自增主键机制等方面的差异。身份认证与用户目录插件用于集成企业的组织架构。这可能需要对接LDAP、Active Directory或国内常见的统一身份认证系统。任务分配处理器定义如何将用户任务分配给具体的人或组。可以是基于表达式、脚本或调用外部服务。外部服务调用器用于执行“服务任务”如调用HTTP REST API、RPC服务、消息队列或本地Java方法。事件监听器允许开发者在流程的特定节点如任务创建、完成、流程启动结束注入自定义逻辑。这种设计带来的核心优势高度可定制化用户可以根据自己的技术栈选型像搭积木一样组装引擎。如果项目使用达梦数据库和东方通应用服务器就引入对应的持久化插件和事务管理插件如果需要与内部审批系统对接就开发一个特定的任务分配插件。核心稳定核心引擎的代码量小逻辑清晰更容易保证其在LoongArch架构上的正确性和高性能。功能扩展不会污染核心代码。便于生态建设社区可以针对不同的国产软硬件环境开发并贡献各类插件丰富LoongFlow的生态。2.3 针对LoongArch的深度优化考量这是LoongFlow区别于其他通用工作流引擎的根本。其优化可能体现在多个层面指令集敏感代码优化对于计算密集型的核心算法如流程跳转的条件判断、表达式求值EL表达式、Spring EL等可能会使用LoongArch指令集特有的优化或者确保JIT编译器如龙芯平台上的OpenJDK能生成高效的本地代码。团队可能会重写某些关键的数据结构如用于缓存流程定义的高效映射表的访问逻辑以更好地利用LoongArch的缓存层次和内存访问模式。内存模型与并发控制适配Java内存模型JMM在不同CPU架构上的表现有细微差别。LoongFlow需要确保其内部的状态管理、乐观锁控制常用于历史记录更新等并发机制在LoongArch的多核处理器上表现正确且高效避免因内存屏障Memory Barrier或缓存一致性协议差异导致的隐蔽bug。本地库Native Library适配如果引擎依赖了某些本地库进行高性能计算或特定操作如图形处理、密码学操作那么这些库必须提供LoongArch的版本或者由LoongFlow团队提供纯Java的替代实现。构建与依赖管理项目的Maven/Gradle构建脚本需要能够正确处理LoongArch架构的标识确保能拉取到对应架构的依赖如果有的话或者在编译时选择正确的源码分支进行构建。3. 从零开始LoongFlow的部署与核心配置实战3.1 环境准备与基础依赖假设我们在一台搭载LoongArch64架构CPU的服务器上如龙芯3A5000/3C5000系列进行部署。基础软件栈建议如下操作系统统信UOS、麒麟软件等国产操作系统或社区版的Loongnix。Java环境龙芯提供的OpenJDK 8或OpenJDK 11建议11以获得更好的容器支持和性能。务必从龙芯官方渠道获取确保JVM针对LoongArch进行了优化。# 检查Java版本 java -version # 输出应包含“LoongArch64”字样数据库以达梦数据库DM8为例。需要提前安装并创建好一个用于LoongFlow的数据库和用户。LoongFlow项目通常通过Maven进行依赖管理。在你的Spring Boot项目的pom.xml中需要添加LoongFlow的starter依赖如果项目提供了的话或者手动添加核心模块依赖。!-- 假设LoongFlow已发布到Maven中央仓库或某个私有仓库 -- dependency groupIdcom.github.baidu-baige/groupId artifactIdloongflow-spring-boot-starter/artifactId version{最新版本}/version /dependency !-- 达梦数据库JDBC驱动 -- dependency groupIdcom.dameng/groupId artifactIdDmJdbcDriver18/artifactId version8.1.3.62/version /dependency3.2 数据库初始化与连接配置LoongFlow需要一系列表来存储流程定义、运行时数据、历史数据等。它应该会提供数据库初始化脚本SQL文件这些脚本需要针对不同的数据库类型。找到针对达梦数据库的脚本例如schema-dm8.sql。关键步骤使用达梦管理工具或命令行连接到为目标业务创建的数据库实例。执行LoongFlow提供的DDL脚本。务必注意达梦数据库与MySQL/PostgreSQL在数据类型、约束语法上存在差异。LoongFlow提供的脚本应该是已经适配过的。如果遇到语法错误需要对照达梦文档进行微调常见的调整点包括自增字段定义、注释语法、索引创建语句等。在Spring Boot的application.yml中配置数据源和LoongFlowspring: datasource: url: jdbc:dm://localhost:5236/LOONGFLOW_DB?schemaLOONGFLOW_SCHEMAzeroDateTimeBehaviorconvertToNulluseUnicodetruecharacterEncodingutf-8 username: loongflow_user password: your_strong_password driver-class-name: dm.jdbc.driver.DmDriver hikari: # 连接池配置根据实际压力调整 maximum-pool-size: 20 minimum-idle: 5 loongflow: # 是否自动部署classpath下的流程定义文件 auto-deploy: true # 流程定义文件扫描路径 deployment-location: classpath:/processes/ # 数据库表前缀用于多租户隔离或避免表名冲突 database-table-prefix: LF_ # 历史数据记录级别none, activity, audit, full history-level: audit实操心得在国产化环境中数据库连接池的配置需要格外小心。达梦数据库的连接建立和销毁成本可能与MySQL不同。建议在测试环境对maximum-pool-size、connection-timeout等参数进行压测找到适合当前硬件和业务规模的配置。另外确保网络防火墙开放了数据库端口默认5236。3.3 流程定义建模与部署你可以使用任何支持BPMN 2.0的建模工具来设计流程。这里以创建一个简单的“员工请假流程”为例。使用建模工具打开Camunda Modeler或Eclipse with BPMN2插件。设计一个包含以下节点的流程开始事件流程起点。用户任务“提交申请”申请人填写请假单。排他网关根据请假天数判断审批路径。用户任务“部门经理审批”天数3天由此节点处理。用户任务“总经理审批”天数3天由此节点处理。服务任务“更新考勤系统”审批通过后自动调用服务更新考勤状态。结束事件流程结束。设置任务分配在“部门经理审批”任务的“Assignee”属性中可以设置为${applicant.deptManagerId}这表示运行时将从流程变量applicant对象中获取deptManagerId属性来指定审批人。导出BPMN XML将设计好的流程图保存为leave-request.bpmn20.xml文件。部署到LoongFlow将XML文件放入Spring Boot项目的src/main/resources/processes/目录下。应用启动时如果配置了loongflow.auto-deploy: trueLoongFlow会自动扫描并部署该流程定义。你也可以通过LoongFlow的RepositoryServiceAPI进行动态部署。RestController RequestMapping(/api/process) public class ProcessDeployController { Autowired private RepositoryService repositoryService; PostMapping(/deploy) public String deployProcess(RequestParam(file) MultipartFile file) throws IOException { if (file.isEmpty()) { return 文件为空; } String fileName file.getOriginalFilename(); Deployment deployment repositoryService.createDeployment() .addBytes(fileName, file.getBytes()) .name(手动部署- fileName) .deploy(); return 部署成功部署ID: deployment.getId(); } }4. 核心API使用与业务集成实战4.1 启动流程实例与变量传递流程定义部署后只是一个“模板”。真正的业务流程是从启动一个流程实例开始的。Service public class LeaveProcessService { Autowired private RuntimeService runtimeService; /** * 发起一个请假流程 * param applicantId 申请人ID * param deptManagerId 部门经理ID * param days 请假天数 * return 流程实例ID */ public String startLeaveProcess(String applicantId, String deptManagerId, int days) { // 设置流程变量这些变量可以在流程流转中传递和使用 MapString, Object variables new HashMap(); variables.put(applicantId, applicantId); // 可以传递一个复杂的对象需序列化 Applicant applicant new Applicant(applicantId, deptManagerId); variables.put(applicant, applicant); variables.put(leaveDays, days); variables.put(startTime, new Date()); // 使用流程定义的Key来启动实例 ProcessInstance instance runtimeService.startProcessInstanceByKey( LeaveRequestProcess, // 对应BPMN文件中process元素的id variables ); return instance.getId(); } }注意事项流程变量是LoongFlow中非常重要的通信机制。但要注意变量的序列化与反序列化。如果存储的是自定义Java对象该对象必须实现Serializable接口。为了更好的性能和兼容性尤其是考虑不同版本应用的可能建议将复杂对象转换为简单的Map或JSON字符串进行存储。此外变量作用域可以是流程实例全局的也可以是任务局部的需要根据业务逻辑仔细设计。4.2 任务查询与办理对于用户任务核心操作是查询待办任务和完成任务。RestController RequestMapping(/api/task) public class TaskController { Autowired private TaskService taskService; // 查询某个用户的待办任务 GetMapping(/todo) public ListTaskDto getTodoTasks(RequestParam String userId) { ListTask tasks taskService.createTaskQuery() .taskAssignee(userId) // 指定办理人 .orderByTaskCreateTime().desc() // 按创建时间排序 .list(); return tasks.stream().map(this::convertToDto).collect(Collectors.toList()); } // 办理任务例如审批通过 PostMapping(/{taskId}/complete) public String completeTask(PathVariable String taskId, RequestParam(required false) String comment, RequestBody(required false) MapString, Object variables) { try { // 可以添加审批意见 if (StringUtils.isNotBlank(comment)) { taskService.addComment(taskId, null, comment); } // 完成任务并可传递新的变量影响后续流程走向 taskService.complete(taskId, variables); return 任务办理成功; } catch (LoongFlowException e) { // 例如任务已被他人领取、流程已结束等 return 任务办理失败: e.getMessage(); } } private TaskDto convertToDto(Task task) { // 将引擎的Task对象转换为前端需要的DTO TaskDto dto new TaskDto(); dto.setId(task.getId()); dto.setName(task.getName()); dto.setCreateTime(task.getCreateTime()); // 可以从任务变量中获取业务数据如请假单号 MapString, Object taskVars taskService.getVariables(task.getId()); dto.setBusinessData(taskVars); return dto; } }4.3 服务任务与外部系统集成“服务任务”是自动化节点的关键。你需要实现一个JavaDelegate接口或使用表达式来定义任务行为。Component(updateAttendanceDelegate) // 在BPMN中通过“${updateAttendanceDelegate}”引用 public class UpdateAttendanceDelegate implements JavaDelegate { Autowired private AttendanceService attendanceService; // 假设的考勤系统服务 Override public void execute(DelegateExecution execution) { // 从流程变量中获取业务数据 String applicantId (String) execution.getVariable(applicantId); Integer leaveDays (Integer) execution.getVariable(leaveDays); Date startTime (Date) execution.getVariable(startTime); String processInstanceId execution.getProcessInstanceId(); // 调用外部考勤系统API boolean success attendanceService.updateLeaveRecord(applicantId, leaveDays, startTime); if (!success) { // 如果调用失败可以抛出一个BpmnError触发边界错误事件 throw new BpmnError(ATTENDANCE_UPDATE_FAILED, 更新考勤系统失败); } // 成功则流程继续 execution.setVariable(attendanceUpdated, true); } }在BPMN XML中对应的服务任务配置为serviceTask idupdateAttendanceTask name更新考勤系统 loongflow:delegateExpression${updateAttendanceDelegate} /serviceTask避坑技巧服务任务中执行的是同步调用。如果外部系统响应慢会阻塞流程引擎的工作线程。对于耗时较长的操作强烈建议改为异步服务任务。在LoongFlow中通常可以通过设置asynctrue属性并结合消息队列如RocketMQ来实现。服务任务触发后引擎会将其挂起向消息队列发送一条消息。一个独立的消息消费者处理实际业务处理完成后通过LoongFlow的API回调引擎继续推进流程。这样能极大提升引擎的吞吐量和稳定性。5. 高级特性与性能调优指南5.1 异步执行与历史数据管理在高并发场景下同步执行每一个流程步骤会成为瓶颈。LoongFlow应该支持异步延续Async Continuation。你可以在BPMN设计器中对某个活动如服务任务、调用活动勾选“异步”属性。这样当流程执行到该节点时引擎会将当前事务提交并将一个作业Job放入异步执行器Async Executor的队列中立即返回。异步执行器是一个独立的线程池它会从队列中取出作业并执行。配置异步执行器通常在Spring配置中loongflow: async-executor: core-pool-size: 10 # 核心线程数根据CPU核心数调整 max-pool-size: 50 # 最大线程数 queue-capacity: 1000 # 队列容量防止内存溢出 default-timeout: 300000 # 默认作业超时时间5分钟历史数据管理history-level配置决定了引擎记录多少历史信息。none不记录activity记录活动实例节点流转audit推荐在activity基础上增加变量更新、任务详情full记录所有细节包括表单属性。级别越高历史表数据量增长越快对性能影响越大。在龙芯平台上需要特别关注达梦数据库在大量历史数据写入和查询时的表现可能需要定期归档或清理历史数据。5.2 流程监控与问题排查一个健壮的系统离不开监控。LoongFlow应提供API和可能的管理界面来监控流程。流程实例监控查询运行中、已结束、异常的流程实例。作业监控查看异步作业队列、失败作业、死信作业。失败作业的重试机制需要配置。性能指标关注平均任务完成时间、流程实例吞吐量、数据库连接池使用率。在龙芯平台上的特殊排查点CPU与内存使用top、htop或国产系统自带的监控工具观察Java进程的CPU使用率。如果异步执行器线程池配置过大可能导致不必要的上下文切换开销。数据库监控达梦数据库的慢查询日志。重点关注对ACT_RU_TASK运行时任务、ACT_HI_ACTINST历史活动等高频读写表的查询。为这些表的主键通常是ID_建立索引至关重要。垃圾回收GC龙芯平台的OpenJDK可能使用G1或ZGC。通过JVM参数如-Xlog:gc*开启GC日志分析是否存在因流程变量大对象或长时间运行的流程实例导致的老年代堆积和Full GC。5.3 集群部署与高可用对于生产环境单点部署是不可接受的。LoongFlow需要支持集群部署其核心是解决数据一致性和作业竞争问题。数据库共享所有LoongFlow引擎节点连接同一个数据库。数据库是所有状态的中心存储。这要求数据库本身具备高可用能力如达梦数据库的DSC集群。乐观锁LoongFlow的核心表如运行时任务、变量应该使用版本号REV_字段实现乐观锁防止多个节点同时更新同一数据造成覆盖。异步执行器集群这是关键。多个引擎节点的异步执行器会同时尝试获取可执行的作业。LoongFlow必须实现一个全局的、数据库驱动的作业获取锁机制。通常每个执行器会周期性地、以事务方式从数据库作业表中“锁定”并获取一批作业。通过数据库的行锁或乐观锁确保一个作业只会被一个节点获取。配置集群节点ID确保每个引擎实例有唯一的loongflow.engine-id以便在日志和监控中区分。loongflow: engine-id: ${HOSTNAME:loongflow-node-1} # 可以使用主机名重要提醒在龙芯服务器集群中务必确保所有节点的系统时间通过NTP服务严格同步。因为作业的获取和超时判断依赖于数据库中的时间戳字段时间不同步会导致作业调度混乱。6. 常见问题与故障排查实录在实际使用LoongFlow的过程中尤其是在新的龙芯硬件和国产软件栈上你可能会遇到一些特有或常见的问题。以下是我根据经验整理的一些典型场景和排查思路。6.1 流程实例启动失败或卡住现象调用startProcessInstanceByKey后没有返回实例ID或者流程启动后没有创建第一个任务。排查步骤检查流程定义确认流程定义的Key是否正确以及该Key的最新版本是否已成功部署。可以通过repositoryService.createProcessDefinitionQuery().processDefinitionKey(“key”).latestVersion().singleResult()查询。检查启动人权限有些引擎扩展了权限模型启动流程可能需要特定的身份或组。检查启动代码中是否设置了正确的认证上下文如通过IdentityService.setAuthenticatedUserId(userId)。审查BPMN XML使用建模工具或XML编辑器验证BPMN文件是否符合规范。特别注意开始事件后的第一个活动以及排他网关的条件表达式。在龙芯平台上表达式引擎如JUEL的兼容性需要验证确保条件表达式${leaveDays 3}能正确解析和计算。查看数据库事务在达梦数据库中检查是否有未提交的长事务锁住了流程定义表或运行时实例表。可以查询达梦的V$TRX视图。启用引擎日志将LoongFlow的日志级别调整为DEBUG观察启动过程中的详细步骤看在哪一步出现了异常或中断。6.2 任务无法分配给指定人员现象用户任务创建了但指定办理人的待办列表里查不到。排查步骤确认Assignee表达式检查BPMN中用户任务的assignee属性。如果是表达式${applicant.deptManagerId}确保在启动流程或到达该任务前流程变量applicant对象中的deptManagerId属性已被正确设置且不为空。检查变量作用域变量是在流程实例级别还是任务级别用户任务的办理人表达式只能访问其作用域内的变量。查询任务表直接查询ACT_RU_TASK表看该任务的ASSIGNEE_字段是否已被正确赋值。如果为NULL则表达式可能未生效。自定义任务分配监听器如果你使用了taskListener或实现了TaskAssignmentHandler检查监听器逻辑是否有误是否抛出了未处理的异常导致任务创建失败。6.3 异步作业大量积压或失败现象管理界面显示异步作业队列越来越长或者大量作业状态为“失败”。排查步骤检查异步执行器状态确认异步执行器的线程池是否已启动线程数配置是否合理。检查应用日志是否有线程池拒绝任务的异常。分析失败作业查看失败作业的异常堆栈信息。最常见的原因是服务任务中调用的外部服务不可达或超时。在龙芯服务器上需要额外检查网络配置、防火墙规则以及外部服务是否兼容LoongArch架构例如某些外部服务提供的SDK或API客户端可能只有x86的二进制包。调整超时和重试策略对于网络调用增加超时时间。配置作业失败后的重试次数和重试间隔。loongflow: async-executor: default-timeout: 600000 # 10分钟 retry-wait-time: 60000 # 失败后等待1分钟重试 max-retries: 3 # 最大重试3次数据库连接池瓶颈异步执行器线程在执行作业时也需要访问数据库。如果数据库连接池maximum-pool-size设置过小大量异步线程可能因获取不到连接而等待造成积压。适当调大连接池并监控其使用情况。龙芯特定性能分析使用perf或龙芯平台提供的性能分析工具对异步执行器线程进行采样看是否存在因某个特定本地库调用或JVM代码路径在LoongArch上效率低下导致的瓶颈。6.4 达梦数据库兼容性问题现象启动时报错或执行过程中出现SQL语法错误。排查步骤驱动版本确保使用的达梦JDBC驱动版本与数据库服务器版本兼容并且是支持LoongArch64的版本。SQL方言LoongFlow在初始化数据库时会执行建表语句。确保你使用的是LoongFlow项目官方提供的或明确标注支持DM8的SQL脚本。如果自行修改需注意达梦的自增列语法可能是IDENTITY(1,1)而非AUTO_INCREMENT。注释语法是COMMENT ON TABLE/COLUMN。分页查询LoongFlow引擎内部会生成分页查询。达梦的分页语法是LIMIT ... OFFSET ...与MySQL类似但需要确认LoongFlow的SQL生成模块是否已正确适配。事务与锁达梦默认的事务隔离级别可能与MySQL不同。在高压下如果出现死锁或乐观锁更新失败频繁可能需要调整LoongFlow的隔离级别配置如果支持或者优化业务流程减少对同一流程实例的高频并发操作。连接字符串参数达梦的JDBC URL可能需要特定的参数来优化性能或避免问题例如compatibleModemysql如果LoongFlow某些SQL写法更贴近MySQL、batchType2批量操作优化等。这需要根据实际情况测试。一个真实的踩坑记录在一次压力测试中我们发现流程实例的完成速度远低于预期。通过监控发现数据库的CPU使用率很高。使用达梦的性能监控工具抓取慢SQL发现是历史表ACT_HI_DETAIL的插入操作非常慢。原因是该表有一个BYTEARRAY_字段用于存储大的变量值而我们的流程中传递了一个较大的JSON对象。解决方案是第一评估是否真的需要full历史级别改为audit第二对于确实需要存储的大对象考虑将其存储到分布式文件系统或对象存储中在流程变量中只存其引用ID从而减少数据库的写入压力和网络传输量。这个优化在龙芯平台和x86平台上都有效但在国产化环境下数据库往往成为更关键的瓶颈因此这类优化显得尤为重要。