camunda7流程引擎外部任务(External Task)如何使用

news2024/11/20 19:36:59

camunda7流程引擎支持两种执行服务任务的方式:

  1. 内部任务:同步调用与流程应用程序一起部署的代码
  2. 外部任务:在列表中提供可由员工轮询的工作单元

第一个选项可以通过委托代码(Delegation) 或者脚本(Script)实现.相反,外部(服务)任务的工作方式是Process Engine流程引擎将工作单元发布给Worker来获取和完成。我们将其称为外部任务模式(the external task pattern)。外部任务模式是camunda工作流引擎特有的机制,其它开源流程引擎activiti、flowable、jbpm等没有外部任务功能。

请注意,上述区别并未说明实际的“业务逻辑”是在本地实现还是作为远程服务实现。由内部服务任务调用的Java委托可以实现业务逻辑本身,也可以调用Web/REST服务,向另一个系统发送消息等等。外部工作人员也是如此。工作人员可以直接实现业务逻辑,也可以再次委托给远程系统。

设计流程时,外部任务可以在流程设计器上配置出来:

如何配置一个external task外部任务和示例demo,详细文档:https://lowcode.blog.csdn.net/article/details/136164616

在线体验camunda流程引擎功能:http://www.yunchengxc.com

1、外部任务模式

