我们已经开发了一个使用 ASP Net Core 的应用程序,用户必须获得批准才能获得批准。用户将在用户指定的时间收到等待批准的电子邮件。
例子
user1 设置在 12.55 pm 接收电子邮件的时间
user2 设置在下午 4 点接收电子邮件的时间
我们已将用户设置的时间保存在数据库中,目前我们正在
Azure Function
上运行 timer trigger
应用程序。触发器将每 15 分钟运行一次,并检查 SQL 数据库的用户通知时间。因此,如果用户将时间设置为下午 12 点 31 分,一旦触发器每 15 分钟运行一次,他将在下午 12 点 45 分后收到电子邮件。问题是用户必须等待 15 分钟,而且电子邮件不准时。
我们已经检查了
HangFire Recurring jobs
,但问题是它每分钟调用我们的 SQL 数据库,这会影响性能。
有没有更好的解决方案可以在用户指定的时间发送电子邮件通知,而无需每分钟调用 SQL 数据库来检查指定的用户时间是否可用于发送通知?
您可以使用延迟交付的队列。
本质上,当创建一个条目时,您会将一条消息推入队列并通过计算 DesiredTime - Now 来延迟其传递。然后你只需实现一个队列监听器。在所需的时间,一条消息将弹出到队列中并由您的工作人员处理。然后,您将一条新消息推送到队列中,延迟到下一个所需时间。
使用此解决方案,您可以挂起大量电子邮件,而数据库压力几乎为 0。它将水平扩展电子邮件的处理,并且立即具有非常好的可靠性。根据您使用的队列,成本也很低。
您可以为此使用 Azure 存储队列。
CloudQueueMessage message = new CloudQueueMessage(requestBody);
// The message will be visible in the queue after 3 days
queue.AddMessage(message, initialVisibilityDelay: TimeSpan.FromDays(3));
您可能需要做一些额外的事情来确保这是可靠的,例如启用死信队列并具有重新排队机制,以防处理消息时出错。
initialVisibilityDelay
Nullable<TimeSpan>
A TimeSpan 指定从现在开始消息不可见的时间间隔。如果为空,则消息将立即可见。
创建一个带有计时器触发器的 Azure Functions 来处理计划的消息:
var queueClient = new QueueClient(serviceBusConnectionString, queueName);
await queueClient.SendAsync(message);
\
步骤如下