如何在开源名目Cadence中成功轮询

  • 电脑网络维修
  • 2024-11-14

本指南适用于一切宿愿了解Cadence中轮询上班原理的开发人员和工程师。Cadence是相对较新(且齐全开源)的容错形态代码平台,最后由Uber开发(如今失掉了包括Instaclustr在内的更多公司的支持)。

少量用例遍布单个恳求-回复、复杂的形态追踪和异步事情照应,并与外部的无法靠依赖项启动通讯。构建此类运行程序的罕用方法是将有形态服务、数据库、定时义务和队列系统像大杂烩一样整合在一同。

但是,这会对开发人员发生负面影响,由于大部分代码都是用于管道的——这覆盖了少量底层细节面前的实践业务逻辑。Cadence是一个齐全开源的编排框架,可以协助开发人员编写高容错且能够长时期运转的运行程序,这通常也被称为上班流。

从实质上讲,它提供了一个与特定进程有关联的虚拟内存,并保管了完整的运行程序形态,包括函数堆栈以及兼容各种主机和软件缺点的部分变量。这使得开发人员在编写代码时能够充沛应用编程言语的性能个性,Cadence则担任运行程序的耐久性、可用性和可裁减性。由于忙碌期待通常会消耗少量非必要的CPU周期,因此应尽或许防止经常使用轮询,而是经常使用由事情触发的终止来启动成功,除非以下两者状况:

关于计算机而言,这相当于在短途游览中每5分钟征询一次性距离目标地还有多远。虽然如此,在很多状况下,这是惟一可用的选用。Cadence为耐久计时器、长时期运转的优惠和有限度重试提供弱小的支持,使得其十分适宜此类性能的成功。

成功轮询机制有很多种方法。本文关键讲成功对外部服务的轮询,并剖析这样做会从Cadence中取得怎样的收益。首先,咱们来繁难的解释一下Cadence的概念。Cadence的外围思念是一个无端障形态的上班流。这象征着上班流代码的形态,包括部分变量和它创立的任何线程,不受进程和Cadence服务缺点的影响。这是一个十分弱小的理念,由于它封装了形态、线程处置、耐久计时器和事情处置程序。为了满足确定性的执行要求,上班流不准许间接调用任何外部API。雷同,它们担任对优惠的执前启动调度。优惠是用来成功业务级性能的运行程序逻辑,例如调用服务或对媒体文件启动转码。当优惠出现缺点时,Cadence并不会复原其运转形态。因此,优惠函数可以蕴含任何代码,且不会遭就任何限度。

代码自身十分繁难——咱们将逐行解释代码的作用:

State polledState = externalServiceActivities.getState();while(!expectedState.equals(polledState)) {Workflow.sleep(Duration.ofSeconds(30));polledState = externalServiceActivities.getState();}

左右滑动检查完整代码

咱们首先调用一个优惠,在这种状况下,外部服务或许是REST API。而后咱们就须要启动条件判别。假设未到达所需的形态,会有10秒的期待。

这不是通常意义上的期待,而是一个耐久的计时器。在这种状况下,轮询会执行周期性的期待,但时期或许会更长;而且,假设执行失败,咱们必定不会宿愿糜费整个时期周期。Cadence经过将计时器以事情的方式启动耐久化,并在成功后通知相应的上班服务(即治理上班流和优惠实施的服务)来处置此疑问。

这些计时器可以对从几秒到几分钟、几小时、几天甚至几个月或几年的时时期隔启动治理。最后,经过再次调用外部服务来刷新形态。在继续启动操作之前,咱们先极速了解一下Cadence终究在后盾做了哪些上班来防止潜在的疑问。

Cadence历史记载和轮询留意事项

Cadence是如何成功无端障形态上班流的呢?关键在于Cadence是如何保持用上班流程执行成功的。上班流形态复原应用事情溯源,而事情溯源对代码的编写方式施加了一些限度。事情溯源将一系列不时变动的事情转为耐久化的形态。

