zoukankan      html  css  js  c++  java
  • Zeebe服务学习1-简单部署与实现demo

    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="&#62;=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>
    View Code

    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实现了。

  • 相关阅读:
    SQL Server 之 在与SQLServer建立连接时出现与网络相关的或特定于实例的错误的解决方法
    Exchange学习:EWS 通过流通知和拉取通知订阅Exchange新邮件提醒
    拓扑提供程序在端点TopologyClientTcpEndpoint (localhost) 上找不到microsoft exchange active directory拓扑服务的解决办法之一
    解决vs下载速度慢或者无法下载,无法下载.net sdk的解决办法
    记一个List转List<Object>的方法
    SqlServer数据库存入decimal类型数据注意事项
    如何在vs里面查看方法重载
    LeetCode 198. 打家劫舍 Java
    LeetCode面试题53
    LeetCode 1010. 总持续时间可被 60 整除的歌曲 Java
  • 原文地址:https://www.cnblogs.com/walt/p/11298154.html
Copyright © 2011-2022 走看看