利用静态服务提升读取Activiti流程图的性能
2016-05-17 00:00
435 查看
1. 现有模式
流程图可以方便用户浏览整个流程的处理过程,或者跟踪参与过的流程的处理状态(当前处于哪个节点、谁在办理、时间等信息),首先需要调用引擎的API读取流程图(二进制流形式),代码如下:1 2 3 4 5 6 | InputStream resourceAsStream = repositoryService.getResourceAsStream(deploymentId,resourceName); byte [] b = new byte [ 1024 ]; int len = - 1 ; while ((len = resourceAsStream.read(b, 0 , 1024 )) != - 1 ){ response.getOutputStream().write(b, 0 ,len); } |
1.1 性能问题
对于上面的代码当经常需要读取图片资源时每次都需要在数据库读取上花费时间,用java输出二进制流也需要一定的时间消耗,所以在一定程度上影响了性能,导致图片读取速度慢甚至超时。从上面的代码可以看出当从前端读取一张图片资源时需要经过一下几个步骤:
发送HTTP请求
根据资源名称(图片文件名称,可以从流程定义对象获取)和Deployment ID读取二进制流
把二进制流输出到前端
如果多个用户请求同一个资源那就要把以上的三个步骤for...each执行N次,也就是说N-1次的数据库读取是浪费的,因为流程定义对象是唯一的,每一次部署后引擎都会把和流程定义生成的图片(或者部署时提供的图片资源)保存到数据库,当需要时通过上面的代码读取,如果把第一次读取的流程资源(泛指和流程有关的各种资源文件)缓存起来可以解决这个问题。
有的读者可能想到使用一个全局Map来保存,但是这样会消耗大量的内存,此举不推荐。
2. 使用静态资源做缓存
大家都知道HTTP服务器最适合做静态资源的访问,例如Apahce、Nginx等;考虑一下这样的一个部署流程的步骤:调用引擎的部署流程API
读取该次部署的所有需要缓存的资源
把换成的资源二进制流保存(持久化)到硬盘上的某个目录(暂且称之为diagrams)
用Apache或者Nginx以目录diagrams开启一个目录服务(可以列出目录中的子目录和文件)
前端访问图片资源时直接从静态服务获取,访问资源的路径可以通过流程定义或许,例如:
http://aws.kafeitu.me:10000/diagrams/leave-formkey/1/leave-formkey.pngleave-formkey表示流程定义的KEY属性,1表示版本号,leave-formkey.png表示资源名称
2.1 导出图片资源
为大家提供一个通用方法可以导出已部署流程定义的流程图,保存到硬盘上的指定目录。1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | /** *导出图片文件到硬盘 * * */ public static String exportDiagramToFile(RepositoryService repositoryService, ProcessDefinition processDefinition,String exportDir) throws IOException{ String diagramResourceName = processDefinition.getDiagramResourceName(); String key = processDefinition.getKey(); int version = processDefinition.getVersion(); String diagramPath = "" ; InputStream resourceAsStream = repositoryService .getResourceAsStream(processDefinition.getDeploymentId(),diagramResourceName); byte [] b = new byte [resourceAsStream.available()]; @SuppressWarnings ( "unused" ) int len = - 1 ; resourceAsStream.read(b, 0 ,b.length); // create file if not exist String diagramDir = exportDir + "/" + key + "/" + version; File diagramDirFile = new File(diagramDir); if (!diagramDirFile.exists()){ diagramDirFile.mkdirs(); } diagramPath = diagramDir + "/" + diagramResourceName; File file = new File(diagramPath); // 文件存在退出 if (file.exists()){ // 文件大小相同时直接返回否则重新创建文件(可能损坏) logger.debug( "diagram exist,ignore... :{}" ,diagramPath); return diagramPath; } else { file.createNewFile(); } logger.debug( "export diagram to :{}" ,diagramPath); // wirtebytes to file FileUtils.writeByteArrayToFile(file,b, true ); return diagramPath; } |
2.2 搭建静态资源服务
根据实际情况选择使用Apache、Nginx或者仅仅用于测试,例如笔者在亚马逊的AWS上使用python的SimpleHttpServer开启了一个简单的目录服务:3. 从静态服务读取资源
原来的URL是这样拼接的:1 | < a target = "_blank" href = '${ctx }/workflow/resource/deployment?deploymentId=${process.deploymentId}&resourceName=${process.diagramResourceName }' >${process.diagramResourceName } |
1 | < a target = "_blank" href = ' >${process.diagramResourceName } |
相关文章推荐
- Java过滤任意(script,html,style)标签符,返回纯文本--封装类
- 微信公众帐号开发教程第2篇-开发模式启用及接口配置
- MyBatis 中XML映射配置文件
- java项目WEB-INF目录作用
- Spring MVC JSON自定义类型转换
- 整合Acitiviti在线流程设计器(Activiti-Modeler 5.18.0)
- jQuery中ready与load事件的区别
- Activiti源码浅析:Activiti的活动授权机制
- Mybatis分页插件 - 示例
- Twitter 架构优化之路--Twitter是如何做到每秒处理3000张图片的
- Java图片工具类完成图片的截取和任意缩放
- ActiveMQ消息系统研究与学习
- java对redis的基本操作
- struts校验框架的一个异常
- js特殊字符验证
- FreeMarker标签与使用
- 利用java实现的一个发送手机短信的小例子
- Activiti初学者教程
- Java SpringMVC项目导出excel多种类对应工具类整理(util)
- 一个简单的Java单例示例谈谈并发