使用消息传递的微服务和 SOA
Posted
技术标签:
【中文标题】使用消息传递的微服务和 SOA【英文标题】:Microservices and SOA using messaging 【发布时间】:2014-04-26 04:07:42 【问题描述】:我一直对尝试将微服务/SOA 作为一种架构非常感兴趣,并且很难概念化如何实际完成服务之间的集成。
我喜欢使用消息传递将客户端与服务分离的想法,但不了解系统如何专门使用它。典型的异步操作和发布/订阅的东西显然是有意义的——比如创建新订单、广播数据以进行报告等场景。我不明白人们是否通常会尝试将消息传递用于常见的请求/回复场景——例如,用户点击他们的“个人资料”页面,需要在页面上呈现的部分数据来自用户服务。
我知道常见的消息传递实现提供类似 REST 的回复/请求功能,但它经常用于简单的数据请求吗?微服务似乎更有可能既公开 REST 端点,又向消息代理注册它将参与的不同类型的通信,但我观看的所有这些 SOA 和微服务架构的演示似乎表明它们只使用其中一种。 .
感谢您的详细说明/经验!
【问题讨论】:
【参考方案1】:我已经发布了这个before - 但一般来说,同步操作(例如,用户单击按钮并期望返回一些数据)是同步的,这是有原因的。
也就是说,同步 - 不是因为用于处理他们的调用的技术 - 而是因为用户的内置且通常不灵活的期望,即事情应该实时发生而不是“离线” (即使大部分时间没有实质性差异)。
因此,在用户和他们的预期响应之间放置任何类型的离线或异步技术堆栈通常是不明智的。
与所有事情一样,例外情况比比皆是(并且可能引发全新的对话),但某些类型的用户调用可以而且应该根据具体情况“离线”处理。
但是,我确实觉得您的主张的重点是:
我喜欢使用消息传递将客户端与 服务
有点没抓住重点。我们实际上并不想将客户端(或消费者)和服务分离。
我们希望客户的应付账款业务能力与应付账款微服务高度耦合。
同样,我们希望服务端点签名bool ProcessTransaction(Transaction transaction)
与此类操作的使用者之间存在高度耦合。
解耦变得真正重要的是支持不同业务功能的服务之间的解耦。
正是在这里,消息传递的好处真正发挥了作用。让我知道您的想法,以及这是否对您有所帮助。
【讨论】:
非常好,谢谢!这就是我所怀疑的,因为从应用程序用户的角度来看,异步调用不适合任何自然的工作流程......似乎它会很快变得混乱。您关于不将消费者与服务脱钩的观点让我们明白了这一点 - 对于业务功能不需要响应即可完成其目的的服务器到服务器场景,异步似乎确实是一个很好的解决方案。 同意,尽管业务功能通常需要某种响应才能完成 - 这也可以通过异步通道启用。在这种情况下,异步和“单向”之间有一个至关重要的区别。当响应(以及随之而来的最终一致性)不是时间关键时,可以使用消息传递。【参考方案2】:我不明白人们是否通常会尝试将消息传递用于常见的请求/回复场景 - 例如,用户点击他们的“个人资料”页面,并且需要在页面上呈现的部分数据来自用户服务。
关键是完全避免请求/回复。从技术上讲,如果您的整个堆栈允许异步消息传递,包括通过在单页应用程序 (SPA) 中使用 WebSocket 之类的东西来实现 Web 前端,这是可能的。对于一个实际示例,您可以查看 Typesafe 的 Reactive Maps 模板 (https://www.typesafe.com/activator/template/reactive-maps-java)。
【讨论】:
【参考方案3】:我认为,当您问在请求/响应中多久使用一次“消息传递”时,您可能指的是异步通信。
我将采取与此处的某些答案不同(相反)的观点,并说您几乎应该始终使用异步,即使在请求/响应中也是如此。这是因为异步意味着您不会阻塞您的程序等待响应,并且您的程序可以在等待响应时继续执行一些其他处理。
例如,假设您正在实现 Twitter 的主页。你向不同的微服务发出一堆请求(“给我推荐的关注者”、“给我最新的时间线”等)。你不想阻止和序列化所有这些请求。你想把它们解雇异步,这创造了更好的用户体验,因为当响应返回时,它们会实时更新 UI。
Twitter 正是为此使用了 Finagle (http://twitter.github.io/finagle/guide/index.html)(异步 RPC)。它没有做一些消息系统会做的事情(特别是,它确实与 JVM 相关联,并且它没有实现流控制或队列),但它确实实现了异步请求/响应。
【讨论】:
【参考方案4】:我刚开始学习微服务,所以这绝不是一个完美的答案。这是我目前的理解的看法。
如果您基于事件创建微服务,那么消息代理将发挥重要作用。假设您有一个名为 CreateUserService 的服务,它只负责收集创建用户所需的数据,而不是持久化数据。然后将此数据发布到队列中。
createUser 队列 DuplicateUserService、UserDataStore 等的订阅者...然后可以对每个服务中的数据做出相应的反应。
最后,客户端从另一个服务接收数据,其中包含有关尝试事件的相关信息。
【讨论】:
【参考方案5】:我没有使用过 REST,但我使用 WSDL 来允许层之间的通信。服务之间的集成非常简单,它们像后端的嵌套函数一样相互交谈,或者如果请求从服务器跳到服务器,则只需使用 XML 和 JSON。
这里的服务器是内部网络服务的主机。并且可以根据需求提供排队服务给个别服务。但最后,只有一个响应从后端发送给调用者。
【讨论】:
感谢您的回复,我特别想知道在回复/请求场景中使用消息传递(基于 jms/amqp/等)。以上是关于使用消息传递的微服务和 SOA的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Jackson 和 MongoDB 传递 JSON 消息中的属性?