每当上班流形态出现变动时,都会有一个新的事情追加到该上班流的事情历史记载中。而后,Cadence经过历史记载来启动操作重放,以从新树立上班流的形态。这就是为什么与外部环境的一切通讯都应该经过优惠启动,并且必定经常使用Cadence API来失掉时期、期待和创立新线程。

1、审慎经常使用轮询​

轮询须要依据判别条件不时地循环。由于每个优惠调用和计时器事情都是耐久的,因此即使是短的轮询距离也或许调演化成无法接受的时期消耗。如今咱们来钻研轮询片段的历史记载会以怎样的方式出现。

Cadence中轮询代码片段的事情历史记载

假设上班流在两边某个中央失败,且必定重放其历史操作记载,这或许会造成少量的事情清单被执行。有一些方法可以防止这些操作脱离掌控:防止经常使用较短的轮询周期,在上班流中设置正当的超时时期,限度轮询的次数。

记住一切操作都是耐久的,或许须要由人重放操作。

2、性能优惠重试次数​

假设外部服务由于某些要素失败了怎样办?咱们须要尝试,尝试,再尝试!Cadence存在一种机制,可以让Cadence记载优惠结果并能够完美地恢停上班流形态,同时还提供了对相似重试逻辑等额外性能的支持。上方是启用重试选项的优惠性能示例:

private final ExternalServiceActivities externalServiceActivities =Workflow.newActivityStub(ExternalServiceActivities.class,new ActivityOptions.Builder().setRetryOptions(new RetryOptions.Builder().setInitialInterval(Duration.ofSeconds(10)).setMaximumAttempts(3).build()).setScheduleToCloseTimeout(Duration.ofMinutes(5)).build());

​左右滑动检查完整代码

经过这样的操作,咱们通知Cadence,在ExternalServiceActivities中的操作最多可以重试3次,且每次重试的距离为10秒。这样,每个对外部服务优惠的调用都可以轻松的成功重试性能,且无需编写任何重试逻辑。

为了展现这种形式的实践成果,咱们将在示例名目中集成一个虚拟的轮询。

1、Instafood简介​

Instafood是一个基于在线运行的送餐服务。客户可以经过Instafood的移动运行从他们外地最青睐的餐厅中订购食物。订单可以是自取或外卖。

假设选用外卖,Instafood将通知其外卖司机从餐厅取餐并将其送到客户手中。Instafood为每个餐厅提供一个展现屏或平板电脑,用于Instafood和餐厅之间的通讯。客户下单后,Instafood就会通知餐厅,而后餐厅可以接受订单、提供估量成功时期或将其标志为已成功等。关于外送订单,Instafood将依据估量成功时期协调外卖司机取餐。

2、轮询"MegaBurgers"​

MegaBurgers是一家大型跨国快餐汉堡连锁店。他们有自己的移动运行程序和网站,并经常使用REST API作为后端为客户提供订单服务。Instafood和MegaBurgers已达成协定,Instafood客户可以经过Instafood的运行程序在MegaBurger下单,并可选用自取和外卖。与通用打算不同的是,MegaBurger并未选用在一切店面装置Instafood展现屏,而是赞同将Instafood的订餐系统以集成的方式与自身基于REST的订餐系统启动对接,以成功下单和接纳降级。

MegaBurger的REST API没有推送机制(WebSockets、WebHooks等),无法接纳订单形态降级。

雷同,其须要活期发送GET恳求来确定订单形态,这些轮询或许会造成订单上班流在Instafood端重复执行(例如布置外卖司机取餐)。

你须要性能一个Cadence集群来运转示例名目。在此示例中,咱们将经常使用Instaclustr平台来执行操作。

第1步:创立Instaclustr托管集群​

Cadence集群须要衔接Apache Cassandra集群作为耐久层。为了成功性能Cadence和Cassandra集群,咱们将遵照“创立Cadence集群”文档的操作指点。

第2步:性能Cadence域​

Cadence的后端由多租户服务提供支持,其中隔离单元被称为域。为了让Instafood运行程序运转,咱们首先须要为它注册一个域。

