1.Zeebe是什么?

Camunda公司研发的工作流引擎Zeebe,目标是对微服务的编排。具体详细介绍可以参考官网:https://zeebe.io/what-is-zeebe/

2.背景

随着微服务的发展,大家都单体服务进行了拆分,解耦,这样做引发了另外的一个问题:之前一个接口实现的功能,现在需要调用几个接口才能完成。如何解决这些原子性的接口呢?

这时候我们想到了Zeebe服务。

3.服务部署

3.1 第一步:安装环境,不管你是Linux系统还是Win系统,首先需要安装上docker,因为我的机器是Win系统,本文就是介绍Windows系统下安装使用情况

确保机器已经安装docker(没有安装的可以下载docker-win,进行安装)

3.2 第二步:在cmd里面执行命令:

docker run --name zeebe -p 26500:26500 camunda/zeebe:latest

  至此,Zeebe服务已经安装成功了。

4.demo

4.1 第一步:创建一个控制台项目,这个应该都会

4.2 第二步:在项目中引用Zeebe客户端的nuget包,目前版本是0.11.0

4.3 第三步:建模,使用Zeebe Modeler工具进行建模

我需要实现的流程是:

具体的BPMN代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:zeebe="http://camunda.org/schema/zeebe/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="Definitions_1011qyd" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Zeebe Modeler" exporterVersion="0.6.2">
<bpmn:process id="instock-process" name="instock-process" isExecutable="true">
<bpmn:startEvent id="start" name="start">
<bpmn:outgoing>SequenceFlow_instock</bpmn:outgoing>
</bpmn:startEvent>
<bpmn:serviceTask id="createinstock" name="createinstock">
<bpmn:extensionElements>
<zeebe:taskDefinition type="createinstock" retries="3" />
<zeebe:ioMapping>
<zeebe:input source="InStockData" target="InStockData" />
</zeebe:ioMapping>
</bpmn:extensionElements>
<bpmn:incoming>SequenceFlow_instock</bpmn:incoming>
<bpmn:outgoing>SequenceFlow_modifystock</bpmn:outgoing>
</bpmn:serviceTask>
<bpmn:sequenceFlow id="SequenceFlow_instock" name="SequenceFlow_instock" sourceRef="start" targetRef="createinstock" />
<bpmn:serviceTask id="modifystock" name="modifystock">
<bpmn:extensionElements>
<zeebe:taskDefinition type="modifystock" retries="3" />
<zeebe:ioMapping>
<zeebe:input source="StockData" target="StockData" />
</zeebe:ioMapping>
</bpmn:extensionElements>
<bpmn:incoming>SequenceFlow_modifystock</bpmn:incoming>
<bpmn:outgoing>SequenceFlow_gateway</bpmn:outgoing>
</bpmn:serviceTask>
<bpmn:sequenceFlow id="SequenceFlow_modifystock" name="SequenceFlow_modifystock" sourceRef="createinstock" targetRef="modifystock" />
<bpmn:exclusiveGateway id="checknum" name="checknum">
<bpmn:incoming>SequenceFlow_gateway</bpmn:incoming>
<bpmn:outgoing>morethan300</bpmn:outgoing>
<bpmn:outgoing>lessthan300</bpmn:outgoing>
</bpmn:exclusiveGateway>
<bpmn:sequenceFlow id="SequenceFlow_gateway" name="SequenceFlow_gateway" sourceRef="modifystock" targetRef="checknum" />
<bpmn:serviceTask id="notify" name="notify">
<bpmn:extensionElements>
<zeebe:taskDefinition type="notify" retries="3" />
</bpmn:extensionElements>
<bpmn:incoming>morethan300</bpmn:incoming>
<bpmn:outgoing>SequenceFlow_end</bpmn:outgoing>
</bpmn:serviceTask>
<bpmn:sequenceFlow id="morethan300" name=">=300" sourceRef="checknum" targetRef="notify">
<bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">stocknum&gt;=300</bpmn:conditionExpression>
</bpmn:sequenceFlow>
<bpmn:endEvent id="end" name="end">
<bpmn:incoming>lessthan300</bpmn:incoming>
<bpmn:incoming>SequenceFlow_end</bpmn:incoming>
</bpmn:endEvent>
<bpmn:sequenceFlow id="lessthan300" name="lessthan300" sourceRef="checknum" targetRef="end">
<bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">stocknum&lt;300</bpmn:conditionExpression>
</bpmn:sequenceFlow>
<bpmn:sequenceFlow id="SequenceFlow_end" name="SequenceFlow_end" sourceRef="notify" targetRef="end" />
</bpmn:process>
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="instock-process">
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="start">
<dc:Bounds x="112" y="159" width="36" height="36" />
<bpmndi:BPMNLabel>
<dc:Bounds x="119" y="202" width="23" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="ServiceTask_0zssdcw_di" bpmnElement="createinstock">
<dc:Bounds x="265" y="137" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="SequenceFlow_0yllvib_di" bpmnElement="SequenceFlow_instock">
<di:waypoint x="148" y="177" />
<di:waypoint x="265" y="177" />
<bpmndi:BPMNLabel>
<dc:Bounds x="163" y="159" width="88" height="27" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="ServiceTask_1db0jmn_di" bpmnElement="modifystock">
<dc:Bounds x="481" y="137" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="SequenceFlow_1uaplin_di" bpmnElement="SequenceFlow_modifystock">
<di:waypoint x="365" y="177" />
<di:waypoint x="481" y="177" />
<bpmndi:BPMNLabel>
<dc:Bounds x="383" y="159" width="80" height="27" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="ExclusiveGateway_1sjnk3d_di" bpmnElement="checknum" isMarkerVisible="true">
<dc:Bounds x="723" y="152" width="50" height="50" />
<bpmndi:BPMNLabel>
<dc:Bounds x="722" y="128" width="51" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="SequenceFlow_1hhfiqd_di" bpmnElement="SequenceFlow_gateway">
<di:waypoint x="581" y="177" />
<di:waypoint x="723" y="177" />
<bpmndi:BPMNLabel>
<dc:Bounds x="610" y="159" width="85" height="27" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="ServiceTask_016w4wa_di" bpmnElement="notify">
<dc:Bounds x="954" y="319" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="SequenceFlow_1ffqddr_di" bpmnElement="morethan300">
<di:waypoint x="748" y="202" />
<di:waypoint x="748" y="359" />
<di:waypoint x="954" y="359" />
<bpmndi:BPMNLabel>
<dc:Bounds x="839" y="341" width="32" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="EndEvent_01b3gni_di" bpmnElement="end">
<dc:Bounds x="1208" y="159" width="36" height="36" />
<bpmndi:BPMNLabel>
<dc:Bounds x="1217" y="202" width="19" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="SequenceFlow_00imkpl_di" bpmnElement="lessthan300">
<di:waypoint x="773" y="177" />
<di:waypoint x="1208" y="177" />
<bpmndi:BPMNLabel>
<dc:Bounds x="961" y="159" width="60" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="SequenceFlow_0c9jvp6_di" bpmnElement="SequenceFlow_end">
<di:waypoint x="1004" y="319" />
<di:waypoint x="1004" y="177" />
<di:waypoint x="1208" y="177" />
<bpmndi:BPMNLabel>
<dc:Bounds x="977" y="245" width="85" height="27" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn:definitions>

