﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-心情小站</title><link>http://www.blogjava.net/RongHao/</link><description>勤学、勤思</description><language>zh-cn</language><lastBuildDate>Mon, 13 Oct 2008 17:42:49 GMT</lastBuildDate><pubDate>Mon, 13 Oct 2008 17:42:49 GMT</pubDate><ttl>60</ttl><item><title>SNA方案之session炒冷饭</title><link>http://www.blogjava.net/RongHao/archive/2008/09/04/226940.html</link><dc:creator>ronghao</dc:creator><author>ronghao</author><pubDate>Thu, 04 Sep 2008 06:31:00 GMT</pubDate><guid>http://www.blogjava.net/RongHao/archive/2008/09/04/226940.html</guid><wfw:comment>http://www.blogjava.net/RongHao/comments/226940.html</wfw:comment><comments>http://www.blogjava.net/RongHao/archive/2008/09/04/226940.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/RongHao/comments/commentRss/226940.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/RongHao/services/trackbacks/226940.html</trackback:ping><description><![CDATA[<p style="margin-left: 24pt; text-indent: 0cm;"><span style="font-size: 12pt; font-family: 宋体;">在集群部署的情况下，应用程序需要做出调整，主要集中在四个方面：对</span><span style="font-size: 12pt;">httpsession</span><span style="font-size: 12pt; font-family: 宋体;">的处理、对缓存的处理、共享的文件系统、</span><span style="font-size: 12pt;">synchronized</span><span style="font-size: 12pt; font-family: 宋体;">关键字的失效。</span></p>
<p style="margin-left: 42pt; text-indent: -18pt;"><strong><span style="font-size: 12pt; font-family: 宋体;">对</span><span style="font-size: 12pt;">httpsession</span><span style="font-size: 12pt; font-family: 宋体;">的处理</span></strong></p>
<p style="margin-left: 42pt; text-indent: 0cm;"><span style="font-size: 12pt; font-family: 宋体;">对</span><span style="font-size: 12pt;">httpsession</span><span style="font-size: 12pt; font-family: 宋体;">的处理最为重要，因为对</span><span style="font-size: 12pt;">WEB</span><span style="font-size: 12pt; font-family: 宋体;">程序而言，</span><span style="font-size: 12pt;">httpsession</span><span style="font-size: 12pt; font-family: 宋体;">无疑是最重要的全局资源，它需要被多个</span><span style="font-size: 12pt;">web</span><span style="font-size: 12pt; font-family: 宋体;">服务器所共享。</span></p>
<p style="margin-left: 42pt; text-indent: 0cm;"><strong><span style="font-size: 12pt; font-family: 宋体; font-weight: normal;">无共享的集群架构（</span></strong><strong><span style="font-size: 12pt; font-family: &quot;Calibri&quot;,&quot;sans-serif&quot;; font-weight: normal;">SNA</span></strong><strong><span style="font-size: 12pt; font-family: 宋体; font-weight: normal;">），</span></strong><span style="font-size: 12pt; font-family: 宋体;">在这样的集群中，每个节点具备完全相同的功能，并且不需要知道其他节点存在与否。每个节点</span><span style="font-size: 12pt;">JVM</span><span style="font-size: 12pt; font-family: 宋体;">进程不保持全局状态，才能够保证</span><span style="font-size: 12pt;">n</span><span style="font-size: 12pt; font-family: 宋体;">个</span><span style="font-size: 12pt;">JVM</span><span style="font-size: 12pt; font-family: 宋体;">节点的幂等性，那些所有涉及到全局状态的，必须放在</span><span style="font-size: 12pt;">JVM</span><span style="font-size: 12pt; font-family: 宋体;">进程之外，例如用户</span><span style="font-size: 12pt;">ID</span><span style="font-size: 12pt; font-family: 宋体;">可以使用</span><span style="font-size: 12pt;">cookie</span><span style="font-size: 12pt; font-family: 宋体;">，</span><span style="font-size: 12pt;">session</span><span style="font-size: 12pt; font-family: 宋体;">可以放入数据库（这并不是一个好的选择），文件可以放在共享存储系统中。</span></p>
<p style="margin-left: 42pt; text-indent: 0cm;"><span style="font-size: 12pt; font-family: 宋体;">也就是说</span><span style="font-size: 12pt;">httpsession</span><span style="font-size: 12pt; font-family: 宋体;">的信息需要被保存在</span><span style="font-size: 12pt;">JVM</span><span style="font-size: 12pt; font-family: 宋体;">进程之外，例如分布式缓存、数据库。</span></p>
<p style="margin-left: 42pt; text-indent: 0cm;"><span style="font-size: 12pt; font-family: 宋体;"><br />
</span></p>
<p style="margin-left: 42pt; text-indent: 0cm;"><span style="font-size: 12pt; font-family: 宋体;">这里是方案：</span></p>
1、使用会话cookie保存web服务器产生的sessionid<br />
&nbsp;&nbsp; 为什么是sessionid而不是userid，原因在于谁也不知道除去登录外其他人会在httpsession里干些什么<br />
<br />
2、自定义SessionMap&lt;String,Serializable&gt;同步保存httpsession内的信息<br />
&nbsp;&nbsp; 自定义SessionMap同步httpsession，在操作httpsession时不用改变调用接口，不用东张西望<br />
<br />
3、使用分布式缓存memcached保存自定义SessionMap&lt;String,Serializable&gt;<br />
<br />
4、会话胶粘<br />
&nbsp;&nbsp; 未失败转发的情况下没必要在memcached和httpsession之间复制来复制去，眉来眼去<br />
<br />
5、使用SnaFilter处理失败转发<br />
<br />
6、使用HttpSessionListener实现SessionMap&lt;String,Serializable&gt;的过期<br />
&nbsp;&nbsp; 利用容器session 机制的好处,httpsession过期的时候干掉memecached里的SessionMap
<p style="margin-left: 60.75pt; text-indent: -18.75pt;"><span style="font-family: 宋体;"><br />
</span></p>
<p style="margin-left: 42pt; text-indent: 0cm;"><span style="font-family: 宋体;">下面根据</span>web<span style="font-family: 宋体;">请求的过程分情况讨论该方案：</span></p>
<p style="margin-left: 60pt; text-indent: -18pt;"><strong><span style="font-family: 宋体;">A、登录</span></strong></p>
<p style="margin-left: 60pt; text-indent: -18pt;"><strong><span style="font-family: 宋体;"><img src="http://www.blogjava.net/images/blogjava_net/ronghao/login1.gif" alt="" border="0" height="420" width="567" /><br />
</span></strong></p>
<p style="margin-left: 60pt; text-indent: 0cm;"><span><!--[if gte vml 1]>
<![endif]--></span></p>
<p style="margin-left: 60pt; text-indent: 0cm;"><span style="font-family: 宋体;">根据请求的</span>url<span style="font-family: 宋体;">判断是否是登录请求</span></p>
<p style="margin-left: 60pt; text-indent: 0cm;"><span style="font-family: 宋体;">在线人数保存在</span>memcached<span style="font-family: 宋体;">里</span></p>
<p style="margin-left: 60pt; text-indent: -18pt;"><strong><span style="font-size: 12pt;">B、&nbsp;</span><span style="font-family: 宋体;">正常请求</span></strong></p>
<p style="margin-left: 60pt; text-indent: -18pt;"><strong><span style="font-family: 宋体;"><img src="http://www.blogjava.net/images/blogjava_net/ronghao/normal1.gif" alt="" border="0" height="445" width="567" /><br />
</span></strong></p>
<p style="margin-left: 60pt; text-indent: 0cm;"><span><!--[if gte vml 1]>
<![endif]--></span></p>
<p style="margin-left: 60pt; text-indent: -18pt;"><strong><span style="font-size: 12pt;">C、&nbsp;</span><span style="font-family: 宋体;">失败转发</span></strong></p>
<p style="margin-left: 60pt; text-indent: -18pt;"><strong><span style="font-family: 宋体;"><img src="http://www.blogjava.net/images/blogjava_net/ronghao/fail1.gif" alt="" border="0" height="424" width="581" /><br />
</span></strong></p>
<p style="margin-left: 60pt; text-indent: 0cm;"><span><!--[if gte vml 1]>
<![endif]--></span></p>
<p style="margin-left: 60pt; text-indent: -18pt;"><strong><span style="font-size: 12pt;">D、</span><span style="font-family: 宋体;">登出</span></strong></p>
<p style="margin-left: 60pt; text-indent: -18pt;"><strong><span style="font-family: 宋体;"><img src="http://www.blogjava.net/images/blogjava_net/ronghao/logout1.gif" alt="" border="0" height="458" width="567" /><br />
</span></strong></p>
<p style="margin-left: 60pt; text-indent: 0cm;"><span><!--[if gte vml 1]>
<![endif]--></span></p>
<p style="margin-left: 60pt; text-indent: 0cm;"><span style="font-family: 宋体;">根据请求的</span>url<span style="font-family: 宋体;">判断是否是登出请求</span></p>
<p style="margin-left: 60pt; text-indent: -18pt;"><strong>E、HttpSession<span style="font-family: 宋体;">过期</span></strong></p>
<p style="margin-left: 60pt; text-indent: 0cm;"><span style="font-family: 宋体;">不</span>hack memcached<span style="font-family: 宋体;">，使用</span>HttpSessionListener<span style="font-family: 宋体;">，</span>sessionDestroyed<span style="font-family: 宋体;">事件时根据</span>sessionid<span style="font-family: 宋体;">删除</span>memcached<span style="font-family: 宋体;">里的</span>sessionMap<span style="font-family: 宋体;">（如果存在）</span></p>
<p style="margin-left: 21pt; text-indent: 0cm;"><span style="font-family: 宋体;">关于在线人数的统计：在线人数存储在</span>memcached<span style="font-family: 宋体;">里，将在线人数与</span>sessionMap<span style="font-family: 宋体;">绑定，往</span>memcached<span style="font-family: 宋体;">里增加</span>sessionMap<span style="font-family: 宋体;">时在线人数</span>+1<span style="font-family: 宋体;">，删除时</span>-1.</p>
<img src ="http://www.blogjava.net/RongHao/aggbug/226940.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/RongHao/" target="_blank">ronghao</a> 2008-09-04 14:31 <a href="http://www.blogjava.net/RongHao/archive/2008/09/04/226940.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>一次性能调优的实战</title><link>http://www.blogjava.net/RongHao/archive/2008/09/01/226068.html</link><dc:creator>ronghao</dc:creator><author>ronghao</author><pubDate>Mon, 01 Sep 2008 05:49:00 GMT</pubDate><guid>http://www.blogjava.net/RongHao/archive/2008/09/01/226068.html</guid><wfw:comment>http://www.blogjava.net/RongHao/comments/226068.html</wfw:comment><comments>http://www.blogjava.net/RongHao/archive/2008/09/01/226068.html#Feedback</comments><slash:comments>8</slash:comments><wfw:commentRss>http://www.blogjava.net/RongHao/comments/commentRss/226068.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/RongHao/services/trackbacks/226068.html</trackback:ping><description><![CDATA[项目情况：是一个大型公司的内部办公系统，该系统有两个和一般企业应用不太一样的特点：一是用户量非常多，人员数达到2W左右，另一个是采用分级管理的形式，各个分公司数据分开管理。
<br />
<br />
我们的定位：我们是作为业务平台的提供商参与这个项目的，我们提供底层的开发平台，系统集成商在此基础上进行二次开发。
<br />
<br />
在项目从开发到部署的过程中遇到了很多的问题，也反映出很多问题。
<br />
<br />
<strong>一、怎么回事，跑得比猫还慢</strong>
<br />
项目开发完毕后部署在Ibm aix
小型机上，32G内存，16个cpu。应用服务器采用的是weblogic9.2，数据库是oracle10.0.2。上线后发现系统运行的非常缓慢，甚
至比开发环境下的tomcat还要慢。于是开始排查原因，最开始是对SQL进行监控，优先考虑是数据库访问性能产生瓶颈。通过监控，发现很多业务需要执行
大量的SQL语句，查看客户编写的相关代码，发现在查询数据时循环执行了大量SQL。主要原因在于他们在代码中循环调用了我们相关API，一个最典型的例
子是通过用户ID查找用户NAME，他们在业务表格里没有保存用户name，而是在查询的时候通过用户ID查找用户name填充到页面，几乎每一个查询都
是n+1。<br />
&nbsp;<br />
另外由于平台使用了hibernate，使得oo编程得非常爽快，导致开发人员完全忽略了相应的数据库操作所带来的压力。很多业务逻辑直接通过PO叠加完成，把一些可以通过很少SQL完成的逻辑全部分散放置到PO里，导致了大量PO的交互和SQL语句。
<br />
<br />
开始优化SQL，优化的同时增加大量业务缓存。但优化完毕后运行缓慢的现象依旧存在，性能有了一定的提升但是不是非常明显。继续优化，其中考虑过
多频繁访问的数据使用内存数据库的方式。但是优化过后在tomcat上效果明显，部署到生产环境就问题依旧。于是考虑weblogic的配置问题，作为开
发平台提供商，我们只是提供系统开发相关方面的支持，对于应用服务器和数据库服务器只是做基本的配置系统可运行即可。但是在这个问题上系统集成商咬定是我
们平台的问题不放，并且存在一个很严重的问题：他们使用的是盗版的weblogic，这样根本就没有相应的技术支持。
<br />
<br />
问题的解决：最后是找了一个BEA曾经的开发人员，问题实际非常的简单，现场部署的weblogic默认是运行在32位机器上，与64位机器存
在一定的不兼容。通过替换相应的jar包，问题得到了解决，主要是IO方面。替换完毕后，速度提升了进30%
。该开发人员说，如果没有lisence，根本就不会得到这些替换的jar包。
<br />
<br />
<strong>二、内存耗尽了</strong>
<br />
访问速度的问题解决了，系统的使用量很快上来，马上遇到新的问题：内存耗尽了。严重到几乎每天都要out of memory一次。这种问题在客户现场频繁出现。
<br />
<br />
本地测试，tomcat，sun jdk
通过Jprofiler监测内存使用情况。在并发访问门户的情况下，内存确实存在暴涨的情况，100并发，内存使用立刻上升了150m左右，继续并发
100，再增长150m。但是很快在抵达高峰时会有一次gc发生，内存使用稳定在200m，内存里大量char[]数组对象。疲劳测试，内存使用曲线并没
有出现逐渐上升泄露的情况。换weblogic和jrocket测试，gc发生的更加频繁，内存使用稳定。<br />
&nbsp;<br />
但是现场依旧频繁当机，内存根本释放不了，一直逐渐增长，典型的内存泄露。对系统缓存、单态对象包括spring管理的对象、IO流进行了统一
排查，依旧没有找到内存泄露的原因。使用IBM
工具分析heapdump文件，结果还是大量的char[]数组对象占据内存，查找应用，找不到相关业务对象引用。<br />
&nbsp;<br />
问题解决：问题解决是一篇偶尔搜到的oracle论坛的帖子，这里<a href="http://forums.oracle.com/forums/message.jspa?messageID=1040570 ">http://forums.oracle.com/forums/message.jspa?messageID=1040570
</a>。原因在于oracle10的数据库驱动对statement最后执行的结果集有着引用，并且不会释放，目的在于通过内存而换取更好的性能。数据库连接采
用的是weblogic的连接池，关于connection有个相关的statement
cache设定，设定一个connection能够被缓存的statement个数，最大是1024，而现场就被设定为了1024！connection
pool的connection个数被设置为了500
。真是个恐怖的设置。在将1024改为10后，内存使用量轰然倒地，稳定在1g左右。这个设置是在前面系统访问速度存在问题时由系统集成商的开发人员设置
上去的，他们将所有和优化相关的参数全部开到了最大。这个问题要是用户购买的是正版的weblogic和oracle的话，相信也会很快得到解决。
<br />
<br />
<strong>三、线程阻塞</strong>
<br />
内存泄露的问题解决后，线程阻塞的问题浮出水面。系统集成商报告是线程死锁，通过分析工具其实是线程阻塞，主要问题在于系统用到了
synchronized关键字，对工作流相关API全部使用了synchronized，原因在这里：<a href="http: //ronghao.javaeye.com/blog/205731">http:
//ronghao.javaeye.com/blog/205731</a>
。分析发现一个工作项提交的操作在连接数据库时被挂起了20分钟！造成了大量线程的排队阻塞。被挂起的原因有很多种。我们采用的方法是将接口拆分和设置事
务timeout时间。但是这显然不是一个好方法。最后是去掉所有的synchronized关键字，将同步的问题交由数据库解决，问题解决。
<br />
<br />
<strong>四、反思</strong>
<br />
1、系统集成商为什么不购买正版？
<br />
2、开发平台提供商究竟在项目开发中处于一种什么样的位置？开发平台是否对所有软件开发问题都要负责？
<br />
3、开发平台是越封装越快乐吗？还是越封装越丑陋？
<img src ="http://www.blogjava.net/RongHao/aggbug/226068.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/RongHao/" target="_blank">ronghao</a> 2008-09-01 13:49 <a href="http://www.blogjava.net/RongHao/archive/2008/09/01/226068.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>BPM向左，工作流向右（一）什么是业务流程</title><link>http://www.blogjava.net/RongHao/archive/2008/08/26/224529.html</link><dc:creator>ronghao</dc:creator><author>ronghao</author><pubDate>Tue, 26 Aug 2008 09:33:00 GMT</pubDate><guid>http://www.blogjava.net/RongHao/archive/2008/08/26/224529.html</guid><wfw:comment>http://www.blogjava.net/RongHao/comments/224529.html</wfw:comment><comments>http://www.blogjava.net/RongHao/archive/2008/08/26/224529.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/RongHao/comments/commentRss/224529.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/RongHao/services/trackbacks/224529.html</trackback:ping><description><![CDATA[<p><strong></strong><strong></strong><span style="font-size: 12pt; font-family: 宋体;"><br />
从事工作流以及相关开发已经三年。提到工作流，很多人都会想到</span><span style="font-size: 12pt;">BPM</span><span style="font-size: 12pt; font-family: 宋体;">，想到业务流程。对于业务流程，我的理解经过了一个过程，从最开始对工作流抱有的不切实际的期望，到对</span><span style="font-size: 12pt;">BPM</span><span style="font-size: 12pt; font-family: 宋体;">的一些看法，再到目前的趋于实际。有一些感触，也有一些理解。对于业务流程管理而言，我想说的是：</span><span style="font-size: 12pt;">BPM</span><span style="font-size: 12pt; font-family: 宋体;">向左，工作流向右，都不靠谱，或者说它们实际所能描述的流程和这里的业务流程根本就风牛马不相及，不是一个概念，唯一的相同点是只不过都叫流程而已。</span></p>
<p style="margin-left: 24pt; text-indent: -24pt;"><strong><span style="font-size: 12pt; font-family: 宋体;">一、什么是业务流程</span></strong></p>
<p style="margin-left: 24pt; text-indent: 0cm;"><span style="font-size: 12pt; font-family: 宋体;">业务流程是一个技术</span><span style="font-size: 12pt;"><a href="http://www.shenmeshi.com/Science/Index.html"></a></span><span style="font-size: 12pt; font-family: 宋体;">术语，它具有准确的定义：有组织的活动，</span><span style="font-size: 12pt; font-family: 宋体;">相互联系，为客户创造价值。</span></p>
<p style="margin-left: 24pt; text-indent: 0cm;"><span style="font-size: 12pt; font-family: 宋体;">这句话很好理解。甚至可以说任何企业的活动都是以业务为主线，以流程为线索串联起来的。企业的规章制度、操作手册等都与业务流程有着契合点。</span></p>
<p style="margin-left: 24pt; text-indent: -24pt;"><strong><span style="font-size: 12pt; font-family: 宋体;">二、业务流程对于企业的意义</span></strong></p>
<p style="margin-left: 24pt; text-indent: 0cm;"><span style="font-size: 12pt; font-family: 宋体;">业务流程对于企业的意义不仅仅在于对企业关键业务的一种描述，更在于对企业的业务运营有着指导意义，这种意义体现在对资源的优化、对企业组织机构的优化以及对管理制度的一系列改变。这种优化的目的实际也是企业所追求的目标：降低企业的运营成本，提高对市场需求的响应速度，争取企业利润的最大化。</span></p>
<p style="margin-left: 24pt; text-indent: -24pt;"><strong><span style="font-size: 12pt; font-family: 宋体;">三、业务流程也是一个体系</span></strong></p>
<p style="margin-left: 24pt; text-indent: 0cm;"><span style="font-size: 12pt; font-family: 宋体;">业务流程通常的表现形式是流程图（不是唯一形式），毕竟图形是最易于理解的一种形式，但似乎我们太关注于流程图本身而忽略了其他。除了流程图之外，业务流程还应该包括目标和指导方针，这才是一个完整的业务流程。在梳理业务使用业务流程描述时首先要想到的是该流程所要达到的目标，能为客户创造什么价值，脱离开业务目标或者说纯粹为描述业务而描述业务是没有意义的。同时在制定业务流程时也要考虑到该业务流程的指导方针，同一个业务可能有很多种业务流程的描述形式，具体哪一种是最合适的，这里就必须有一个指导方针来进行约束。</span></p>
<p style="margin-left: 24pt; text-indent: -24pt;"><strong><span style="font-size: 12pt; font-family: 宋体;">四、业务流程的特征</span></strong></p>
<p style="margin-left: 42pt; text-indent: -18pt;"><strong><span style="font-size: 12pt; font-family: 宋体;">1、层次性、逐层抽象</span></strong></p>
<p style="margin-left: 42pt; text-indent: 0cm;"><span style="font-size: 12pt; font-family: 宋体;">业务流程是有层次性的，这种层次体现在由上至下、由整体到部分、由宏观到微观、由抽象到具体的逻辑关系。</span></p>
<p style="margin-left: 42pt; text-indent: 0cm;"><span style="font-size: 12pt; font-family: 宋体;"><img src="http://www.blogjava.net/images/blogjava_net/ronghao/rh1.gif" alt="" border="0" height="391" width="586" /><br />
</span></p>
<p style="margin-left: 42pt; text-indent: 0cm;"><span style="font-size: 12pt;"><!--[if gte vml 1]>
<![endif]--></span></p>
<p style="margin-left: 42pt; text-indent: 0cm;"><span style="font-size: 12pt; font-family: 宋体;">这样一个层次关系符合人们的思维习惯，有利于企业业务模型的建立。一般来说，我们可以先建立主要业务流程的总体运行过程（其中包括了整个企业的大的战略），然后对其中的每项活动进行细化，落实到各个部门的业务过程，建立相对独立的子业务流程以及为其服务的辅助业务流程。</span></p>
<p style="margin-left: 42pt; text-indent: 0cm;"><span style="font-size: 12pt; font-family: 宋体;">业务流程之间的层次关系一定程度上也反映了企业部门之间的层次关系。不同层级的部门有着对业务流程不同的分级管理权限。决策层、管理者、使用者可以清晰的查看到下属和下属部门的业务流程。</span></p>
<p style="margin-left: 42pt; text-indent: 0cm;"><span style="font-size: 12pt; font-family: 宋体;"><img src="http://www.blogjava.net/images/blogjava_net/ronghao/rh2.gif" alt="" border="0" height="410" width="584" /><br />
</span></p>
<p style="margin-left: 42pt; text-indent: 0cm;"><span style="font-size: 12pt;"><!--[if gte vml 1]>
<![endif]--></span></p>
<p style="margin-left: 42pt;">为使得所建立的业务流程能够更顺畅的运行，业务流程的改进与企业组织结构的优化是一个相互制约、相互促进的过程。</p>
<p style="margin-left: 42pt; text-indent: -18pt;"><strong><span style="font-size: 12pt; font-family: 宋体;">2、以人为本</span></strong></p>
<p style="margin-left: 42pt; text-indent: 0cm;"><span style="font-size: 12pt; font-family: 宋体;">组织中最重要的部分是人员的工作方式以及构成他们每日操作的工作流程。</span></p>
<p style="margin-left: 42pt; text-indent: 0cm;"><span style="font-size: 12pt; font-family: 宋体;">人是业务流程的驱动者，组织中的每一个人都会在业务流程中充当一个角色。通过良好的业务流程，每一个人都会有自己清晰的职责，要求具有良好的沟通协作意识和团队意识，明确自己在一个个业务流程中所担当的角色。</span></p>
<p style="margin-left: 42pt; text-indent: 0cm;"><span style="font-size: 12pt; font-family: 宋体;">同时对于参与其中的业务流程，每个人员都要有自己的反馈。</span></p>
<p style="margin-left: 42pt; text-indent: 0cm;"><span style="font-size: 12pt; font-family: 宋体;">首先，每个人员都能查看到这些业务流程，他们需要充分理解这些业务流程、流程的业务意义和目的，这些业务流程通过切合他们理解能力的方式（切合业务的图形、说明文字、相应的制度、规范、标准等等）得以展现。</span></p>
<p style="margin-left: 42pt; text-indent: 0cm;"><span style="font-size: 12pt; font-family: 宋体;">其次，对于流程运行中存在的问题或瓶颈，每个人员都要积极反馈（提出修改的建议，或者在权限范围内直接修改）以促进流程的持续改进，业务流程的管理和变动不仅仅是业务分析人员或管理人员的职责，每一个员工都要参与其中，否则只有失败。管理人员和决策层更重要的职责是制定出业务流程的规则和约束，在这个规则和约束范围内，员工可以根据变化的商业环境对业务流程做出迅速修改，这样不必等到领导了解情况后再做出决策从而失去机会。</span></p>
<p style="margin-left: 42pt; text-indent: -18pt;"><strong><span style="font-size: 12pt; font-family: 宋体;">3、对流程运行效益的分析</span></strong></p>
<p style="margin-left: 42pt; text-indent: 0cm;"><span style="font-size: 12pt; font-family: 宋体;">从企业投资者的角度来讲，好的业务流程设计必然是能够为企业带来最高利润的设计。因此，对业务流程的效益分析是评价业务流程的一个重要方面。财务数据是最关键的数据，但这种分析不一定完全是由数据支撑的，有些是不能量化的，比如人员效率等等。</span></p>
<p style="margin-left: 24pt; text-indent: -24pt;"><strong><span style="font-size: 12pt; font-family: 宋体;">五、业务流程管理</span></strong></p>
<p style="margin-left: 24pt; text-indent: 0cm;"><span style="font-size: 12pt; font-family: 宋体;">良好的业务流程管理是保证企业灵活运营的关键（业务流程管理又何尝不是一种业务流程？）。</span></p>
<p style="margin-left: 42pt; text-indent: -18pt;"><strong><span style="font-size: 12pt; font-family: 宋体;">1、业务分析</span></strong></p>
<p style="margin-left: 42pt; text-indent: 0cm;"><span style="font-size: 12pt; font-family: 宋体;">实际这也是业务流程管理最重要的部分。它需要对企业业务有着强大的分析能力，因为业务分析对企业的运营有着重大的指导意义，只有具备了这样的业务分析能力，才能把握住企业运转的真实流程，而且这种分析能力往往带有对整个行业的深刻理解和前瞻性。没有异议，业务分析在于人，与</span><span style="font-size: 12pt;">IT</span><span style="font-size: 12pt; font-family: 宋体;">无关。</span></p>
<p style="margin-left: 42pt; text-indent: -18pt;"><span style="font-size: 12pt; font-family: 宋体;"><strong>2</strong><strong>、业务流程的持续改进</strong></span></p>
<p style="margin-left: 42pt; text-indent: 0cm;"><span style="font-size: 12pt; font-family: 宋体;">不仅仅是流程管理人员（管理决策层）根据运行效益的分析和商业环境的分析对流程进行重整。还包括每个员工对其参与的流程的持续反馈和持续改进。柔性的业务流程。</span></p>
<p style="margin-left: 42pt; text-indent: -18pt;"><strong><span style="font-size: 12pt;">3、IT</span><span style="font-size: 12pt; font-family: 宋体;">系统与业务流程的关系</span></strong></p>
<p style="margin-left: 42pt; text-indent: 0cm;"><span style="font-size: 12pt;">IT</span><span style="font-size: 12pt; font-family: 宋体;">系统与业务流程并没有直接的关系。正如</span><span style="font-size: 12pt;">06z</span><span style="font-size: 12pt; font-family: 宋体;">在</span><span style="font-size: 12pt;">SOA</span><span style="font-size: 12pt; font-family: 宋体;">帖子里表达的：</span><span style="font-size: 12pt;">soa95%</span><span style="font-size: 12pt; font-family: 宋体;">以上的工作是在做业务流程的分析解构和重整，技术层面的支持只占</span><span style="font-size: 12pt;">5%</span><span style="font-size: 12pt; font-family: 宋体;">不到。在落实到技术层面，你觉得一个</span><span style="font-size: 12pt;">soa</span><span style="font-size: 12pt; font-family: 宋体;">产品究竟应该包括些什么内容呢？这些内容又能有多少是能够辅助大家对业务流程进行分析和测试，对业务元素进行重整和再分配？如果你们真的有这个能力，你们觉得是在这里继续开发软件过苦日子，还是去开拓商业咨询呢？我的观点是：</span><span style="font-size: 12pt;">SOA</span><span style="font-size: 12pt; font-family: 宋体;">很美好，但是一落地就变成了小丑。所谓的业务流程管理软件同理。</span></p>
<p style="margin-left: 42pt; text-indent: 0cm;"><span style="font-size: 12pt; font-family: 宋体;">可以这样理解：业务流程管理是一个很大的命题，</span><span style="font-size: 12pt;">IT</span><span style="font-size: 12pt; font-family: 宋体;">系统通过信息化对它的子集进行支撑，这里的</span><span style="font-size: 12pt;">IT</span><span style="font-size: 12pt; font-family: 宋体;">系统包括的范围很广泛，包括了所有的企业应用软件（所有的企业应用软件都可以看作是对企业某部分的业务流程进行的描述）。业务流程管理的核心在于业务流程的分析解构和重整，这点是所有软件都不可企及的，关键在于人。至于</span><span style="font-size: 12pt;">BPM</span><span style="font-size: 12pt; font-family: 宋体;">还是工作流，它们本来就有它们自己的适用范围，硬要把它提升到业务流程管理的高度来宣传，那就真的和小丑一样，滑稽而可笑。</span></p>
<p style="margin-left: 42pt; text-indent: 0cm;"><span style="font-size: 12pt; font-family: 宋体;">关注下篇：</span><span style="font-size: 12pt;">BPM</span><span style="font-size: 12pt; font-family: 宋体;">是干什么的</span></p>
<img src ="http://www.blogjava.net/RongHao/aggbug/224529.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/RongHao/" target="_blank">ronghao</a> 2008-08-26 17:33 <a href="http://www.blogjava.net/RongHao/archive/2008/08/26/224529.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>js组件的测试，是个问题</title><link>http://www.blogjava.net/RongHao/archive/2008/08/11/221362.html</link><dc:creator>ronghao</dc:creator><author>ronghao</author><pubDate>Mon, 11 Aug 2008 11:05:00 GMT</pubDate><guid>http://www.blogjava.net/RongHao/archive/2008/08/11/221362.html</guid><wfw:comment>http://www.blogjava.net/RongHao/comments/221362.html</wfw:comment><comments>http://www.blogjava.net/RongHao/archive/2008/08/11/221362.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.blogjava.net/RongHao/comments/commentRss/221362.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/RongHao/services/trackbacks/221362.html</trackback:ping><description><![CDATA[用js编写自己的组件，测试一直是个头疼的问题。最开始大量使用alert，firebug出现后天突然蓝了。但人的欲望总是没有止境的，在面对越来越多的后台数据交互以及特定于不同业务数据不同的展现形式时，仿佛一夜回到解放前。<br />
<br />
说说我现在的困境：<br />
<br />
目前要做的是工作流的提交页面，也就是对当前办理工作的用户展现后续任务，根据不同的情况由用户选择或是引擎自动计算。这是最简单的情况，后续包括参与者的选择计算、时间服务设定以及Comment等等。<br />
现在根据业务逻辑分为了四种情况：<br />
1、串行<br />
2、分支选择<br />
3、M选N选择<br />
4、复杂的分支组合<br />
四种情况需要准备不同的业务测试数据，同时页面展现也是不同的。我采用的方式如下图：<br />
<img src="http://www.blogjava.net/images/blogjava_net/ronghao/kek.gif" alt="" border="0" /><br />
<br />
针对每种情况都建立相应的测试文件夹，在各自文件夹下准备各自的业务测试数据以及测试页面。并且一个testcase往往需要很多的业务测试数据（和通用组件还是不太一样）。清晰还是清晰，但是问题在于这种测试还是人肉，做不到自动化测试，同时为了业务数据能够顺利插入不得不hack一些代码。当增加或改动部分代码后就要人肉返测一次，预计代码还会大量膨胀，相应的测试文件还会增加。真是苦海无边，无心睡眠。想想cc和junit真是幸福的像花一样。<br />
<br />
我佛慈悲，不知道大家有什么好的方法没有？<br />
<br />
<img src ="http://www.blogjava.net/RongHao/aggbug/221362.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/RongHao/" target="_blank">ronghao</a> 2008-08-11 19:05 <a href="http://www.blogjava.net/RongHao/archive/2008/08/11/221362.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>工作流之收回</title><link>http://www.blogjava.net/RongHao/archive/2008/07/15/215036.html</link><dc:creator>ronghao</dc:creator><author>ronghao</author><pubDate>Tue, 15 Jul 2008 10:28:00 GMT</pubDate><guid>http://www.blogjava.net/RongHao/archive/2008/07/15/215036.html</guid><wfw:comment>http://www.blogjava.net/RongHao/comments/215036.html</wfw:comment><comments>http://www.blogjava.net/RongHao/archive/2008/07/15/215036.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.blogjava.net/RongHao/comments/commentRss/215036.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/RongHao/services/trackbacks/215036.html</trackback:ping><description><![CDATA[<p><strong><span style="font-size: 12pt; font-family: 宋体;">收回</span></strong></p>
<p><span style="font-size: 12pt; font-family: 宋体;">收回是工作流参与者对自己&#8220;已办任务&#8221;（对已完成的工作项）的一种操作，即参与者主动对已办理过的工作项进行重新办理。</span></p>
<p><strong><span style="font-family: 宋体;">为什么要收回？</span></strong></p>
<p>参与者完成任务后，发现自己办理有错误等情况后，需要将此任务收回重新办理。</p>
<p><strong>工作项的参与方式</strong></p>
<p>目前有四种方式：共同参与、竞争参与、顺序参与、基于角色的共同参与。</p>
<p>下面会针对这四种方式进行讨论。</p>
<p><strong>工作项收回模式</strong></p>
<p><strong>1、未触发下一节点的工作项的收回</strong></p>
<p>即当前任务节点并未完成，依旧处于执行状态</p>
<p><br />
</p>
<p>1.1共同参与</p>
<p><img src="http://www.blogjava.net/images/blogjava_net/ronghao/sh1.gif" alt="" border="0" height="328" width="583" /><br />
</p>
<p><span><!--[if gte vml 1]>
<![endif]--></span></p>
<p>如图：在节点A未结束之前，workitem1、workitem2和workitem3正常完成后可以任意收回。在只产生一个workitem的情况下，不存在未触发下一节点的收回情况。</p>
<p><br />
</p>
<p>1.2顺序参与</p>
<p><img src="http://www.blogjava.net/images/blogjava_net/ronghao/sh2.gif" alt="" border="0" height="355" width="580" /><br />
</p>
<p><span><!--[if gte vml 1]>
<![endif]--></span></p>
<p><span style="font-size: 12pt; font-family: 宋体;">如图：</span><span style="font-size: 12pt;">workitem1</span><span style="font-size: 12pt; font-family: 宋体;">、</span><span style="font-size: 12pt;">workitem2</span><span style="font-size: 12pt; font-family: 宋体;">和</span><span style="font-size: 12pt;">workitem3</span><span style="font-size: 12pt; font-family: 宋体;">顺序完成，</span><span style="font-size: 12pt;">workitem1</span><span style="font-size: 12pt; font-family: 宋体;">在</span><span style="font-size: 12pt;">workitem2</span><span style="font-size: 12pt; font-family: 宋体;">签收（包括挂起和手工终止）前可以收回，同样，</span><span style="font-size: 12pt;">workitem2</span><span style="font-size: 12pt; font-family: 宋体;">在</span><span style="font-size: 12pt;">workitem3</span><span style="font-size: 12pt; font-family: 宋体;">签收（包括挂起和手工终止）前也可以收回。</span><span style="font-family: 宋体;">在只产生一个</span>workitem<span style="font-family: 宋体;">的情况下，</span><span style="font-size: 12pt; font-family: 宋体;">不存在未触发下一节点的收回情况。</span></p>
<p><span style="font-size: 12pt; font-family: 宋体;"><br />
</span></p>
<p><span style="font-size: 12pt;">1.3</span><span style="font-size: 12pt; font-family: 宋体;">竞争参与</span></p>
<p><span style="font-size: 12pt; font-family: 宋体;">因为只会产生一个</span><span style="font-size: 12pt;">workitem</span><span style="font-size: 12pt; font-family: 宋体;">，该</span><span style="font-size: 12pt;">workitem</span><span style="font-size: 12pt; font-family: 宋体;">完成后会立刻触发下一节点，所以不存在未触发下一节点的收回情况。</span></p>
<p><span style="font-size: 12pt; font-family: 宋体;"><br />
</span></p>
<p><span style="font-size: 12pt;">1.4</span><span style="font-size: 12pt; font-family: 宋体;">基于角色的共同参与</span></p>
<p><span style="font-size: 12pt; font-family: 宋体;">与</span><span style="font-size: 12pt;">1.1</span><span style="font-size: 12pt; font-family: 宋体;">相同。</span></p>
<p><strong><span style="font-size: 12pt;">2</span></strong><strong><span style="font-size: 12pt; font-family: 宋体;">、已触发下一节点的工作项的收回</span></strong></p>
<p><strong>&nbsp;</strong></p>
<p><span style="font-size: 12pt;">2.1</span><span style="font-size: 12pt; font-family: 宋体;">共同参与</span></p>
<p><span style="font-size: 12pt; font-family: 宋体;"><img src="http://www.blogjava.net/images/blogjava_net/ronghao/sh3.gif" alt="" border="0" /><br />
</span></p>
<p><span style="font-size: 12pt;"><!--[if gte vml 1]>
<![endif]--></span></p>
<p><span style="font-size: 12pt; font-family: 宋体;">问题</span><span style="font-size: 12pt;">1</span><span style="font-size: 12pt; font-family: 宋体;">：多个工作项时谁可以执行收回操作？</span></p>
<p><span style="font-size: 12pt;">workitem1</span><span style="font-size: 12pt; font-family: 宋体;">、</span><span style="font-size: 12pt;">workitem2</span><span style="font-size: 12pt; font-family: 宋体;">和</span><span style="font-size: 12pt;">workitem3</span><span style="font-size: 12pt; font-family: 宋体;">都可以执行收回操作。第一个工作项的收回将会导致节点</span><span style="font-size: 12pt;">B</span><span style="font-size: 12pt; font-family: 宋体;">实例的删除，同时节点</span><span style="font-size: 12pt;">A</span><span style="font-size: 12pt; font-family: 宋体;">重新恢复执行状态。</span></p>
<p><span style="font-size: 12pt; font-family: 宋体;"><br />
</span></p>
<p><span style="font-size: 12pt; font-family: 宋体;">问题</span><span style="font-size: 12pt;">2</span><span style="font-size: 12pt; font-family: 宋体;">：节点</span><span style="font-size: 12pt;">B</span><span style="font-size: 12pt; font-family: 宋体;">处于什么状态节点</span><span style="font-size: 12pt;">A</span><span style="font-size: 12pt; font-family: 宋体;">的工作项可以执行收回操作？</span></p>
<p><span style="font-size: 12pt; font-family: 宋体;">由</span><span style="font-size: 12pt;">A</span><span style="font-size: 12pt; font-family: 宋体;">触发的节点</span><span style="font-size: 12pt;">B</span><span style="font-size: 12pt; font-family: 宋体;">处于正在执行的状态，节点</span><span style="font-size: 12pt;">B</span><span style="font-size: 12pt; font-family: 宋体;">所产生的工作项：</span></p>
<p><span style="font-size: 12pt;">a</span><span style="font-size: 12pt; font-family: 宋体;">共同参与</span><span style="font-size: 12pt; font-family: 宋体;">&nbsp;&nbsp; 工作项均未签收、挂起或手工终止</span></p>
<p><span style="font-size: 12pt;">b</span><span style="font-size: 12pt; font-family: 宋体;">顺序参与</span><span style="font-size: 12pt; font-family: 宋体;">&nbsp;&nbsp;&nbsp; 第一个工作项未签收、挂起或手工终止</span></p>
<p><span style="font-size: 12pt;">c </span><span style="font-size: 12pt; font-family: 宋体;">竞争参与&nbsp;&nbsp; </span><span style="font-size: 12pt; font-family: 宋体;">工作项均未签收、挂起或手工终止</span></p>
<p><span style="font-size: 12pt;">d</span><span style="font-size: 12pt; font-family: 宋体;">角色</span><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp; &nbsp; &nbsp; </span><span style="font-size: 12pt; font-family: 宋体;">同共同参与</span></p>
<p><span style="font-size: 12pt; font-family: 宋体;"><br />
</span></p>
<p><span style="font-size: 12pt; font-family: 宋体;">问题</span><span style="font-size: 12pt;">3</span><span style="font-size: 12pt; font-family: 宋体;">：工作项收回产生的影响？</span></p>
<p><span style="font-size: 12pt; font-family: 宋体;">节点</span><span style="font-size: 12pt;">A</span><span style="font-size: 12pt; font-family: 宋体;">重新执行，收回的工作项重新执行。节点</span><span style="font-size: 12pt;">B</span><span style="font-size: 12pt; font-family: 宋体;">重新恢复未触发状态，</span><span style="font-size: 12pt;">B</span><span style="font-size: 12pt; font-family: 宋体;">所产生的工作项全部删除。</span></p>
<p><span style="font-size: 12pt; font-family: 宋体;"><br />
</span></p>
<p><span style="font-size: 12pt;">2.2</span><span style="font-size: 12pt; font-family: 宋体;">顺序参与</span></p>
<p><span style="font-size: 12pt; font-family: 宋体;"><img src="http://www.blogjava.net/images/blogjava_net/ronghao/sh4.gif" alt="" border="0" /><br />
</span></p>
<p><span style="font-size: 12pt;"><!--[if gte vml 1]>
<![endif]--></span></p>
<p><span style="font-size: 12pt; font-family: 宋体;">问题</span><span style="font-size: 12pt;">1</span><span style="font-size: 12pt; font-family: 宋体;">：多个工作项时谁可以执行收回操作？</span></p>
<p><span style="font-size: 12pt;">workitem1</span><span style="font-size: 12pt; font-family: 宋体;">、</span><span style="font-size: 12pt;">workitem2</span><span style="font-size: 12pt; font-family: 宋体;">和</span><span style="font-size: 12pt;">workitem3</span><span style="font-size: 12pt; font-family: 宋体;">根据顺序可以依次执行收回操作。</span></p>
<p><span style="font-size: 12pt; font-family: 宋体;"><br />
</span></p>
<p><span style="font-size: 12pt;">2.3</span><span style="font-size: 12pt; font-family: 宋体;">竞争参与</span></p>
<p><span style="font-size: 12pt; font-family: 宋体;">情况简单，只有一个工作项，所以可以直接收回。</span></p>
<p><span style="font-size: 12pt; font-family: 宋体;"><br />
</span></p>
<p><span style="font-size: 12pt;">2.4</span><span style="font-size: 12pt; font-family: 宋体;">基于角色的共同参与</span></p>
<p><span style="font-size: 12pt; font-family: 宋体;">同</span><span style="font-size: 12pt;">2.1</span></p>
<p><span style="font-size: 12pt;"><br />
</span></p>
<p><strong>工作流收回模式</strong></p>
<p>后续触发节点只能是人工节点（可以是多个，至少一个），否则不支持收回。目前不支持父子流程之间的收回。</p>
<p><span style="font-size: 12pt; font-family: 宋体;">一个典型的同步汇聚情况：</span></p>
<p><span style="font-size: 12pt; font-family: 宋体;"><img src="http://www.blogjava.net/images/blogjava_net/ronghao/sh5.gif" alt="" border="0" /><br />
</span></p>
<p><span style="font-size: 12pt;"><!--[if gte vml 1]>
<![endif]--></span></p>
<p><span style="font-size: 12pt; font-family: 宋体;">节点</span><span style="font-size: 12pt;">1</span><span style="font-size: 12pt; font-family: 宋体;">首先执行完毕，但是因为是同步汇聚，所以它不会触发实际的流转；而节点</span><span style="font-size: 12pt;">2</span><span style="font-size: 12pt; font-family: 宋体;">的完成则会触发节点</span><span style="font-size: 12pt;">3</span><span style="font-size: 12pt; font-family: 宋体;">的执行。在这种情况下，节点</span><span style="font-size: 12pt;">2</span><span style="font-size: 12pt; font-family: 宋体;">的工作项可以执行收回操作，而节点</span><span style="font-size: 12pt;">1</span><span style="font-size: 12pt; font-family: 宋体;">的工作项因为后续没有触发节点而不能收回。</span></p>
<img src ="http://www.blogjava.net/RongHao/aggbug/215036.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/RongHao/" target="_blank">ronghao</a> 2008-07-15 18:28 <a href="http://www.blogjava.net/RongHao/archive/2008/07/15/215036.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>