1、为了与Cadence集群启动交互,咱们须要装置其命令行界面客户端。

假设经常使用macOS,可以经过Homebrew装置Cadence CLI,如下所示:

brew install cadence-workflow# run command line clientcadence <command> <arguments>

其余操作系统​

可以经过Docker Hub镜像仓库ubercadence/cli来运转和经常使用CLI:

# run command line clientdocker run --network=host --rm ubercadence/cli:master <command><arguments>

左右滑动检查完整代码

在的步骤中,咱们将经常使用cadence来指代客户端。

2、为了衔接的稳固性,倡导经过负载平衡器地址来衔接和访问集群。可以在“衔接消息”选项卡的顶部找到负载平衡器地址,如下所示:

“ab-cd12ef23-45gh-4baf-ad99-df4xy-azba45bc0c8da111.elb.us-east 1.amazonaws.com”

左右滑动检查完整代码

3、如今可以经过列出域来测试衔接:

cadence --ad <cadence_host>:7933 admin domain list
cadence --ad <cadence_host>:7933 --do instafood domain register --global_domain=false

左右滑动检查完整代码

cadence --ad <cadence_host>:7933 --do instafood domain describe

第3步:运转Instafood示例名目​

1、从Instafood名目标Git代码仓库中克隆Gradle名目。

2、关上位于instafood/src/main/resources/instafood.properties门路的性能文件,将cadenceHost的值交流为自己的负载平衡器地址:

cadenceHost=<cadence_host>

​3、经过以下方式运转该运行程序:

cadence-cookbooks-instafood/instafood$ ./gradlew run

​4、检查终端输入以确认其能否曾经反常运转:

在了解Instafood如何与MegaBurger集成之前,让咱们先极速了解一下他们的API。

1、运转MegaBurger服务​

让咱们从运转服务开局。经过以下命令来启动服务:

cadence-cookbooks-instafood/megaburger$ ./gradlew run

或许在IDE中运转MegaburgerRestApplication。这是一个以内存作为耐久层的Spring Boot Rest API演示示例。当运行程序封锁时,一切数据都会失落。

2、MegaBurger的订单API​

MegaBurger颁布其Orders API以便跟踪和降级每个食品订单的形态。

POST /orders

创立一个订单并前往其ID。

curl -X POST localhost:8080/orders -H “Content-Type: application/json” --data ‘{“meal”: “Vegan Burger”, “quantity”: 1}’

左右滑动检查完整代码

{“id”: 1,“meal”: “Vegan Burger”,“quantity”: 1,“status”: “PENDING”,“eta_minutes”: null}

GET /orders​

前往一个蕴含一切订单消息的列表。

curl -X GET localhost:8080/orders
[{“id”: 0,“meal”: “Vegan Burger”,“quantity”: 1,“status”: “PENDING”,“eta_minutes”: null},{“id”: 1,“meal”: “Onion Rings”,“quantity”: 2,“status”: “PENDING”,“eta_minutes”: null}]

GET /orders / {orderId}

curl -X GET localhost:8080/orders/1
{“id”: 1,“meal”: “Onion Rings”,“quantity”: 2,“status”: “PENDING”,“eta_minutes”: null}

PATCH /orders/{orderId}

curl -X PATCH localhost:8080/orders/1 -H “Content-Type: application/ json” --data ‘{“status”:“ACCEPTED”}’

左右滑动检查完整代码

{“id”: 1,“meal”: “Onion Rings”,“quantity”: 2,“status”: “ACCEPTED”,“eta_minutes”: null}

如今曾经成功了一切性能的初始化,让咱们看看Instafood和MegaBurger之间集成的实践成果如何。

1、轮询上班流​

首先定义新的上班流MegaBurgerOrderWorkflow:

