利用静态服务提升读取Activiti流程图的性能

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输出二进制流也需要一定的时间消耗,所以在一定程度上影响了性能,导致图片读取速度慢甚至超时

从上面的代码可以看出当从前端读取一张图片资源时需要经过一下几个步骤:

  1. 发送HTTP请求
  2. 根据资源名称(图片文件名称,可以从流程定义对象获取)和Deployment ID读取二进制流
  3. 把二进制流输出到前端

如果多个用户请求同一个资源那就要把以上的三个步骤for...each执行N次,也就是说N-1次的数据库读取是浪费的,因为流程定义对象是唯一的,每一次部署后引擎都会把和流程定义生成的图片(或者部署时提供的图片资源)保存到数据库,当需要时通过上面的代码读取,如果把第一次读取的流程资源(泛指和流程有关的各种资源文件)缓存起来可以解决这个问题。

有的读者可能想到使用一个全局Map来保存,但是这样会消耗大量的内存,此举不推荐。

2. 使用静态资源做缓存

大家都知道HTTP服务器最适合做静态资源的访问,例如Apahce、Nginx等;考虑一下这样的一个部署流程的步骤:

  1. 调用引擎的部署流程API
  2. 读取该次部署的所有需要缓存的资源
  3. 把换成的资源二进制流保存(持久化)到硬盘上的某个目录(暂且称之为diagrams
  4. 用Apache或者Nginx以目录diagrams开启一个目录服务(可以列出目录中的子目录和文件)
  5. 前端访问图片资源时直接从静态服务获取,访问资源的路径可以通过流程定义或许,例如:
    http://aws.kafeitu.me:10000/diagrams/leave-formkey/1/leave-formkey.png

    leave-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

/**

*
导出图片文件到硬盘

*

*
@return 文件的全路径

*/

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);

 

    //
wirte bytes to file

    FileUtils.writeByteArrayToFile(file,
b,
true);

    return

diagramPath;

}

在部署流程时调用一下方法exportDiagramToFile()即可。

2.2 搭建静态资源服务

根据实际情况选择使用Apache、Nginx或者仅仅用于测试,例如笔者在亚马逊的AWS上使用python的SimpleHttpServer开启了一个简单的目录服务: http://aws.kafeitu.me:10000 ,其中的diagrams目录中的文件就是通过方法exportDiagramToFile导出的。

3. 从静态服务读取资源

原来的URL是这样拼接的:

?


1

<a

target
="_blank"

href
='${ctx
}/workflow/resource/deployment?deploymentId=${process.deploymentId}&resourceName=${process.diagramResourceName }'
>${process.diagramResourceName
}

现在是这样:

?


1

<a

target
="_blank"

href
='http://localhost:10000/${process.key}/${process.version}/${process.diagramResourceName
}'
>${process.diagramResourceName
}

性能提升大概在三倍左右,具体取决于使用的静态服务和网速。

时间: 2016-03-10

利用静态服务提升读取Activiti流程图的性能的相关文章

[案例]酒店如何利用顾客反馈提升社交媒体表现力?

本文来自SocialBeta内容合作伙伴@环球旅讯 . 为了利用社会媒体来提升顾客满意度,酒店不仅需要在最新的社交网络平台上创建资料页面,它们还需要具备较高的"社交反应能力".如果我跟你说一件事,我如何确认你已经听到我说的话呢?唯一的方法就是你做出回应.不管我们是在分享信息还是在提出请求,我们都需要确认对方已经接收到我们所传递的信息. 顾客与酒店在网络中的互动跟上述情况是一样的. 在任何一个旨在提升顾客满意度的计划中,"倾听"都是一个必要条件,但酒店要做的并不仅仅是

利用微软WebService技术实现远程数据库存取 利用web服务在不同站点间共享同一数据库

web|web服务|数据|数据库|微软|站点 随着微软Visual Studo.Net Beta版的发布,由于Visual Studio.Net对XML以及Web服务的强大支持,利用Visual Studio.Net开发Web服务应用将会越来越多而且是非常的方便.本文以一个B2B电子商务网站为例,介绍利用web服务在不同站点间共享同一数据库的具体方法和步骤.本文中,客户端是指使用web服务的一方,服务器端是指提供web服务的另一方. 问题的提出 该网站是一家(简称A)从事网上销售手机SIM卡的业

利用静态路由实现网络访问控制

