Java 如何触发/接收延迟事件

Java 如何触发/接收延迟事件,java,azure,event-handling,azure-eventgrid,Java,Azure,Event Handling,Azure Eventgrid,如何在azure事件网格中延迟事件触发或事件接收 我设计的系统需要对低频对象状态做出反应(创建、启动、检查长时间处于启动状态、结束)。它看起来像是事件处理的候选者。我想用azure函数实现它。。。 问题是我需要对在启动状态下10分钟(可配置)的对象做出反应。在事件发生10分钟后作出反应。如何延迟事件火灾?如何安排火灾事件?如何等待事件? 我正在寻找不会消耗我的付费资源(功能处理时间)的解决方案。 你知道怎么解决这个问题吗?多谢各位 职能1: 时间触发(轮询) 检查条件 无法创建对象创建的事件

如何在azure事件网格中延迟事件触发或事件接收

我设计的系统需要对低频对象状态做出反应(创建、启动、检查长时间处于启动状态、结束)。它看起来像是事件处理的候选者。我想用azure函数实现它。。。 问题是我需要对在启动状态下10分钟(可配置)的对象做出反应。在事件发生10分钟后作出反应。如何延迟事件火灾?如何安排火灾事件?如何等待事件? 我正在寻找不会消耗我的付费资源(功能处理时间)的解决方案。 你知道怎么解决这个问题吗?多谢各位

职能1:

  • 时间触发(轮询)
  • 检查条件
    • 无法创建对象创建的事件
职能2:

  • http触发
  • 用户从UI启动对象
    • 创建对象启动事件,但从现在起10分钟后启动它?(在功能代码中使用睡眠/定时器将消耗10分钟的资源,最终导致成本过高)
功能3:

  • 检查状态并检测10分钟延迟
    • 火灾对象10分钟启动事件

在事件发生10分钟后作出反应

首先,我要强调,事件应该代表过去发生的事情,而不是未来发生的事情。对事件的期望是通知所发生的事情

其次,如果您对需要发生的事情有一个预期,那么命令比事件更好。在本例中,您希望工作在10分钟内发生在blob上,该blob将处于其实际可用于工作的状态。我将通过向队列(Azure Service Bus)发送一条延迟消息来响应该事件,其中包含处理blob所需的信息。这样,您通过准备未来/延迟的工作项来响应事件

如何在azure事件网格中延迟事件触发或事件接收

Azure事件网格(AEG)没有内置此功能,但是很容易使用Azure服务总线(ASB)实体对延迟(计划)消息进行扩展,就像Sean在回答中提到的那样

以下屏幕片段显示了延迟用户推拉的概念:

事件消息被推送到ASB主题中,并根据其订阅规则,将事件消息作为计划消息转发到队列实体

主题订阅需要设置以下属性:

  • 转发

    name of the queue/topic entity
    
  • $Default规则

    过滤器:

    1=1 
    
    行动(例如10分钟):

目标队列:

 EnableDeadLetteringOnMessageExpiration = true
根据上述设置,队列中的计划消息必须在TTL内使用,如“01:00:00”,否则消息将发送到DLQ。更多细节见肖恩的评论

使用ServiceBustigger函数,可以像AEG订阅服务器一样,以透明的方式从队列中提取延迟事件消息

在这种情况下,当延迟事件发送回AEG进行扇出分发并使用推送和推送模式时,以下示例显示了ServiceBusTrigger的此实现,其输出绑定到AEG自定义主题:

run.csx:

#r "Newtonsoft.Json"
#r "Microsoft.Azure.EventGrid"
#r "Microsoft.Azure.ServiceBus"


using System.Net;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Microsoft.Azure.EventGrid.Models;
using Microsoft.Azure.ServiceBus;


public static async Task Run(Message queueItem, IAsyncCollector<EventGridEvent> outputEvents, ILogger log)
{   
    string jsontext = JToken.Parse(Encoding.UTF8.GetString(queueItem.Body)).ToString(Formatting.Indented); 
    log.LogInformation(jsontext);

    EventGridEvent eventGridEvent = JsonConvert.DeserializeObject<EventGridEvent>(jsontext);
    eventGridEvent.Topic = null;
    eventGridEvent.Subject += "/delayed";
    await outputEvents.AddAsync(eventGridEvent);

    await Task.CompletedTask;
}

如您所见,subject属性已使用后缀/delayed进行了修改,用于过滤目的,如避免循环等。

可能应将
TimeToLive
的值重置为
10675199.02:48:05.4775807
,以确保消息在一小时后不会消失。这将把
expiresAuthc
设置为最大值。@SeanFeldman设置TimeToLive='01:00:00'的目的是在消息未被使用时在队列中使用死信消息功能。顺便说一句,在这个解决方案中,我发现了中描述的问题。我希望这是一个bug,它很快就会被修复。默认情况下,
启用DeadLetteringOnMessageExpatition
将被设置为false,并将导致消息在10小时后被丢弃。如果处理代码没有在该时间段内处理消息,则会出现危险路径。我建议将
TimeToLive
设置为最大值,或者修改答案,指出如果要进行死信,则必须将目标实体上的
enabledDeadLetteringOnMessageExpatition
设置为true。很好的错误发现顺便说一句!我已经就如何引起团队注意的问题发表了评论。@SeanFeldman感谢您的宝贵意见,在我的测试环境(使用服务总线资源管理器)中,当消息过期时,已为DLQ启用目标队列。我已经更新了我的答案。
#r "Newtonsoft.Json"
#r "Microsoft.Azure.EventGrid"
#r "Microsoft.Azure.ServiceBus"


using System.Net;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Microsoft.Azure.EventGrid.Models;
using Microsoft.Azure.ServiceBus;


public static async Task Run(Message queueItem, IAsyncCollector<EventGridEvent> outputEvents, ILogger log)
{   
    string jsontext = JToken.Parse(Encoding.UTF8.GetString(queueItem.Body)).ToString(Formatting.Indented); 
    log.LogInformation(jsontext);

    EventGridEvent eventGridEvent = JsonConvert.DeserializeObject<EventGridEvent>(jsontext);
    eventGridEvent.Topic = null;
    eventGridEvent.Subject += "/delayed";
    await outputEvents.AddAsync(eventGridEvent);

    await Task.CompletedTask;
}
{
  "bindings": [
    {
      "name": "queueItem",
      "type": "serviceBusTrigger",
      "direction": "in",
      "queueName": "aeg",
      "connection": "rk2016_SERVICEBUS"
    },
    {
      "type": "eventGrid",
      "direction": "out",
      "name": "outputEvents",
      "topicEndpointUri": "AEG_TOPIC_XX_ENDPOINT",
      "topicKeySetting": "AEG_TOPIC_XX_KEY"
    }
  ]
}