ActiveMQ-Activiti6
--------------------------------ActiveMQ---------------------------------------------
1、什么情况下使用ActiveMQ?
多个项目之间集成
(1) 跨平台
(2) 多语言
(3) 多项目
降低系统间模块的耦合度,解耦
(1) 软件扩展性
系统前后端隔离
(1) 前后端隔离,屏蔽高安全区
下载后——解压——apache-activemq-5.15.4->bin->win64->activemq启动服务(关闭窗口则关闭服务)
localhost:8161/61616 默认账户 admin,admin
什么是JMS?
Java消息服务即JMS,是一个Java平台中关于面向消息中间件的API,
用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信,ActiveMQ就是JMS接口的实现。
什么是AMQP?
AMQP是一个提供统一消息服务的应用层标注协议,基于此协议的客户端与消息中间件可传递消息,
并不受客户端/中间件不同产品,不同开发语言的限制
JMS和AMQP对比
JMS规范 AMQP协议
定义 Java api Wire-protocol
跨语言 否(不跨) 是
消息类型 2种消息模型:p2p,pub/sub 5中消息模型:direct,fanout,topic,headers,system
消息类型 6中 TextMessage,MapMessage等等 byte[]
综合评价 JMS定义了JAVA API层面的标准 主要特征面向消息,队列,路由(点对点和发布订阅)安全可靠
JMS规范(相关概念)
提供者:实现JMS规范的消息中间件服务器
客户端:发送或接受消息的应用程序
生产者/发布者:创建并发送消息的客户端
消费者/订阅者:接受并处理消息的客户端
消息:应用程序之间传递的数据内容
消息模式:在客户端之间传递消息的方式,JMS中定义了主题和队列两种模式
大部分的消息队列都有两种通信模式。
- 点对点(Point-to-Point Messaging Domain)
- 发布-订阅(Publish/Subscribe Messaging Domain)
JMS也不例外的定义了这两种消息发送模型的规范,但是并没有给予实现,实现JMS接口的消息中间件(MOM)称为JMS Provider。
点对点
消息到达消息系统,被保留在消息队列中,然后由一个或者多个消费者消费队列中的消息,一个消息只能被一个消费者消费,然后就会被移除。例如订单处理系统。
发布-订阅
消息发送时指定主题(或者说通道),消息被保留在指定的主题中,消费者可以订阅多个主题,并使用主题中的所有的消息,例如现实中的电视与电视频道。所有客户端包括发布者和订阅者,主题中的消息可以被所有的订阅者消费,消费者只能消费订阅之后发送到主题中的消息。
JMS编码接口
ConnectionFactory用于创建连接到消息中间件的连接工厂
Connection代表应用程序和消息服务器之间的连接
Destination指消息发布和接受的地点,包括队列或主题
Session表示一个单线程的上下文,用于发送和接受消息
MessageConsumer由会话创建,用于接受发送到目标的消息
MessageProducer由会话创建,用于发送消息到目标
Message是在消费者和生产者之间传送的对象,消息头,一组消息属性,一个消息体
JMS接口之间的关系
1.ConnectionFactory
2.Connection
3.Session
4.MessageConsumer/MessageConsumer
5.Destination/Message/Destination
队列模式的消息演示
//生产者
public class AppProducer {
private static final String url="tcp://localhost:61616";//ActiveMQ端口
private static final String queueName="queue-test";
public static void main(String[] args)throws JMSException{
//1.创建ConnectionFactory
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(url);
//2.创建Connection
Connection connection = connectionFactory.createConnection();
//3.启动连接
connection.start();
//4.创建会话
Session session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
//5.创建一个目标
Destination destination = session.createQueue(queueName);
//6.创建一个生产者
MessageProducer producer = session.createProducer(destination);
for (int i=0;i<100;i++){
//7.创建消息
TextMessage textMessage = session.createTextMessage("text"+i);
//8.发布消息
producer.send(textMessage);
System.out.println("发布消息"+textMessage.getText());
}
//9.关闭连接
connection.close();
}
}
//消费者
public class AppConsumer {
private static final String url="tcp://localhost:61616";//ActiveMQ端口
private static final String queueName="queue-test";
public static void main(String[] args)throws JMSException{
//1.创建ConnectionFactory
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(url);
//2.创建Connection
Connection connection = connectionFactory.createConnection();
//3.启动连接
connection.start();
//4.创建会话
Session session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
//5.创建一个目标
Destination destination = session.createQueue(queueName);
//6.创建一个消费者
MessageConsumer consumer = session.createConsumer(destination);
//7.创建一个监听器
consumer.setMessageListener(new MessageListener() {
@Override
public void onMessage(Message message) {
TextMessage textMessage = (TextMessage) message;
try {
System.out.println("接收消息" + textMessage.getText());
}catch (JMSException e){
e.printStackTrace();
}
}
});
//8.关闭连接
//connection.close();
}
}
主题模式的消息演示
//生产者
public class AppProducer {
private static final String url="tcp://localhost:61616";//ActiveMQ端口
private static final String topicName="topic-test";
public static void main(String[] args)throws JMSException{
//1.创建ConnectionFactory
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(url);
//2.创建Connection
Connection connection = connectionFactory.createConnection();
//3.启动连接
connection.start();
//4.创建会话
Session session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
//5.创建一个目标
Destination destination = session.createTopic(topicName);
//6.创建一个生产者
MessageProducer producer = session.createProducer(destination);
for (int i=0;i<100;i++){
//7.创建消息
TextMessage textMessage = session.createTextMessage("text"+i);
//8.发布消息
producer.send(textMessage);
System.out.println("发布消息"+textMessage.getText());
}
//9.关闭连接
connection.close();
}
}
//消费者
public class AppConsumer {
private static final String url="tcp://localhost:61616";//ActiveMQ端口
private static final String topicName="topic-test";
public static void main(String[] args)throws JMSException{
//1.创建ConnectionFactory
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(url);
//2.创建Connection
Connection connection = connectionFactory.createConnection();
//3.启动连接
connection.start();
//4.创建会话
Session session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
//5.创建一个目标
Destination destination = session.createTopic(topicName);
//6.创建一个消费者
MessageConsumer consumer = session.createConsumer(destination);
//7.创建一个监听器
consumer.setMessageListener(new MessageListener() {
@Override
public void onMessage(Message message) {
TextMessage textMessage = (TextMessage) message;
try {
System.out.println("接收消息" + textMessage.getText());
}catch (JMSException e){
e.printStackTrace();
}
}
});
//8.关闭连接
//connection.close();
}
}
队列和主题的区别:
主题模式下如果没提前订阅的话是接收不到的!!!
主题模式下订阅者是可以全部收到的,而队列则不会
Spring JMS理论
使用Spring集成JMS连接ActiveMQ
ConnectionFactory用于管理连接工厂
一个Spring提供的连接池
JmsTemplate每次发消息都会重新创建连接,会话和productor
spring提供了SingleConnectionFactory和CachingConnectionFactory 注意:后者是继承了前者
JmsTemplate 用于发送和接收消息的模板类
是spring提供,只需向spring容器内注册这个类就可以使用JmsTemplate方便的操作jms
JmsTemplate类是线程安全的,可以在整个应用范围使用,并可以创建多个
MessageListerner消息监听器
实现一个onMessage方法,该方法只接受一个Message参数
1.pom.xml
<properties>
<spring.version>4.2.5.RELEASE</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-all</artifactId>
<version>5.9.0</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jms</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-core</artifactId>
<version>5.7.0</version>
<exclusions>
<exclusion>
<artifactId>spring-context</artifactId>
<groupId>org.springframework</groupId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
2.
common.xml
<!--开启注解的配置-->
<context:annotation-config/>
<!-- 1.ActiveMQ提供的ConnectionFactor-->
<bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="tcp://localhost:61616"/>
</bean>
<!--2.Spring jms提供的连接池ConnectionFactory-->
<bean id="connectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory">
<property name="targetConnectionFactory" ref="targetConnectionFactory"/>
</bean>
<!--一个队列目的地,点对点的-->
<bean id="queueDestination" class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg value="queue"/>
</bean>
<!--一个主题目的地,发布订阅模式--><!--更改主题模式:1.当前位置公共配置xml,2.实现类,3.消费者xml-->
<bean id="topicDestination" class="org.apache.activemq.command.ActiveMQTopic">
<constructor-arg value="topic"/>
</bean>
producer.xml
<!--引入公共配置-->
<import resource="common.xml"/>
<!--4.Spring jms提供,JmsTemplate用于发送消息-->
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="connectionFactory"/>
</bean>
<!--配置(注入)消息发送的实现类-->
<bean class="com.imooc.jms.producer.ProducerServiceImpl"/>
consumer.xml
<!--引入公共配置-->
<import resource="common.xml"/>
<!--配置(注入)消息监听器-->
<bean id="consumerMessageListener" class="com.imooc.jms.consumer.ConsumerMessageListener"/>
<!--配置消息监听容器-->
<bean id="jmsContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<!--连接工厂配置-->
<property name="connectionFactory" ref="connectionFactory"/>
<!--队列点对点-->
<!--<property name="destination" ref="queueDestination"/>-->
<!--主题模式-->
<property name="destination" ref="topicDestination"/>
<!--消息监听器-->
<property name="messageListener" ref="consumerMessageListener"/>
</bean>
3.com.imooc.jms.producer
AppProducer
public class AppProducer {
public static void main(String[] args){
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("producer.xml");
ProducerService service = context.getBean(ProducerService.class);
for (int i =0; i<100; i++){
service.sendMessage("test" + i);
}
context.close();
}
}
ProducerService
public interface ProducerService {
void sendMessage(String message);
}
ProducerServiceImpl
public class ProducerServiceImpl implements ProducerService{
@Autowired
JmsTemplate jmsTemplate;
//队列
/*@Resource(name = "queueDestination")*/
//主题
@Resource(name = "topicDestination")
Destination deprecated;
@Override
public void sendMessage(final String message) {
//使用JmsTemplate发送消息
jmsTemplate.send(deprecated, new MessageCreator() {
@Override//创建消息
public Message createMessage(Session session) throws JMSException {
TextMessage textMessage = session.createTextMessage(message);
return textMessage;
}
});
System.out.println("发送消息:"+message);
}
}
4.com.imooc.jms.consumer
AppConsumer
public class AppConsumer {
public static void main(String [] args){
ApplicationContext context = new ClassPathXmlApplicationContext("consumer.xml");
}
}
ConsumerMessageListener
//消息监听器
public class ConsumerMessageListener implements MessageListener {
@Override
public void onMessage(Message message) {
TextMessage textMessage = (TextMessage)message;
try {
System.out.println("接收消息"+textMessage.getText());
} catch (JMSException e) {
e.printStackTrace();
}
}
}
ActiveMQ集群配置
集群方式:
客户端集群:让多个消费者消费同一个队列
ActiveMQ失效转移(failover):允许当其中一台消息服务器宕机是,客户端在传输层上重新连接到其他消息服务器
语法:failover:(uri1,...,uriN)?transportOptions
transportOptions参数说明
randomize默认为true,在URl连接时是否采用随机策略
initialReconnectDelay默认为10,单位毫秒,第一次重新连接的等待时间
maxReconnectDelay默认30000,单位毫秒,最长重连时间间隔
Broker clusters: 多个Broker之间同步消息
NetworkConnector(网络连接器)
网络连接器主要用于配置ActiveMQ服务器与服务器之间的网络通信方式,用于服务器透传消息
网络连接器分为静态连接器和动态连接器
静态连接器:<networkConnectors>
<networkConnector uri="static:(tcp://127.0.0.1:61617,tcp://127.0.0.1:61618)"/>
</networkConnectors>
动态连接器:<networkConnectors>
<networkConnector uri="multicast://default"/>
</networkConnectors>
<transportConnectors>
<transportConnector uri="tcp://localhost:0" descoveryUri="multicast://default"/>
</transportConnectors>
Master Slave: 实现高可用
Shared storage master/slave共享存储 √高可用 ×负载均衡
Replicated LevelDB Store 基于复制的LevelDB Store
集群实践、
mkdir activemq
cp -rf apache-activemq-5.14.2 activemq/activemq-a
cp -rf apache-activemq-5.14.2 activemq/activemq-b
cp -rf apache-activemq-5.14.2 activemq/activemq-c
activemq-a/activemq-b/activemq-c kahadb 分别为4个文件夹
a节点
cd conf
vi activemq.xml 配置文件:其他注释掉,61616
添加网络连接器
<networkConnectors>
<networkConnector name="local_network" uri="static:(tcp://127.0.0.1:61617,tcp://127.0.0.1:61618)"/>
</networkConnectors>
vi jetty.xml
修改端口8161
a节点配置完成
-------------
b节点
注释掉61617
网络连接器
共享文件夹:因为B节点和C节点需要配置为mst/salv
<kahaDB directory="/jove/softwares/activemq/kahadb">
vi jetty.xml
端口8162
c节点(和b节点差不多)
注释掉61618
网络连接器
共享文件夹:因为B节点和C节点需要配置为mst/salv
<kahaDB directory="/jove/softwares/activemq/kahadb">
vi jetty.xml
端口8163
启动
检查:ps -ef|grep activemq
查看端口状态:netstat -anp|grep 61616
//生成者 //状态转移,出现故障自动切换
private static final String url="failover:(tcp://192.168.31.10:61617,tcp:192.168.31.10:61618)?randomize=true";//ActiveMQ端口
//消费者
private static final String url="failover:(tcp://192.168.31.10:61616,tcp://192.168.31.10:61617,tcp:192.168.31.10:61618)?randomize=true";//ActiveMQ端口
--------------------------------Activiti-------------------------------------------
什么是工作流?
StartEvent 开始
UserTask 任务
Exclusive Gateway排他网关
EndEvent 结束
Sequence Flow顺序流
购物工作流
Line
Pool
Service Task服务任务
工作流需要依靠工作流管理系统来实现
如何学习工作流?
Activiti vs JBPM
BPMN2.0
工作流技术选型
JBPM Activiti
Hibernate MyBatis
Drools Flow JBPM4
JPA Spring
Message RESTfui
环境准备:
Activiti软件包activiti-6.0.0.zip
jdk1.8
tomcat8.0
Cygwin:curl/unzip/wget
安装sdkman
Activiti6.0源码初探
概述
Activiti目录s
.idea
distro发布
eclipse配置文件
modules源码
qa 测试
scripts 脚本
tooling 脚手架
pom.xml 管理了很多modules,流程模型的管理
核心模块
module/activiti-engine 核心引擎
module/activiti-spring Spring集成模块
module/activiti-spring-boot SpringBoot集成模块
module/activiti-rest 对外提供Rest api模块
module/activiti-ldap 集成ldap用户的模块
Activiti依赖的模块
bpmn-converter模型转换
process-validation模型流程效验
image-generator流程图绘制
dmn-api 决策标准
form-api 表单
form-model
基于源码运行activiti-app
activiti-ui
activiti-app 集成发布的war工程
activiti-app-conf UI独立业务外的配置
activiti-app-logic UI的业务逻辑
activiti-app-rest 提供接口的rest api
WebConfigurer
Hello World之Activiti6.0
Actititi流程引擎配置
activiti.cfg.xml
//查找并解析xml配置文件activiti.cfg.xml
//提供多个静态方法创建配置对象
//实现几个基于不同场景的子类,配置方式灵活
ProcessEnigneConfiguration
ProcessEnigne
RepositoryService
RuntimeService
xxxService
ProcessEngineConfiguration的子类
ProcessEngineConfigurationImpl
StandaloneProcessEngineConfiguration
SpringProcessEngineConfiguration
手动安装Activiti脚手架
cd tooling/archetypes
clear
mvn clean install
改动pom.xml
创建对应main的resources目录
改动 package ${package}
设置maven
archetype-metadata.xml
MyUnitTest.java:包结构
cd activiti-archetype-unittest2
mvn clean install
添加脚手架:Add Archetype
Activiti数据库配置
缺省配置默认,使用H2内存数据库
配置JDBC属性,使用mybatis提供的连接池
基本配置 连接池配置
jdbcUrl jdbcMaxActiveConnections
jdbcDriver jdbcMaxldleConnections
jdbcUsername jdbcMaxCheckoutTime
jdbcPassword jdbcMaxWaitTime
配置DataSource,可自选第三方实现
Druid:为监控而生的数据连接池 来自阿里,支持的数据库类型:如下
h2 jdbc:h2:tcp://localhost/activiti
mysql jdbc:mysql://localhost:3306/activiti
oracle jdbc:oracle:thin:@localhost:1521:xe
postgresjdbc:postaresql://localhost:5432/activiti
db2 jdbc:db2://localhost:50000/activiti
mssql jdbc:sqlserver://localhost:1433;databaseName=activiti
dbcp: 老牌数据源连接池,稳定可靠,Tomcat自带
HikariCp:来自日本的极速数据源连接池,Spring默认选择
配置databaseSchemaUpdate
false:启动时检查数据库版本,发送不匹配抛异常
true: 启动时自动检查并更新数据库表,不存在会创建
create-drop:启动时创建数据库表结构,结束时删除表结构
//是否使用历史数据
//是否使用身份数据
<property name="dbHistoryUsed" value="true"></property>
<property name="dbIdentityUsed" value="true"></property>
//定义表结构前缀,
<property name="databaseTablePrefix" value="t_"/>
Activiti日志和数据记录配置
日志组件的关系及(MDC)
日志门面 日志实现 桥接方式 改变依赖
slf4j Logback slf4j-log4j12 jcl-over-slf4j
commons-logging Log4j sf4j-jdk14 log4j-over-slf4j
MDC默认没有开启,需要手动设置LogMDC.setMDCEnable(true)
配置logback.xml日志模板%X{mdcProcessInstanceID}
流程只有在执行过程出现异常时才会记录MDC信息
配置历史记录级别(HistoryLevel)
none:不记录历史流程,性能高,流程结束后不可读取
activiti:归档流程实例和活动实例,流程变量不同步
audit: 默认值,在activiti基础上同步变量值,保存表单属性
full: 性能较差,记录所有实例和变量细节变化
配置基于db的事件日志(Event logging):方法
实验性的事件记录机制,性能影响较大
开启默认记录所有数据的变化过程,表记录快速增长
日志内容json格式,建议存入mongoDB,Elastic Search
实例操作没写!!!
Activiti命令拦截器的配置
命令模式与责任链模式
Client Receiver ConcreateCommand Invoker
CommandInterceptor
customPre default customPost CommandInvoker
拦截器的配置方式
Activiti的拦截器
Activiti作业执行器Job Executor
作业执行器的配置
asyncExecutorActivate:激活作业执行器
asyncExecutorXXX: 异步执行器的属性配置
asyncExecutor:异步执行器bean
配置自定义线程池
corePoolSize:核心线程数
maxPoolSize:最大线程数
queueCapacity:堵塞队列大小
流程定义定时启动流程
timeData:指定启动时间
timeDuration:指定持续时间间隔后执行
timeCycle:R5/P1DT1H指定事件段后周期执行
Activiti和Spring集成
集成Spring配置
添加pom依赖activiti-spring
基于Spring的默认配置activiti-context.xml
Activiti核心服务注入Spring容器
基于Spring与Activiti管理
集成Spring事物管理器
定义文件表达式中使用Spring bean
自动部署资源文件
基于Spring的流程单元测试
添加pom依赖Spring-test
辅助测试Rule:ActivitiRule
辅助测试TestCase:SpringActivitiTestCase
Activiti流程引擎及服务
Activiti.cfg.xml
流程引擎配置对象
ProcessEnigneConfiguration
流程引擎:
ProcessEnigne:RepositoryService流程定义文件的管理
流程存储服务:
管理流程定义文件xml及静态资源的服务
对特定流程的暂停和激活
流程定义启动权限管理
部署文件构造器DeploymentBuilder
部署文件查询器DeploymentQuery
流程定义文件查询对象ProcessDefinitionQuery
流程部署文件对象Deployment
流程定义文件对象ProcessDefinition
流程定义的java格式BpmnModel
RuntimeService流程进行控制
启动流程及对流程数据的控制
启动流程的常用方式(id,key,message)
启动流程可选参数(businessKey,variables,tenantId)
变量(variables)的设置和获取
流程实例(ProcessInstance)与执行流(Execution)查询
触发流程操作、接收消息和信号
TaskServie管理运行中的USTask人工任务:如增删改查
Task对象的创建、和删除,很少有
查询Task,并驱动Task节点完成执行
IdentityService用户和用户组的管理
FormService用于解析出流程定义中涉及的表单输入类型格式数据渲染:启动表单、
HistoryService运行结束的流程查询功能
管理流程实例结束后的历史数据
构建历史数据的查询对象
根据实例流程Id删除流程历史数据
ManagementService流程引擎基础管理、使用较少
DynamicBpmService6.0新增,对动态的流程模型做修改
ActivitiException异常
数据库模型设计
表结构设计
ACT_GE_* 通用数据表(表示General)
ACT_RE_* 流程定义存储表(表示Repository)
ACT_RE_DEPLOYMENT 流程部署记录表
ACT_RE_PROCDEF 流程定义信息表
ACT_RE_MODEL 模型信息表(用于web设计器)
ACT_PROCDEF_INFO 流程定义动态改变信息表
ACT_ID_* 身份信息表(表示Identity)
ACT_ID_USER 用户的基本信息
ACT_ID_INFO 用户的扩展信息
ACT_ID_GROUP 群组
ACT_ID_MEMBERSHIP 用户与群组关系
ACT_RU_* 运行时数据库表(表示Runtime)
ACT_RU_EXECUTION 流程实例与分支执行信息
ACT_RU_TASK 用户任务信息
ACT_RU_VARIABLE 变量信息
ACT_RU_IDENTITYLINK 参与者相关信息
ACT_RU_EVENT_SUBSCR 事件监听表
ACT_RU_JOB 作业表
ACT_RU_TIMER_JOB 定时器表
ACT_RU_SUSPENDED_JOB 暂停作业表
ACT_RU_DEADLETTER_JOB 死信标
ACT_HI_* 历史数据库表(History)
ACT_HI_PROCINST 历史流程实例表
ACT_HI_ACTINST 历史节点信息表
ACT_HI_TASKINST 历史任务表
ACT_HI_VARINST 历史变量
ACT_HI_IDENTITYLINK 历史参与者
ACT_HI_DETAIL 历史变更
ACT_HI_ATTACHMENT 附件
ACT_HI_COMMENT 评论
ACT_EVT_LOG 事件日志
Mysql建表语句
核心引擎activiti.mysql.create.engine.sql
历史数据activiti.mysql.create.history.sql
身份信息activiti.mysql.create.identity.sql
实体模型设计
BPMN2.0概述
是一套业务流程模型与符号建模标准
精准的执行语义来描述元素的操作
以XML为载体,以符号可视化业务
BPMN2.0组成元素:
流对象(FlowObjects)
活动 事件 网关
连接对象ConnectingObject)
顺序流 关联 数据关联 消息流
数据(Data)
数据对象 数据输入对象 数据输出对象 数据存储
泳道(Swimlanes)
池 道
描述对象(Artifacts)
组 注释
事件分类
位置分类、特性分类、定义分类
错误事件
错误事件定义、错误边界事件、
信号消息事件
信号开始事件、信号中间事件、消息事件定义
核心流程任务
Service Task 服务任务
执行实现JavaDelegate或ActivityBehavior的类
执行一个JavaDelegate对象表达式,通常是spring配置的Bean
执行调用方法表达式和值表达式
Send Task 发送消息任务
Receive Task 接收任务
User Task 用户任务
Script Task 脚本任务
JUEL脚本(默认)
Groovy脚本(依赖groovy-all.jar)
JavaScript脚本
内置变量:
<scriptTask id="scripttask" name="Script Task" scriptFormat="groovy">
<script>
def myValue="test123"
execution.setVariable("myKey",myValue)
</script>
</scriptTask>
顺序流和网关
包容性网关、事件的网关
子流程
子流程(Sub-Process)
分层建模、数据隔离、事件范围、边界事件
事件子流程(Event Sub-Process)
监听、捕获
事务子流程(Transaction Sub-Process)
调用式子流程(Call Actitity)
可以简化流程定义文件的复杂度
Activiti集成SpringBoot2.0
可以jar方式独立运行:因为将Servlet容器内嵌到了jar里,
不用部署war,jar只需jdk,相比war包更快跟简洁。
云计算天然集成:独立jar保运
@SpringBootApplication开启组件扫描和自动配置功能
Spring boot提供Maven插件运行
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
1.添加插件spring-boot-maven-plugin
2.直接运行mvn spring-boot:run
3.打包stand-alone运行
a)mvn clean package 生成jar文件
b)执行 java -jar xxx.jar
3.curl http://locahost:8080/home HellWorld
添加运维监控Actuator
//暴露出程序的信息
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
//多媒体的方式,基于json
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-hateoas</artifactId>
</dependency>
1.添加依赖spring-boot-starter-actuator
2.配置management.endpoints.web.exposure.include=*
升级Activiti6.0依赖Springboot版本为2.0
升级Spring Boot依赖并解决编译错误
更新activiti-spring-boot-starter-basic版本并安装
集成使用Activiti的AutoConfiguration功能
工作流平台搭建
需求分析:
基于SpringBoot2与Activiti6.0搭建通用的工作流引擎平台
支持流程定义文件在线设计及部署和维护
支持自定义表单与流程定义的继承
满足流程运行的用户及权限管理功能
管理角度的监控流程运行过程和历史数据
平台角度方便与第三方系统数据继承
平台搭建
技术方案:
基于Activiti6.0源代码中activiti-ui工程升级开发
升级activiti-spring-boot模块依赖版本
改造activiti-ui为Spring boot工程
基于改造后的activiti
基于activiti-engine从零开始搭建
开发步骤
1.基于源码Activiti6.0.0版本checkout出新的base分支
2.定义activiti-spring-boot、activiti-ui及子模块版本6.0.0-boot2
3.基于activiti-ui依赖版本6.0.0-boot2运行activiti-app模块
4.改造activiti-app为spring boot工程
5.升级activiti-ui使用activiti-spring-boot-starter*6.0.0-boot2
6.启动运行基于spring boot工程activiti-app
7.升级activiti-spring-boot依赖boot2.0版本:编译、排错、安装
8.重新安装activiti-ui:编译、排错、安装
9.启动运行基于spring boot2工程activiti-app
10.创建新的独立工程workflow
11.添加依赖(6.0.0)及配置文件
12.集成web相关资源文件
电商业务建模
工作流平台部署和运维
回顾:准备环境并部署
准备物料
Activiti软件包activiti-6.0.0.zip
Java环境1.8.0_161
Servlet容器apache-tomcat-8.0.50.zip
安装sdkman
$ curl -s "https://getsdkman.io"|bask
$ source "$HOME/.sdkman/bin/sdkman-init.sh"
$ sdk varsion
安装JDK
$ sdk install java 8u161-oracle
$ java -version
$ echo $JAVA_HOME
部署Tomcat
$ wget http://mirror.bit.edu.cn/apache/tomcat/tomcat-8/v8.0.50/bin/apache-tomcat-8.0.50.zip
$ tar -zxcf apache-tomcat-8.0.50.zip
$ ./apache-tomcat-8.0.50/bin/startup.sh
$ jps -mlv
部署Activiti
$ wget http://github.com/Activiti/Activiti/releases/download/activiti-6.0.0/activiti-6.0.0.zip
$ tar -zxcf activiti.6.0.0.zip
$ cp activiti-6.0.0/wars/activiti-app.war apache-tomcat-8.0.50/webapps
$ cp activiti-6.0.0/wars/activiti-admin.war apache-tomcat-8.0.50/webapps
云环境部署
选择镜像:Java多版本环境(Nginx Tomcat JDK Mysql),注:将自动安装好
切换JDK版本和Tomcat版本
查看系统配置
上传部署文件
$scp /Users/jimmy/Code/workflow/target/wf.war
root@140.143.161.179:/yjdata/www/www
$ /yjdata/www/tomcat.sh start
$ open http://140.143/161.179/wf
系统扩容
横向扩容tenantId(多租户)
空租户引擎数据库-多租户共享数据库-多租户映射数据库
踩过的坑
线上运行不是使用自动部署
基于spring的流程配置对象默认部署位置classpath:/processes
系统每次重启都会自动部署一次,仅对版本号更新无实际意义
推荐在线设计流程定义文件,或者设计好后导入流程
流程中的变量建议仅使用基础类型+String$Date
基础类型可以很好的序列化的变量表
Activiti对一般的Java VO对象序列化方式采用ObjectOutputStream
可以自定义VariableType实现特定对象的序列化方式
Activiti6集成Spring Boot2的不兼容问题
EndPoint的实现方式变化
Spring Data Jpa中delete方法API发送变化
流程引擎自动装配默认忽略FormEngineConfiguration