4.4 第四步:写代码

(1)客户端代码:

 internal class Program
{
private static readonly string DemoProcessPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Resources", "instock-process.bpmn");
private static readonly string ZeebeUrl = "127.0.0.1:26500";
private static dynamic WorkflowInstanceVariables = new
{
stocknum = 100
};
public static async Task Main(string[] args)
{
InitClient.Initialize(); // create zeebe client
var client = ZeebeClient.NewZeebeClient(ZeebeUrl);
// deploy
// var deployResponse = await client.NewDeployCommand().AddResourceFile(DemoProcessPath).Send(); // create workflow instance
// var workflowKey = deployResponse.Workflows[0].WorkflowKey;//2251799813685495
// 模拟调用
var workflowInstance = await client
.NewCreateWorkflowInstanceCommand()
.WorkflowKey(2251799813685495)
.Variables(JsonConvert.SerializeObject(WorkflowInstanceVariables))
.Send(); }

(2)服务端代码:

 internal class Program
{
private static Dictionary<string, string> JobTypeAndMethod = new Dictionary<string, string>()
{
{ "createinstock","InStockJobHandler"},
{ "modifystock","StockJobHandler"},
{ "notify","NotifyJobHandler"}
};
private static readonly string ZeebeUrl = "127.0.0.1:26500";
public static async Task Main(string[] args)
{
InitClient.Initialize(); // create zeebe client
var client = ZeebeClient.NewZeebeClient(ZeebeUrl); // open job worker
await OpenJobWorkers(client);
} private static Task OpenJobWorkers(IZeebeClient client)
{ using (var signal = new EventWaitHandle(false, EventResetMode.AutoReset))
{
foreach (var item in JobTypeAndMethod)
{
client.NewWorker()
.JobType(item.Key)
.Handler(JobHandlerFactory.GetJobType(item.Value))
.MaxJobsActive(5)
.Name(item.Key)
.AutoCompletion()
.PollInterval(TimeSpan.FromSeconds(1))
.Timeout(TimeSpan.FromSeconds(10))
.Open();
}
// blocks main thread, so that worker can run
signal.WaitOne();
}
return Task.CompletedTask;
} }

客户端的代码中,只有第一次会将BPMN文件进行部署,Zeebe服务会返回一个Key,之后如果建模数据不发生改变的情况下,就可以直接使用key进行调用即可了,如果发生变化需要再一次部署才行;

每次部署都会改变工作流程的Version值(默认获取的事latestVersion)。

至此,一个简单的Zeebe Demo实现了。

最新文章

  1. workbench中safe update
  2. OEM代工厂产品经理个人经历谈
  3. 将ECSHOP会员注册页面的Email修改成非必填项
  4. mac mysql环境配置
  5. 总结下遇到的C#新语法
  6. 一道面试题,简单模拟spring ioc
  7. javaweb学习总结二十(http响应)
  8. ubuntu中下运行asp.net程序
  9. POJ 1472 Instant Complexity 应该叫它编程题。。
  10. BZOJ 2693 jzptab
  11. Java jsp基本结构
  12. 深入学习Java8 Lambda (default method, lambda, function reference, java.util.function 包)
  13. uploadify上传文件(1)--下载
  14. MQTT和paho(一)
  15. 解决服务器代码执行mvn test后在classes和test-classes下找不到Spring的bean.xml配置文件问题
  16. 阿里云 putty链接服务器出现 server refused our key
  17. AngularJS 指令中的 replace:true
  18. Logback 日志持久化
  19. 解决apache上访问 cgi脚本时总是在网页中显示出脚本的源代码而不是执行结果的问题
  20. Http协议中常用字段总结(不定时完善中)

热门文章

  1. Codeforces Round #681 (Div. 2, based on VK Cup 2019-2020 - Final) D. Extreme Subtraction (贪心)
  2. Python 往Excel写数据
  3. SSH 密钥认证
  4. 2.了解nginx常用的配置
  5. select(),fd_set(),fd_isset()
  6. u-boot 移植 ---&gt;3、S5PV210启动序列
  7. Inkscape 太慢
  8. npm version ^ meaning
  9. GitHub Classroom
  10. Angular Learning Paths