执行外部任务(external task)的流程在概念上可以分为三个步骤,如下图所示:

  1. 流程引擎(Process Engine创建外部任务实例
  2. 外部工作者External Worker获取并锁定外部任务
  3. 外部工作者External Worker & 流程引擎(Process Engine:完成外部任务实例

上面的这个例子描述的是让客户确认收货地址是否正确,客户确认收货地址(Validate Address)这个动作就是一个外部任务。当Process Engine遇到配置为外部处理的服务任务时,它会创建一个外部任务实例并将其添加到外部任务列表中(步骤1)。任务实例接收标识要执行的工作的性质的主题。在将来的某个时间,外部工作人员可能会获取并锁定特定主题集的任务(步骤2)。为了防止多个工作线程同时获取一个任务,任务具有基于时间戳的锁定,该锁定在获取任务时设置。只有当锁过期时,另一个工作线程才能再次获取该任务。当外部工作人员完成了所需的工作时,它可以向流程引擎发出信号,以在服务任务之后继续流程执行(步骤3)。

1.1、如何理解外部任务-类比用户任务

外部任务在概念上与用户任务非常相似。在第一次尝试理解外部任务模式时,将其与用户任务进行类比会很有帮助:用户任务由流程引擎创建并添加到任务列表中。然后,流程引擎等待人工用户查询列表,获取任务,然后完成任务。外部任务与此类似:创建外部任务,然后将其添加到主题中。然后,外部应用程序查询主题并锁定任务。锁定任务后,应用程序可以处理并完成该任务。

此模式的本质是执行实际工作的实体独立于流程引擎,并通过轮询流程引擎的API来接收工作项。这样做有以下好处:

  • 跨越系统边界:外部工作者不需要运行在相同的Java进程中、相同的机器上、相同的集群中。所需要的只是它可以访问流程引擎的API(通过REST或Java)。由于轮询模式,工作者不需要公开任何接口以供流程引擎访问。
  • 跨越技术边界:外部工作者不需要在Java中实现。相反,可以使用任何最适合执行工作项的技术,以及可用于访问流程引擎的API(通过REST或Java)的技术。
  • 专业工作人员:外部工作人员不需要是通用应用程序。每个外部任务实例接收标识要执行的任务的性质的主题名称。工作人员只能轮询他们可以处理的主题的任务。
  • 细粒度扩展:如果有高负载集中在服务任务处理上,则各个主题的外部工作者的数量可以独立于流程引擎进行扩展。
  • 独立维护:工作者(Workers 可以在不中断操作的情况下独立于流程引擎进行维护。例如,如果特定主题的工作人员停机(例如,由于更新),则对流程引擎没有直接影响。这样的工作者的外部任务的执行被适度降级:它们被存储在外部任务列表中,直到外部工作者恢复操作。

2、处理外部任务

要处理外部任务,必须在BPMN XML中声明它们。在运行时,可以通过Java和REST API访问外部任务实例。下面解释了API的概念,并重点介绍了Java API。通常,REST API更适合这种情况,尤其是在使用不同技术实现在不同环境中运行的Workers时。

在流程定义的BPMN XML中,通过使用属性camunda:type和camunda:topic,可以将服务任务声明为由外部工作者执行。例如,服务任务Validate Address可以配置为提供主题AddressValidation的外部任务实例,如下所示:

<serviceTask id="validateAddressTask"
  name="Validate Address"
  camunda:type="external"
  camunda:topic="AddressValidation" />

可以使用表达式而不是常数值来定义主题名称。

此外,其他类似服务任务的元素,如发送任务、业务规则任务和抛出消息事件,都可以使用外部任务模式来实现。有关详细信息,请参阅BPMN 2.0实现参考。

2.1、错误事件定义

外部任务允许定义引发指定BPMN错误的错误事件。这可以通过向任务的定义中添加camunda:errorEventDefinition扩展元素来完成。与bpmn:errorEventDefinition相比,camunda:errorEventDefinition元素接受一个额外的表达式属性,该属性支持任何JUEL表达式。在表达式中,您可以通过键externalTask访问ExternalTaskEntity对象,该键为errorMessage、errorDetails、workerId、retries等提供getter方法。

在调用ExternalTaskService#complete和ExternalTaskService#handleFailure时计算表达式。如果表达式的计算结果为true,则实际的方法执行将被取消,并通过引发相应的BPMN错误来替换。此错误可能会被错误边界事件捕获。这意味着错误事件定义可以在成功和失败场景中使用——即使任务成功完成,您仍然可以决定抛出BPMN错误。

<serviceTask id="validateAddressTask"
  name="Validate Address"
  camunda:type="external"
  camunda:topic="AddressValidation" >
  <extensionElements>
    <camunda:errorEventDefinition id="addressErrorDefinition" 
      errorRef="addressError" 
      expression="${externalTask.getErrorDetails().contains('address error found')}" />
  </extensionElements>
</serviceTask>

有关外部任务的错误事件定义功能的更多信息,请参见表达式语言用户指南.中介绍了RPA业务流程方案在外部任务中的具体使用。Camunda平台RPA网桥.

2.2、Rest API

请参见REST API文档 了解如何通过HTTP访问API操作。

https://docs.camunda.org/rest/camunda-bpm-platform/7.19/#tag/External-Task

2.2.1、获取和锁定外部任务的长轮询

无论请求的信息是否可用,服务器都会立即响应普通的HTTP请求。这不可避免地导致客户端必须执行多个重复请求直到信息可用(轮询)的情况。就资源而言,这种方法显然是昂贵的。

在长轮询的帮助下,如果没有外部任务可用,服务器将挂起请求。一旦发生新的外部任务,就重新激活请求并执行响应。暂停仅限于可配置的时间段(超时)。

长轮询大大减少了请求的数量,并使服务器和客户端都能更有效地使用资源。

另请参阅REST API文档.https://docs.camunda.org/rest/camunda-bpm-platform/7.19/#tag/External-Task/operation/fetchAndLock

2.2.2、唯一工作程序请求

默认情况下,多个workers 工人可以使用同一个workerId。为了确保服务器端的workerId唯一性,可以激活“唯一工人请求”标志。此配置标志仅影响长轮询请求,而不影响普通的“获取和锁定”请求。如果“唯一工作人员请求”标志已激活,则在收到新请求时,将取消具有相同workerId的挂起请求。

为了启用“Unique Worker Request”标志,需要通过将上下文参数fetch and lock Unique Worker Request设置为true来调整引擎休息工件中包含的引擎休息/WEB-INF/WEB.xml文件。请考虑以下配置片段:

<!-- ... -->
<context-param>
  <param-name>fetch-and-lock-unique-worker-request</param-name>
  <param-value>true</param-value>
</context-param>
<!-- ... -->

2.3、Java API

外部任务的Java API的入口点是ExternalTaskService。可以通过ProcessEngine.GetExternalTaskService()访问它。

下面是一个交互示例,它获取10个任务,在一个循环中处理这些任务,并且对于每个任务,要么完成任务,要么将其标记为失败。

List<LockedExternalTask> tasks = externalTaskService.fetchAndLock(10, "externalWorkerId")
  .topic("AddressValidation", 60L * 1000L)
  .execute();
for (LockedExternalTask task : tasks) {
  try {
    String topic = task.getTopicName();
    // work on task for that topic
    ...
    // if the work is successful, mark the task as completed
    if(success) {
      externalTaskService.complete(task.getId(), variables);
    }
    else {
      // if the work was not successful, mark it as failed
      externalTaskService.handleFailure(
        task.getId(),
        "externalWorkerId",
        "Address could not be validated: Address database not reachable",
        1, 10L * 60L * 1000L);
    }
  }
  catch(Exception e) {
    //... handle exception
  }
}

以下部分更详细地介绍了与ExternalTaskService的不同交互。

2.3.1、获取外部任务

为了实现轮询工作者,可以使用方法ExternalTaskService#FetchAndLock执行获取操作。此方法返回一个Fluent构建器,该构建器允许定义一组主题来获取任务。考虑以下代码片段:

List<LockedExternalTask> tasks = externalTaskService.fetchAndLock(10, "externalWorkerId")
  .topic("AddressValidation", 60L * 1000L)
  .topic("ShipmentScheduling", 120L * 1000L)
  .execute();
for (LockedExternalTask task : tasks) {
  String topic = task.getTopicName();
  // work on task for that topic
  ...
}

此代码最多获取AddressValidation和ShipmentScheduling主题的10个任务。结果任务专为ID为ExternalWorkerID的员工锁定。锁定是指在从获取时间开始的一段时间内为该工作线程保留任务,并防止另一个工作线程在锁定有效时获取相同的任务。如果锁过期并且任务尚未完成,则不同的工作线程可以获取它,以便静默失败的工作线程不会无限期地阻止执行。单个主题获取说明中给出了确切的持续时间:AddressValidation任务锁定60秒(60L*1000L毫秒),而ShipmentScheduling任务锁定120秒(120L*1000L毫秒)。锁过期持续时间不应短于预期执行时间。它也不应该太高,如果这意味着超时时间太长,直到重试任务,以防工作者静默失败。

执行任务所需的变量可以与任务一起获取。例如,假设AddressValidation任务需要一个地址变量。使用此变量获取任务可能如下所示:

List<LockedExternalTask> tasks = externalTaskService.fetchAndLock(10, "externalWorkerId")
  .topic("AddressValidation", 60L * 1000L).variables("address")
  .execute();
for (LockedExternalTask task : tasks) {
  String topic = task.getTopicName();
  String address = (String) task.getVariables().get("address");
  // work on task for that topic
  ...
}

然后,结果任务包含所请求变量的当前值。请注意,变量值是在外部任务执行的范围层次结构中可见的值。

为了获取所有变量,应省略对方法variables()的调用。

List<LockedExternalTask> tasks = externalTaskService.fetchAndLock(10, "externalWorkerId")
  .topic("AddressValidation", 60L * 1000L)
  .execute();
for (LockedExternalTask task : tasks) {
  String topic = task.getTopicName();
  String address = (String) task.getVariables().get("address");
  // work on task for that topic
  ...
}

为了启用序列化变量值(通常是存储自定义Java对象的变量)的反序列化,必须()调用EnableCustomObjectDeserialization。否则,一旦从变量映射中检索到序列化的变量,就会抛出一个异常,即对象未被反序列化。

List<LockedExternalTask> tasks = externalTaskService.fetchAndLock(10, "externalWorkerId")
  .topic("AddressValidation", 60L * 1000L)
  .variables("address")
  .enableCustomObjectDeserialization()
  .execute();
for (LockedExternalTask task : tasks) {
  String topic = task.getTopicName();
  MyAddressClass address = (MyAddressClass) task.getVariables().get("address");
  // work on task for that topic
  ...
}

2.3.2、外部任务优先级

外部任务优先级划分与作业优先级划分类似。同样的问题也存在于饥饿中,这是应该考虑的。有关更多详细信息,请参见工作优先级.

为外部任务配置优先级。如何在配置中启用和禁用外部任务优先级。可以在流程引擎配置上设置两个相关的配置属性:

productionPrioritydExternalTasks:控制流程引擎是否为外部任务分配优先级。默认值为true。如果不需要优先级,则可以将流程引擎配置属性producePrioritydExternalTasks设置为false。在这种情况下,所有外部任务的优先级都为0。有关如何指定外部任务优先级以及流程引擎如何分配这些优先级的详细信息,请参阅以下“指定外部任务优先权”部分。

2.2.3、指定外部任务优先级

外外部任务优先级可以在BPMN模型中指定,也可以在运行时通过API覆盖。

外部任务优先级可以在流程或活动级别分配。为此,可以使用Camunda扩展属性Camunda:taskPriority。

为了指定优先级,同时支持常数值和表达式。使用常数值时,会将相同的优先级分配给流程或活动的所有实例。另一方面,表达式允许为流程或活动的每个实例分配不同的优先级。表达式的计算结果必须为Java长范围内的数字。具体值可以是复杂计算的结果,并基于用户提供的数据(来自任务表单或其他来源)。

在流程实例级别配置外部任务优先级时,camunda:taskPriority属性需要应用于bpmn<process…>要素:

<bpmn:process id="Process_1" isExecutable="true" camunda:taskPriority="8">
  ...
</bpmn:process>

其效果是,流程中的所有外部任务都继承相同的优先级(除非在本地被覆盖)。上面的示例显示了如何使用常数值来设置优先级。这样,相同的优先级将应用于流程的所有实例。如果不同的流程实例需要以不同的优先级执行,则可以使用表达式:

<bpmn:process id="Process_1" isExecutable="true" camunda:taskPriority="${order.priority}">
  ...
</bpmn:process>

在上述示例中,基于变量顺序的属性优先级来确定优先级。

服务任务级别的优先级。在服务任务级别配置外部任务优先级时,camunda:taskPriority属性需要应用于bpmn<serviceTask…>要素服务任务必须是具有属性camunda:type=“external”的外部任务。

  ...
  <serviceTask id="externalTaskWithPrio" 
               camunda:type="external" 
			   camunda:topic="externalTaskTopic" 
			   camunda:taskPriority="8"/>
  ...

其效果是为定义的外部任务设置优先级(覆盖流程TaskPriority)。上面的示例显示了如何使用常数值来设置优先级。这样,在流程的不同实例中,将相同的优先级应用于外部任务。如果不同的流程实例需要以不同的外部任务优先级执行,则可以使用表达式:

  ...
  <serviceTask id="externalTaskWithPrio" 
               camunda:type="external" 
			   camunda:topic="externalTaskTopic" 
			   camunda:taskPriority="${order.priority}"/>
  ...

在上述示例中,基于变量顺序的属性优先级来确定优先级。

2.2.4、获取具有优先级的外部任务

要根据优先级获取外部任务,可以使用带有参数usePriority的重载方法ExternalTaskService#FetchAndLock。没有布尔参数的方法任意返回外部任务。如果给定参数,则返回的外部任务按降序排列。请参阅以下有关外部任务优先级的示例:

List<LockedExternalTask> tasks =
  externalTaskService.fetchAndLock(10, "externalWorkerId", true)
  .topic("AddressValidation", 60L * 1000L)
  .topic("ShipmentScheduling", 120L * 1000L)
  .execute();
for (LockedExternalTask task : tasks) {
  String topic = task.getTopicName();

  // work on task for that topic
  ...
}

2.2.5、完成任务

在获取并执行所请求的工作之后,工作者可以通过调用ExternalTaskService#complete方法来完成外部任务。工作线程只能完成它之前获取并锁定的任务。如果任务在此期间已被其他工作线程锁定,则会引发异常。

2.2.6、错误事件

外部任务可以包括错误事件定义 如果错误事件的表达式的计算结果为true,则可以取消#complete的执行。如果错误事件的表达式计算引发异常,则对#Complete的调用将因相同的异常而失败。

2.2.7、扩展外部任务上的锁

当外部任务被工作线程锁定时,可以通过调用ExternalTaskService#extendLock方法来延长锁定持续时间。工作线程可以指定更新超时的时间量(以毫秒为单位)。锁只能由拥有给定外部任务的锁的工作线程扩展。

2.2.8、任务失败报告

员工可能无法始终成功完成任务。在这种情况下,它可以使用ExternalTaskService#HandleFailure向流程引擎报告故障。与#Complete一样,#HandleFailure只能由拥有任务最新锁的工作线程调用。#handleFailure方法有四个额外的参数:errorMessage、errorDetails、retries和retryTimeout。错误消息可以包含对问题性质的描述,并且限制为666个字符。当再次获取或查询任务时,可以访问它。ErrorDetails可以包含完整的错误描述,并且长度不受限制。根据任务ID参数,可通过单独的方法ExternalTaskService#getExternalTaskErrorDetails访问错误详细信息。通过Retries和RetryTimout,工作人员可以指定重试策略。将重试次数设置为大于0的值时,可以在RetryTimeout过期后再次获取任务。 将“重试次数”设置为0时,无法再获取任务,并为该任务创建突发事件。

考虑以下代码片段:

List<LockedExternalTask> tasks = externalTaskService.fetchAndLock(10, "externalWorkerId")
  .topic("AddressValidation", 60L * 1000L).variables("address")
  .execute();
LockedExternalTask task = tasks.get(0);
// ... processing the task fails
externalTaskService.handleFailure(
  task.getId(),
  "externalWorkerId",
  "Address could not be validated: Address database not reachable",     // errorMessage
  "Super long error details",                                           // errorDetails
  1,                                                                    // retries
  10L * 60L * 1000L);                                                   // retryTimeout

// ... other activities

externalTaskService.getExternalTaskErrorDetails(task.getId());

对于锁定的任务报告失败,以便可以在10分钟后再次重试。流程引擎本身不会减少重试次数。相反,可以通过在报告失败时将RETRIES设置为Task.getRetries()-1来实现此类行为。

在需要错误详细信息时,使用单独的方法从服务中查询它们。

2.2.9、错误事件

外部任务可以包括错误事件定义 这可以在错误事件的表达式计算为true时取消#HandleFailure的执行。如果错误事件的表达式计算引发异常,则此表达式将被视为计算结果为false。

2.2.10、报告BPMN错误

由于某些原因,在执行过程中可能会出现业务错误。在这种情况下,工作线程可以使用ExternalTaskService#handleBPMNerror向流程引擎报告BPMN错误。与#Complete或#HandleFailure一样,它只能由拥有任务最新锁的工作线程调用。#handleBPMnError方法有一个额外的参数:errorCode。错误代码标识预定义的错误。如果给定的ErrorCode不存在,或者没有定义边界事件,则当前活动实例简单地结束,并且不处理错误。

请参见以下示例:

List<LockedExternalTask> tasks = externalTaskService.fetchAndLock(10, "externalWorkerId")
  .topic("AddressValidation", 60L * 1000L).variables("address")
  .execute();
LockedExternalTask task = tasks.get(0);

将传播错误代码为BPMN-ERROR的BPMN错误。如果存在具有此错误代码的边界事件,则将捕获并处理BPMN错误。错误消息和变量是可选的。它们可以提供有关错误的其他信息。如果捕捉到BPMN错误,变量将被传递给执行。

2.2.11、查询任务

可以通过ExternalTaskService#createExternalTaskQuery查询外部任务。与#fetchandlock相反,这是一个不设置任何锁的读取查询。

2.2.12、管理操作

其他管理操作包括ExternalTaskService#Unlock、ExternalTaskService#SetRetries和ExternalTaskService#SetPriority,用于清除当前锁定、设置重试次数以及设置外部任务的优先级。当任务的剩余重试次数为0且必须手动恢复时,设置重试次数非常有用。使用最后一种方法,可以为较重要的外部任务设置较高的优先级,或者为不太重要的外部任务设置较低的优先级。

还有ExternalTaskService#setRetriesSync和ExternalTaskService#setRetriesAsync操作,用于同步或异步设置多个外部任务的重试。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1478247.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

从零开始手写RPC框架(1)

学习java后端也有一段时间了&#xff0c;在网上寻一些教程和github上的开源库&#xff0c;学习从零开始手写一个RPC&#xff0c;学习各位大牛的代码适当修改&#xff0c;并贴上自己的一些见解和注释。 目录 RPC简介RPC和HttpClient的区别和共同点常见RPC框架 RPC框架设计常见序…

白宫敦促开发者弃用C和C++,转而使用“内存安全”的编程语言。

美国白宫国家网络总监办公室&#xff08;ONCD&#xff09;在一份新报告中呼吁开发者停止使用C或C等编程语言&#xff0c;转而使用“内存安全编程语言”&#xff0c;这是美国总统拜登网络安全战略的一部分&#xff0c;旨在保护网络空间的基础构建块。内存安全是指防止因内存访问…

6.WEB渗透测试-前置基础知识-AI应用

内容参考于&#xff1a; 易锦网校会员专享课 上一个内容&#xff1a;5.WEB渗透测试-前置基础知识-常用的dos命令-CSDN博客 1.AI在生活中扮演的角色越来越重要&#xff0c;AI现在可以用来帮我们办许多事情 目前比较好用的AI模型例如Chatgpt&#xff0c;Claude&#xff0c;必应…

推荐一款ssh工具 xshell替代品 electerm

下载地址 electerm&#xff1a; https://electerm.github.io/electerm/ windows版本 产品优势 复制粘贴&#xff0c;可以直接使用ctrlc/v 非常的方便 而且不想xshell 需要账号登陆&#xff0c;有更新弹窗&#xff0c;自身集成了sftp 界面设计更新&#xff0c;比MobaXterm的…

TCP的三次握手和四次挥手 | 查看网络状态

三次握手和四次挥手是在计算机网络中用于建立和终止TCP连接的协议。这两个过程是TCP协议的重要组成部分&#xff0c;确保数据的可靠传输。 三次握手指的是在客户端和服务器之间建立连接时的步骤。具体流程如下&#xff1a; 客户端向服务器发送一个连接请求报文段&#xff08;…

0201sherlock(福尔摩斯)-通过名称寻找媒体账号(地址)-github-开源项目学习

文章目录 一 项目简介二 项目安装和演示1 安装2 演示 三 源码分析1 项目结构2 主程序源代码分析 四 添加自定义网址结语 一 项目简介 二 项目安装和演示 1 安装 # clone the repo $ git clone https://github.com/sherlock-project/sherlock.git# change the working direct…

推荐几款优秀免费开源的导航网站

&#x1f9a9;van-nav 项目地址&#xff1a;van-nav项目介绍&#xff1a;一个轻量导航站&#xff0c;汇总你的所有服务。项目亮点&#xff1a;全平台支持&#xff0c;单文件部署&#xff0c;有配套浏览器插件。效果预览 &#x1f9a9;发现导航 项目地址&#xff1a;nav项目…

【开源项目】自动字幕生成和字幕翻译

文章目录 1. 安装ffmpeg2. 克隆项目3. 配置项目运行环境4. 填写配置文件5. 运行项目&#xff08;仅使用CPU&#xff09; 项目地址&#xff1a;Github - qinL-cdy/auto_ai_subtitle 项目原理&#xff1a;使用ffmpeg提取视频的音频&#xff0c;使用whisper将音频转写为字幕&#…

消息中间件之RocketMQ源码分析(二十三)

Broker的关机恢复机制 概述 Broker关机恢复是指恢复CommitLog、Consume Queue、Index File等数据文件。Broker关机分为正常调用命令关机和异常被迫进程终止关机两种情况。恢复过程的设计目标是使正常停止的进程实现零数据丢失&#xff0c;异常停止的进程实现最少量的数据丢失…

Python:练习:输出int值a占b的百分之几。例如:输入1和4,输出:25%。

案例&#xff1a; 输出int值a占b的百分之几。例如&#xff1a;输入1和4&#xff0c;输出&#xff1a;25%。 思考&#xff1a; 所有的一步步思考&#xff0c;最后综合起来。 首先&#xff0c;确定 输出&#xff0c;那么就用input&#xff0c;而且是int值&#xff0c;所以肯定…

javaee教程郑阿奇,一线互联网架构师筑基必备技能之Java篇

一、什么情况下会发生栈内存溢出&#xff1f; 1、栈是线程私有的&#xff0c;栈的生命周期和线程一样&#xff0c;每个方法在执行的时候就会创建一个栈帧&#xff0c;它包含局部变量表、操作数栈、动态链接、方法出口等信息&#xff0c;局部变量表又包括基本数据类型和对象的引…

【Kubernetes】安装K3S

目录 前言一、原理单体架构高可用架构 二、初始化1.配置yum源2.关掉防火墙3.关掉selinux4. 修改内核参数5.关掉swap交换分区 三、安装master节点1. 安装container2.启动master服务 四、安装node节点五、卸载六、总结 前言 各位小伙伴们&#xff0c;大家好&#xff0c;小涛又来…

【MATLAB源码-第149期】基于MATLAB的2ASK,2FSK,2PSK,2DPSK等相干解调仿真,输出各节点波形。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 2ASK&#xff08;二进制幅移键控&#xff09;、2FSK&#xff08;二进制频移键控&#xff09;、2PSK&#xff08;二进制相移键控&#xff09;和2DPSK&#xff08;二进制差分相移键控&#xff09;是数字调制技术中的基本调制方…

1.2 debug的六种指令的使用,四个通用寄存器

汇编语言 首先进入环境 mount c d:masm //把c挂载在d盘中的masm当中 c: //进入c&#xff0c;进入到编译环境 dir //查看文件&#xff0c;可有可无Debug是DOS、Windows都提供的实模式&#xff08;8086 方式&#xff09;程序的调试工具。使用它可以查看CPU各种寄存器中的内容…

同芯.共赢 | 暴雨服务器亮相AMD EPYC合作伙伴峰会

2月29日&#xff0c;AMD EPYC合作伙伴峰会活动在北京成功举行&#xff0c;暴雨作为AMD重要生态合作伙伴应邀参加。作为AMD开年首场活动&#xff0c;此次活动意义非凡&#xff0c;AMD在现场向合作伙伴分享了AMD数据中心全新产品路线、解决方案以及生态建设领域的最新进展。 AMD是…

centos服务配置springboot服务开机启动

在做后端服务运维时&#xff0c;经常遇到服务器重启时&#xff0c;需要移动一堆后端服务。服务器故障自动重启时&#xff0c;通常无人通知。把springboot服务的jar包配置开机启动太有必要了&#xff0c;虽然不是很复杂&#xff0c;这里记录一下太有必要了。 创建jar包启动和停…

linux下gcc编译时默认是32位还是64位,怎么指定为32or64?

本来是想研究一下long的字节大小sizeof(long)&#xff0c;于是写了代码&#xff1a; #include <stdio.h> int main() {long a 10;printf("%d\n", sizeof(a));return 0; } 我当时使用的是win10系统&#xff0c;使用的是vs 2022&#xff0c;然后对以上代码进行…

嵌入式 Linux 下的 LVGL 移植

目录 准备创建工程修改配置修改 lv_drv_conf.h修改 lv_conf.h修改 main.c修改 Makefile 编译运行更多内容 LVGL&#xff08;Light and Versatile Graphics Library&#xff0c;轻量级通用图形库&#xff09;是一个轻量化的、开源的、在嵌入式系统中广泛使用的图形库&#xff0c…

【刷题】 Leetcode 1022.从根到叶的二进制数之和

刷题 1022.从根到叶的二进制数之和题目描述&#xff1a;思路一&#xff08;dfs深搜万能版&#xff09;思路二 &#xff08;栈迭代巧解版&#xff09;总结 Thanks♪(&#xff65;ω&#xff65;)&#xff89;谢谢阅读&#xff01;&#xff01;&#xff01;下一篇文章见&#xff…

Qt6.8 GRPC功能使用(2)标准 Qt实现客户端

简介 基于之前的文章所说&#xff0c; Qt6.7之后才开始支持客户端、服务端、及双向流&#xff0c;恰好电脑需要重装&#xff0c;看到Qt6.8版本就直接安装了&#xff0c;内容也是使用Qt6.8的版本进行编译的 客户端实现步骤 1. 安装Qt6.8, 包含GRPC功能模块 Qt 6.8安装目录下包…