异步消息传递和微服务

时间:2018-02-05 14:27:51

标签: java spring-boot apache-kafka microservices

我正在计划开发基于微服务的架构应用程序,当我读Ronnie Mitra的书 Microservice Architecture时,我决定使用kafka进行内部通信;马特麦克拉蒂;迈克阿蒙森; Irakli Nadareishvili 他们说:

  

让微服务直接与消息代理交互(例如   RabbitMQ等)很少是个好主意。如果有两个微服务   通过消息队列通道直接通信,他们共享一个   数据空间(频道),我们已经详细谈过了   共享数据空间的两个微服务的邪恶。相反,我们   可以做的是封装消息传递背后的独立   可以松散地提供消息传递功能的微服务   耦合方式,对所有感兴趣的微服务。

enter image description here

我使用Netflix Eureka进行服务注册和发现,Zuul作为边缘服务器和Hystrix。 这样说,在实践中,我该如何实现这种微服务呢?如何让我的微服务与通信渠道(在这种情况下是卡夫卡)无关? 实际上我直接与频道互动,所以我的发布者/订阅者和kafka之间没有额外的层。

更新06/02/2018

更准确地说,我们有几个微服务:一个是发布关于主题的新闻(activemq,kafka ......),另一个微服务订阅了该主题,并对正在通过的消息进行一些操作。所以我们将这些服务连接到消息代理(到通道)......我们的代码中有消息代理的api“embedeed”,例如,如果我们想要更改消息代理,我们必须更改所有利用消息代理的api的微服务。因此,他们建议使用微服务(在图中我假设是事件中心),它是各种消息的“调度程序”。通过这种方式,它是与频道互动的唯一组件。

3 个答案:

答案 0 :(得分:2)

一般性前言 - 如果您不需要,请不要这样做。如果您处理大量事件和事件备份问题等,引入队列系统可能是一个很大的改进。但如果您不面对任何问题,您可能会因为直接服务通信的低复杂性而更好

回到你的问题 - 听起来你想要抽象与队列的通信,因为你担心用不同的系统替换队列的努力 - 这是正确的吗?

在这种情况下,你可以做你提出的建议 - 在中间开发一项新服务。这带来了物理服务的所有包袱(包括部署,扩展等)。

或者第二种方法是编写一个客户端库,以您希望的方式抽象队列,并允许您在需要参与队列的所有服务中重用它。这样您就不必为此目的而物理部署其他服务,但您仍然可以完全控制您的队列接口应该是什么样的,并且您只需要一段代码来合并更改(至少对于队列的方向)。如果您确定库的面向应用程序的一侧足够稳定,这将有用。

但是,当你不确定是否需要所有的复杂性时,再也不要做第一次迭代中的任何一个。 (过度工程是危险的事情)

答案 1 :(得分:1)

你应该创建一个接口让我们说“队列”,它提供你想要的所有功能,从Kafka或RabbitMQ,创建差异。类似于Queue接口的KafkaQueue和RabbitMQQueue,并注入要在系统中使用的正确的impl。

在此使用if if new queue系统时,不会更改现有代码

在这种情况下,创建另一个微服务是额外的开销

答案 2 :(得分:0)

在服务架构中,通过正确建模的自给自足消息,使代码独立于通信信道的约束之外的正确方法。历史上的例子是文档模式下的WSDL,EDIFACT,HATEOAS等。从这个角度来看,带有spring-boot和kafka的微服务只是在大型机统治全世界时所做的相同的旧事情的不同实现。

基本上,如果您将应用程序视为blackbox异步服务器;应用程序所做的一切都是接收事件并生成新事件。在app中如何引发事件并不重要。 Http请求,jms消息中的xml,kafka中的json,无论如何 - 所有这些只是传递事件和业务层应用程序的方式应该只响应事件的内容。

因此,业务层通常围绕某些自定义模型/域构建,这些模型/域作为有效负载提供。业务层由监听器/生产者层调用/触发,该层与通信信道(kafka监听器,http监听器等)进行通信。除了记录和实施安全性之外,您不应该在应用程序中使用通信通道逻辑。我已经看到了由原始jms连接或解析请求URL驱动的业务逻辑的不幸示例。如果您的代码中有此代码,则无法正确构建代码。

然而,这比实施更容易。有些人擅长这种建模,有些人从不学习。

没有其他方法可以学习,但尝试失败。