- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我已经开始使用微服务,并且需要创建一个事件发布机制。
我计划使用Amazon SQS。
这个想法很简单。我将事件与聚合存储在数据库中。
如果用户要更改其电子邮件,则事件UserChangedEmail
将存储在数据库中。
我也有事件处理程序,例如UserChangedEmailHandler
,它将(在这种情况下)负责将此事件发布到SQS队列,以便其他服务可以知道用户已更改电子邮件。
我的问题是,实现这一目标的做法是什么?我是否应该有某种后台定时过程来扫描事件表并将事件发布到SQS?
这可以是WebApi应用程序内的进程(首选),还是应该是单独的进程?
一种想法是使用Hangfire,但在一分钟之内不支持cron作业。
有什么建议?
编辑:
如答案之一所示,我已经查看了NServicebus。 NServiceBus page上的示例之一显示了我关注的核心。
在他们的示例中,他们创建一个已下订单的日志。如果日志或数据库条目已成功提交但发布中断且事件从未发布,该怎么办?
这是事件处理程序的代码:
public class PlaceOrderHandler :
IHandleMessages<PlaceOrder>
{
static ILog log = LogManager.GetLogger<PlaceOrderHandler>();
IBus bus;
public PlaceOrderHandler(IBus bus)
{
this.bus = bus;
}
public void Handle(PlaceOrder message)
{
log.Info($"Order for Product:{message.Product} placed with id: {message.Id}");
log.Info($"Publishing: OrderPlaced for Order Id: {message.Id}");
var orderPlaced = new OrderPlaced
{
OrderId = message.Id
};
bus.Publish(orderPlaced); <!-- my concern
}
}
最佳答案
现成的建议
我建议您不要研究自己的现成产品,因为这里有很多复杂性,这些复杂性在一开始就不会明显。
管理事件订阅者列表-SQS队列与事件使用者(而不是事件生产者)更合适地配对,因为当消息被消耗时,它不再在队列中可用-因此,如果您想为给定事件支持多个订阅者(这是事件驱动的体系结构的巨大好处),如何知道首次引发事件消息时将消息推送到哪个SQS队列?
重试语义,错误转发队列-处理由临时基础结构问题导致的临时错误与由于业务逻辑语义问题导致的永久错误
审核跟踪哪些消息何时发出以及在何处发送
通过SQS发送的消息的安全性(您的业务案例是否要求对它们进行加密?SQS是Amazon提供的一种应用程序服务,不提供存储级加密
邮件大小-SQS有邮件大小限制,因此您最终可能需要处理大型邮件的带外传输
那就是我的头顶...
一些现成的系统将有助于:
NServiceBus提供了用于管理命令和事件消息传递的框架,并且具有允许灵活的传输类型的插件框架-NServiceBus.SQS提供了SQS作为传输。
提供全面,灵活的重试,审核和错误处理
公然使用命令vs事件(命令消息说“执行此操作”,并发送到单个服务进行处理,事件消息说“发生了什么事”,并发送到任意数量的灵活订户)
发件箱模式提供了事务一致的消息传递,即使使用非事务一致的传输,例如SQS
当前,SQS插件使用默认的NServiceBus订阅者持久性,这需要使用SQL Server来存储事件订阅者列表(有关利用SNS的选项,请参见下文)
内置对sagas的支持,提供了一个框架,以通过补偿动作来确保多事务最终与回滚的一致性
支持预定消息处理的超时
商业产品,因此不是免费的,但是许多插件/扩展是开源的
Mass Transit
不支持现成的SQS,但支持Azure Service Bus和RabbitMq,因此如果可以的话,可以替代您
与NServiceBus类似的产品,但并非100%相同-NServiceBus vs MassTransit提供了全面的比较
完全开源/免费
Just Saying
轻量级开源消息传递框架,专为基于SQS / SNS的设计
每个事件的SNS主题,每个微服务的SQS队列,使用本机SNS SQS Queue订阅来实现扇出
免费开源
可能还有其他人,并且我在NServiceBus方面拥有最丰富的个人经验,但是我强烈建议您研究现成的解决方案-它们将使您腾出时间来根据业务事件开始设计系统,而不用担心系统的工作原理事件传输。
即使您确实想构建自己的学习练习,但回顾一下上述工作的方式可能会为您提供一些可靠的事件驱动消息传递所需的技巧。
交易一致性和发件箱模式
已对问题进行了编辑,以询问如果部分操作成功但发布操作失败会发生什么情况。我已经将其称为消息传递的事务一致性,它通常意味着在事务中,所有业务副作用都已落实,或者没有。业务副作用可能意味着:
数据库记录已更新
另一个数据库记录已删除
消息已发布到消息队列
邮件已发送
如果数据库操作失败,通常您不希望发送电子邮件或发布消息,同样,如果消息发布失败,您也不想执行数据库操作。
那么如何确保消息传递的一致性呢?
NServiceBus通过以下两种方式之一处理此问题:
使用事务一致的消息传输,例如MSMQ。
MSMQ能够使用Microsoft's DTC (Distributed Transaction Coordinator),而DTC可以使用SQL Server更新在分布式事务中注册消息的发布-这意味着,如果您的业务事务失败,则发布操作将被回滚,反之亦然
Outbox Pattern
使用发件箱模式,不会立即发送消息-作为同一事务的一部分,消息将被添加到数据库(最好是与业务数据相同的数据库)中的发件箱表中
提交事务后,它将尝试分派每条消息,并仅在成功分派后将其从发件箱中删除
如果在发送后但删除之前系统发生故障,则将再次发送该消息。为了弥补这一点,启用发件箱后,NServiceBus还将通过保留所有入站消息的记录并丢弃重复项来对入站消息进行重复数据删除。
重复数据删除对于Amazon SQS尤其有用,因为它本身最终是一致的,并且相同的消息可能会收到两次。
这与您的问题中的原始概念相去不远,但是有一些区别:
您正在构思后台定时过程,以扫描事件表(又称为发件箱表)并将事件发布到SQS
NServiceBus在pipeline中执行处理程序-使用发件箱,将消息分发到传输(也就是将消息推入SQS队列)只是管道中的最后步骤之一。因此,每当处理一条消息时,在处理事务过程中生成的所有出站消息都将在提交业务事务后立即被调度,而无需对事件表进行定时扫描。
注意:仅当有环境NServiceBus Handler事务时,即在NServiceBus管道中处理消息时,发件箱才成功。在某些情况下(例如, WebAPI请求管道。因此,NServiceBus recommends using your API request to send a single Command message only,然后将业务数据操作与后端端点服务中事务一致的命令处理程序内的其他消息传递结合在一起。尽管文档中的第3点与MSMQ的关系比与SQS传输的关系更大。
处理程序语义
关于您的建议的另一条评论-按照惯例,UserChangedEmailHandler
通常会与响应电子邮件更改而执行某些操作的服务相关联,而不是简单地参与电子邮件更改信息的传播。当系统发布了50个事件时,是否要50个不同的处理程序仅将这些消息推送到不同的队列中?
上面的系统使用通用框架通过传输方式传播消息,因此您可以为订阅系统保留UserChangedEmailHandler
,并在其中包含用户更改电子邮件时应发生的业务逻辑。
关于c# - ASP.NET Web Api的事件发布者,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39305118/
我正在尝试将 WPF CodeBehid 事件(如 Event、Handler、EventSetter)转换为 MVVM 模式。我不允许使用 System.Windows.Controls,因为我使用
我可能误解了 Backbone 中的事件系统,但是当我尝试以下代码时什么也没有发生。当我向 Backbone.Events 扩展对象添加新属性时,它不应该触发某种更改、更新或重置事件吗?就像模型一样吗
我遇到了一个简单的问题,就是无法弄清楚为什么它不起作用。我有一个子组件“app-buttons”,其中我有一个输入字段,我想听,所以我可以根据输入值过滤列表。 如果我将输入放在我有列表的根组件中,一切
System.Timers.Timer 的 Elapsed 事件实际上与 System.Windows.Forms.Timer 的 Tick 事件相同吗? 在特定情况下使用其中一种比使用另一种有优势吗
嗨,这个 javascript 代码段是什么意思。(evt) 部分是如此令人困惑.. evt 不是 bool 值。这个怎么运作? function checkIt(evt) { evt
我正在使用jquery full calendar我试图在事件被删除时保存它。 $('calendar').fullCalendar ({
我有两个链接的鼠标事件: $('body > form').on("mousedown", function(e){ //Do stuff }).on("mouseup", function(
这是我的代码: $( '#Example' ).on( "keypress", function( keyEvent ) { if ( keyEvent.which != 44 ) {
我尝试了 dragOver 事件处理程序,但它没有正常工作。 我正在研究钢琴,我希望能够弹奏音符,即使那个键上没有发生鼠标按下。 是否有事件处理程序? 下面是我正在制作的钢琴的图片。 最佳答案 您应该
当悬停在相邻文本上时,我需要使隐藏按钮可见。这是通过 onMouseEnter 和 onMouseLeave 事件完成的。但是当点击另外的文本时,我需要使按钮完全可见并停止 onMouseLeave
我有ul标签内 div标签。我申请了mouseup事件 div标记和 click事件 ul标签。 问题 每当我点击 ul标签,然后都是 mouseup和 click事件被触发。 我想要的是当我点击 u
我是 Javascript 和 jQuery 的新手,所以我有一个非常愚蠢的疑问,请耐心等待 $(document).click(function () { alert("!"); v
我有一个邮政编码解析器,我正在使用 keyup 事件处理程序来跟踪输入长度何时达到 5,然后查询服务器以解析邮政编码。但是我想防止脚本被不必要地调用,所以我想知道是否有一种方法可以跟踪 keydown
使用事件 API,我有以下代码来发布带有事件照片的事件 $facebook = new Facebook(array( "appId" => "XXX", "se
首次加载 Microsoft Word 时,既不会触发 NewDocument 事件也不会触发 DocumentOpen 事件。当 Word 实例已打开并打开新文档或现有文档时,这些事件会正常触发。
我发现了很多相关问题(这里和其他地方),但还没有具体找到这个问题。 我正在尝试监听箭头键 (37-40) 的按键事件,但是当以特定顺序使用箭头键时,后续箭头不会生成“按键”事件。 例子: http:/
给定的 HTML: 和 JavaScript 的: var $test = $('#test'); $test.on('keydown', function(event) { if (eve
我是 Node.js 的新手,希望使用流运行程序。对于其他程序,我必须同时启动一个服务器(mongodb、redis 等),但我不知道我是否应该用这个运行一个服务器。请让我知道我哪里出了问题以及如何纠
我正在尝试使用 Swift 和 Cocoa 创建一个适用于 OS X 的应用程序。我希望应用程序能够响应关键事件,而不将焦点放在文本字段上/文本字段中。我在 Xcode 中创建了一个带有 Storyb
我有以下代码: (function(w,d,s,l,i){ w[l]=w[l]||[];w[l].push({
我是一名优秀的程序员,十分优秀!