公司内部开发的工作流引擎被以前的一批人开发出来之后,问题很多,功能实现上几个功能实现得有问题。最严重的问题是性能问题,10个用户就并发就内存溢出了,而且内存得不到释放。

    近期我的同事修改了节点的操作之后,性能就有了明显提升,100个用户并发也能够处理。也就是说节点的操作做了很多不必要的工作。虽然我1、2个礼拜之前就发现了这个问题,并且通过跟踪发现了这个严重的问题点,但我的同事现在就能够发现这个问题,可谓是非常不错!毕竟他是应届毕业生,工作了这么短时间就能够达到这水平。我还计划晚点再让它见笑,看来计划发生变动,呵呵!

    他使用的解决方案是ThreadLocal(线程局部变量)。这个定义的解释是在他提出之后我讲解给他的,并且告诉他这个方案可行。于是采用了线程局部变量对Node和WorkItemManager进行优化。虽然我理解的线程局部变量概念是没错,但是我也忽略了Tomcat的一些要点:Tomcat使用的是线程池,客户端请求时会从线程池里面获取一个可用的线程,在用户访问完毕之后线程池又及时回收,但该线程只是回收不会被关闭!!!

    问题就出在线程没有关闭,这样ThreadLocal的变量没有释放,而是在下一个用户访问该局部变量时依然保持着该变量。然而这个局部变量并不是当前用户对于的信息。因此,之后的修改就是没错操作后把局部变量给清除。(学习了,呵呵!)

    话说回来,他这个设计放在节点的查找中,其实还不算完美,因为这样是没有必要。然而线程局部变量用与WorkItemManager(待办事宜管理器),确实非常必要,以为之前的设计把它设置为静态全局变量,并且这个变量是个Map类型,再者它没能够及时清除,而且也不能过每次操作的时候对它清除,或者清除指定map的某个项,因为极有可能会有不同用户需要对同一个map的项进行访问和操作。并且,以前的设计中存在这个变量的耦合度很大,要对其解耦就需要做大幅度的代码重构。使用线程局部变量就能够解决这个“历史遗留问题”了!!好,好!