public interface MegaBurgerOrderWorkflow {@WorkflowMethodvoid orderFood(FoodOrder order);// ...}

此上班流有一个orderFood方法,该方法将经过与MegaBurger集成来发送和跟踪相应的FoodOrder。

如今来看看它的成功方式:

public class MegaBurgerOrderWorkflowImpl implements MegaBurgerOrderWork flow {// ...@Overridepublic void orderFood(FoodOrder order) {OrderWorkflow parentOrderWorkflow = getParentOrderWorkflow();Integer orderId = megaBurgerOrderActivities.createOrder(mapMegaBurgerFoodOrder(order)); updateOrderStatus(parentOrderWorkflow, OrderStatus.PENDING);// Poll until Order is accepted/rejectedupdateOrderStatus(parentOrderWorkflow,pollOrderStatusTransition(orderId, OrderStatus.PENDING));if (OrderStatus.REJECTED.equals(currentStatus)) { throw new RuntimeException(“Order with id “ + orderId + “was rejected”);}// Send ETA to parent workflowparentOrderWorkflow.updateEta(getOrderEta(orderId));// Poll until Order is cooking updateOrderStatus(parentOrderWorkflow,pollOrderStatusTransition(orderId, OrderStatus.ACCEPTED)); //Poll until Order is readyupdateOrderStatus(parentOrderWorkflow,pollOrderStatusTransition(orderId, OrderStatus.COOKING)); //Poll until Order is deliveredupdateOrderStatus(parentOrderWorkflow,pollOrderStatusTransition(orderId, OrderStatus.READY)); }// ...}

左右滑动检查完整代码

该上班流首先失掉其父上班流。MegaBurgerOrderWorkflow只处置与MegaBurger的集成,将订单交付给由独立上班流治理的客户端处置;这象征着咱们经常使用的是子上班流。而后,经过优惠来创立订单,并取得订单ID。

优惠只是API客户端的装璜器,该API客户端担任发送POST恳求到/orders。创立订单后,父上班流会收到一个订单如今处于PENDING形态的信号(这是一个发送给上班流的,来自外部的异步恳求)。

如今咱们肯活期待订单从PENDING转变为ACCEPTED或REJECTED。这就是轮询施展作用的中央。如今看看咱们的函数pollOrderStatusTransition做了什么:

private OrderStatus pollOrderStatusTransition(Integer orderId,OrderStatus orderStatus) { OrderStatus polledStatus =megaBurgerOrderActivities.getOrderById(orderId).getStatus();while (orderStatus.equals(polledStatus)) {Workflow.sleep(Duration.ofSeconds(30)); polledStatus = megaBurgerOrderActivities. getOrderById(orderId).getStatus();}return polledStatus;}

左右滑动检查完整代码

这与本文引见的其余轮询循环十分相似。惟一的区别是它用一个轮询的特定形态替代期待,直到订单形态出现变动。雷同的,用于经过ID失掉订单的实在API调用暗藏在优惠的前面,该优惠启用了重试性能。假设订单被拒绝,则会引发运转形态异常,使上班散失败。假设订单被接受,则将MegaBurger的估量成功时期前往给父上班流(父上班流经常使用估量成功时期来成功交付调度)。最后,图3中所示的形态将会被转换,直到订单被标志为已交付。

2、运转反常的场景​

最后,让成功一个完整的订单场景。

这个场景是示例名目中测试套件的一部分。惟一的要求是同时运转Instafood和MegaBurger主机,而后依照前文中的步骤操作。

测试用例形容了客户端经过Instafood下单MegaBurger的新素食汉堡,并且来店面取餐:

cadence-cookbooks-instafood/instafood$ ./gradlew test
class InstafoodApplicationTest {// ...@Testpublic voidgivenAnOrderItShouldBeSentToMegaBurgerAndBeDeliveredAccordingly() {FoodOrder order = new FoodOrder(Restaurant.MEGABURGER,“Vegan Burger”, 2, “+54 11 2343-2324”, “Díaz velez 433, Lalucila”, true);// Client orders foodWorkflowExecution workflowExecution= WorkflowClientstart(orderWorkflow::orderFood, order);// Wait until order is pending Megaburger’s acceptance await().until(() -> OrderStatus.PENDING.equals(orderWorkflow.getStatus()));// Megaburger accepts order and sends ETAmegaBurgerOrdersApiClient.updateStatusAndEta(getLastOrderId(),“ACCEPTED”, 15);await().until(() -> OrderStatus.ACCEPTED.equals(orderWorkflow.getStatus()));// Megaburger starts cooking ordermegaBurgerOrdersApiClient.updateStatus(getLastOrderId(),“COOKING”);await().until(() -> OrderStatus.COOKING.equals(orderWorkflow.getStatus()));// Megaburger signals order is readymegaBurgerOrdersApiClient.updateStatus(getLastOrderId(),“READY”);await().until(() -> OrderStatus.READY.equals(orderWorkflow.getStatus()));// Megaburger signals order has been picked-upmegaBurgerOrdersApiClient.updateStatus(getLastOrderId(),“RESTAURANT_DELIVERED”);await().until(() -> OrderStatus.RESTAURANT_DELIVERED.equals(orderWorkflow.getStatus()));await().until(() -> workflowHistoryHasEvent(workflowClient,workflowExecution, EventType.WorkflowExecutionCompleted)):} }

左右滑动检查完整代码

在这个场景中,有3个介入者:Instafood、MegaBurger和客户端。

2. 一旦订单抵达MegaBurger(订单形态为PENDING),MegaBurgers将其标志为ACCEPTED并前往估量成功时期。

3. 而后咱们看下整个形态降级序列:

4. 由于该订单是以取餐的方式交付,因此一旦客户端成功交付,整个上班流程就完结了。

在本文中,咱们学习了如何经常使用Cadence成功轮询。咱们展现了如何让Cadence集群在Instaclustr平台上运转,以及让运行程序衔接到它是如许容易。

译者引见

仇凯,社区编辑,目前就任于北京宅急送快运股份有限公司,职位为消息安保工程师。关键担任公司消息安保规划和树立(等保,ISO27001),日常关键上班内容为安保打算制订和落地、外部安保审计微危险评价以及治理。