当一台主机应用需要向位于不同网络的目的地发送数据包时,路由器从一个接口接受数据信息.网络层会检查这个数据包来决定预计发送的网络,然后,路由器会检查自己的路由表,并利用路由表的信息来判断预计要发送的端口.路由器再次把数据报按一定的规则进行封装,然后把数据包在某个端口转发出去. 路由器再转发任何一个数据包的时候,都会发生这个路由判断的过程.路由判断使得路由器能够选择最合适的接口来转发数据包.也就是说,路由器主要是靠路由表来工作的,若没有路由表或者路由表中的信息错误的话,则路由器将如同一堆废铁,没有任

阿里巴巴欲利用H5游戏提升移动端电商导购效率

DoNews游戏2月3日特稿(记者 赵玥) H5游戏因其低廉的开发成本和强大的传播能力,从神经猫起便获得了广泛的关注.但同时,较低的变现能力,及以微信等平台对其传播的限制,又让这一新兴的游戏类型进入了商业化模式的迷茫探索. H5游戏的开发者想要一个舒适的生存环境,而阿里的电商平台在从PC端转至移动端的过程中也亟需导购模式的转变.二者的结合,刚好能同时满足阿里手淘卖家和H5开发者各自的需求,阿里巴巴商家业务事业部无线商家负责人张阔表示. 利用H5游戏提升移动端电商导购效率 张阔介绍,淘宝的用户在由

互联网大佬刘庆峰:利用大数据提升政府效率

2015年3月3日15时,全国政协十二届三次会议在人民大会堂举行.这次大会总共有两千多名政协委员和接近三千名人大代表参与,其中互联网行业的代表人士已经增加至6人,反映这个行业影响力或者重要性正在逐渐提高.那在今年两会上互联网大佬们都有哪些提议呢? 马化腾:用移动互联网防治雾霾 这两天柴静的<穹顶之下>可谓是刷爆了朋友圈,因此雾霾问题也成为此次两会关注的焦点.我们的小马哥也就这一点用自己的互联网思维提了自己的建议. 腾讯CEO马化腾表示,随着移动互联网.大数据.云计算.物联网与人工智能等新技术的

Activiti流程图查看实例_java

本文实例展示了Activiti流程图查看的实现方法,具体步骤如下所示: 1.测试用例查看图片代码如下: public void viewImage() throws Exception { // 创建仓库服务对对象 RepositoryService repositoryService = processEngine.getRepositoryService(); // 从仓库中找需要展示的文件 String deploymentId = "701"; List<String&g

利用静态路由技术 实现网络访问控制

当一台主机应用需要向位于不同网络的目的地发送数据包时,路由器从一个接口接受数据信息.网络层会检查这个数据包来决定 预计发送的网络, 然后,路由器会检查自己的路由表,并利用路由表的信息来判断预计要发送的端口.路由器再次把数据报按一定的规则进行封装,然后把数据包在某个端口转发出去.路由器再转发任何一个数据包的时候,都会发生这个路由判断的过程.路由判断使得路由器能够选择最合适的接口来转发数据包.也就是说,路由器主要是靠路由表来工作的,若没有路由表或者路由表中的信息错误的话,则路由器将如 同一堆废铁,没

瑞云渲染梁幸尧: 利用云服务实现超级电脑技术

10月30日-31日,2014腾讯全球合作伙伴大会在海南博鳌顺利举行.随着互联网科技的高速发展,互联网行业出现了爆发式的增长,大量资金与人才纷纷投入互联网创业大潮之中.10月30日腾讯云"大云端·大生态"峰会设立"如何打造互联网精品"的圆桌讨论,众多来自互联网新兴领域的大佬们展开了探讨. 腾讯云计算公司副总裁陈晓建.Rayvision瑞云渲染董事长梁幸尧.南京泥巴怪公司首席技术官秦川.上海良栀之志网络科技有限公司首席执行官冯良会.未来电视首席执行官张宇霞.Visua

利用索引服务和ASP建立面向整个网站搜索程序

程序|索引|索引 配置Index Server 在执行Web服务器上的搜索之前,首先必须创建至少一个索引,并遵循以下步骤完成这项工作. ⒈启动Windows 2000 Server服务器上的索引. 缺省情况下选择图标位于管理工具组中的计算机管理.窗口的右边提供关于当前在服务器上存在的索引信息.默认有两个索引:System和Web. ⒉要创建新的索引,用鼠标右键单击索引服务或右边的面板,选定新建编录. 显示添加编录对话框,指定索引的名称并用浏览按钮选取位置.索引服务不会立即开始索引,此时将弹出一条