免责声明:我真的刚刚开始使用SOA,所以你不得不原谅我的无知。
我有一个非常简单的服务,可以处理来自第三方API(salesforce)的应用程序。用户界面接受ID - >发送ProcessCmd并启动saga - > saga从API导入数据 - > saga订阅了ImportedEvt&试图验证 - > saga无限期地运行检查新信息或手动覆盖 - >如果saga结束发布带有状态的ProcessedEvt。
现在我的UI是基于Angular / SignalR的两个页面。
使用提交的ID和空字段填充Index.html(通过JS)并侦听这两个事件。 ImportedEvt填充一些字段,ProcessedEvt填充状态字段(接受/拒绝等)。它还会激活指向详细信息的链接。
Details.html只查询数据库。
最初我把数据保存在ProcessingSaga中,但是我在David Boike的book中读到这是不好的做法,因为一个传奇是船的船长,只发出命令但没有实际的转向。所以我在我的服务上添加了另一个ProcessedEvtHandler以保存到DB,但我不知道这是否正确。
有些事让我困惑:
在我看来,尽管我的UI拥有自己的端点,并且能够像任何其他服务一样发送/接收消息。它并不真正适合同一类别。拥有最终的一致性对于幕后的业务规则来说是很好的,但却会产生糟糕的用户体验,我不明白我如何不能拥有UI服务共享数据库?
我错过了什么吗?
答案 0 :(得分:4)
如果两个物理服务/进程共享一个数据库,那么您基本上没有两个逻辑服务,只有一个。这是SOA的基本原则。
听起来您的用户界面和后端服务在物理上是分开的。即便如此,您可能想问自己,他们是代表两种逻辑服务还是一种服务。如果它们代表相同的逻辑服务,那么通过让它们访问同一个数据库就不会违反任何内容。
如果它们代表两个逻辑服务(我怀疑他们这样做),请考虑不直接从UI查询数据库;而是通过某种形式的请求/响应(WebAPI,WCF等)查询后端服务,并让 it 查询数据库。应该通过从UI向后端服务发送命令来保存到数据库。命令通常应该是业务动词(例如“ChangeCustomerAddress”与“UpdateCustomer”)。
为什么我纯粹为了UI而有一个新事件SavedToDbEvt?
我不完全确定我理解这部分问题。基本上,当某些事情已经发生时,您应该发布事件。如果您正在处理保存到数据库的进程,则在数据库提交成功后将发布通常事件。 不意味着您应该发布“SavedToDbEvt”之类的事件,但这可能意味着在数据被保留之前不应发布您的ProcessedEvt。
修改强>
这是一个很好的问题,您在评论中的后续问题也是合理的。不幸的是,我们开始跨越界限,使这个问题成为论坛的一个更好的问题,可以进行反复讨论。我会在这里添加一些一般想法,但是由于每种情况都是独特的,因此可能无法得出明确的答案,并且(可能)有多种解决方案可行。
也许我正在创造比我真正需要的更多层/服务。
很难说不知道更多。用户界面会使用其他后端服务,还是只涉及问题所涉及的服务?此外,后端逻辑是由其他服务消耗还是仅由此UI使用?如果它们在逻辑上是一个单元,那么你绝对应该考虑通过不进行物理分配来简化你的设计。
另一层抽象(即WCF)有助于缩小差距[...]
即使您使用的是事件驱动/总线式架构,也几乎总是需要对其他服务进行请求/响应式查询。就像一个简单的例子:如果您的UI服务是全新的,但您的后端服务已部署多年,该怎么办? UI如何获得现有状态,因为它可能错过了后端服务已经发布的多年事件?
虽然您可以通过ESB模拟请求/响应,但这确实不是它的目的 - 在大多数情况下我建议不要使用它。
最后,听起来您确实需要在数据库保存完成后发布其他事件。在我看来,当应用程序成为系统的永久部分时,它代表了一个有趣的状态变化。如果是这种情况,那么状态变化会让业务变得有趣吗?如果你能搞清楚,你的活动应该开始变得更有意义,并且可能自然会转化为比“SavedToDb”更好的名字!