  • 关注微信

本网站的文章部分内容可能来源于网络和网友发布,仅供大家学习与参考,如有侵权,请联系站长进行删除处理,不代表本网站立场,转载联系作者并注明出处:https://duobeib.com/diannaowangluoweixiu/5051.html

猜你喜欢

热门标签

洗手盆如何疏浚梗塞 洗手盆为何梗塞 iPhone提价霸占4G市场等于原价8折 明码箱怎样设置明码锁 苏泊尔电饭锅保修多久 长城画龙G8253YN彩电输入指令画面变暗疑问检修 彩星彩电解除童锁方法大全 三星笔记本培修点上海 液晶显示器花屏培修视频 燃气热水器不热水要素 热水器不上班经常出现3种处置方法 无氟空调跟有氟空调有什么区别 norltz燃气热水器售后电话 大连站和大连北站哪个离周水子机场近 热水器显示屏亮显示温度不加热 铁猫牌保险箱高效开锁技巧 科技助力安保无忧 创维8R80 汽修 a1265和c3182是什么管 为什么电热水器不能即热 标致空调为什么不冷 神舟培修笔记本培修 dell1420内存更新 青岛自来水公司培修热线电话 包头美的洗衣机全国各市售后服务预定热线号码2024年修缮点降级 创维42k08rd更新 空调为什么运转异响 热水器为何会漏水 该如何处置 什么是可以自己处置的 重庆华帝售后电话 波轮洗衣机荡涤价格 鼎新热水器 留意了!不是水平疑问! 马桶产生了这5个现象 方便 极速 邢台空调移机电话上门服务 扬子空调缺点代码e4是什么疑问 宏基4736zG可以装置W11吗 奥克斯空调培修官方 为什么突然空调滴水很多 乐视s40air刷机包 未联络视的提高方向 官网培修 格力空调售后电话 皇明太阳能电话 看尚X55液晶电视进入工厂形式和软件更新方法 燃气热水器缺点代码

热门资讯

关注我们

微信公众号