activiti5.10解決分散式叢集部署的主鍵問題
一、概要綜述
1、activiti5是jbpm4升級上來的一款最新版工作流引擎,已經將自己的表劃分為4類:執行時、通用資料、歷史資料、流程相關資料,但是有一個核心問題就是是否支援叢集部署,經過我對原始碼的初步分析發現,他的預設主鍵策略是全域性獲取一個通用表中的欄位來做增加,在大併發量的情況下會出現主鍵重複的問題
2、activiti5的預設主鍵策略分析:
(1)、每次需要主鍵的時候從act_ge_property表中的next.dbid中獲取下一個主鍵值,但是主鍵增長步長是100,也就是說每次從這裡獲取下一個值的時候,上次是100,下次的值是200.
(2)、他們所有需要主鍵的表都從這個表中獲取下一個值
(3)、但是他們針對性能做了一個取巧處理,就是每次步長100,將這個步長cache在本地用sychronize方法呼叫,也就是說一段時間內只需要在本地獲取主鍵即可,不需要訪問資料實時更新,一定程度的緩解了資料庫呼叫壓力
(4)、但是對於高併發來說,這個只能區域性緩解,併發寫入壓力,還是有造成主鍵重複的概率
3、解決方案分析
(1)、因為activiti的主鍵是統一管理,直接通過集中替換主鍵策略就可以完成主鍵策略的替換
(2)、經過分析原始碼發現activiti的流程引擎的主鍵引用採用的方式是先看spring配置的 idGenerator 屬性是否有外部注入,如果沒有,才使用預設的主鍵策略生成主鍵,所以我們只需要針對配置檔案進行主鍵策略的替換即可
(3)、尋找一種能產生唯一主鍵的生成策略,這裡uuid可能是一個比較通用的解決方案,不過悲劇的是uuid對於人去識別可能不是很友好,但是對於程式來說無所謂了,而activiti本身的id欄位也支援uuid演算法來生成主鍵。
二、實施方案
為了快速見效,直接用activiti官方提供的activiti-explorer專案來更換主鍵策略來驗證效果
1、直接找到部署的war包,更新它的配置檔案,來指定主鍵策略。這裡我們要找的就是那個applicationContext.xml檔案
<bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration"> <property name="dataSource" ref="dataSource" /> <property name="transactionManager" ref="transactionManager" /> <property name="databaseSchemaUpdate" value="true" /> <property name="jobExecutorActivate" value="true" /> <property name="customFormTypes"> <list> <ref bean="userFormType"/> </list> </property> <strong> <property name="idGenerator"><bean class="org.activiti.engine.impl.persistence.StrongUuidGenerator" /></property></strong> </bean>
2、將主鍵策略要引用的uuid這個jar包引入,這裡我使用java-uuid-generator-3.1.2.jar
3、重新啟動tomcat來做相關流程部署,發現數據庫中的主鍵策略真的變為uuid了(這裡別忘記先清理庫啊,這樣看起來效果才不會被幹擾,因為以前一直用的是預設主鍵生成策略,生成的int型別的主鍵)