建议 运行 同一应用程序中的 Kafka 生产者 + 消费者?

Advisable to run a Kafka producer + consumer in same application?

Spring + Apache Kafka 菜鸟在这里。我想知道是否建议 运行 一个 Spring 引导应用程序来处理 生成消息和使用消息。

我最近看到的许多使用 Kafka 的应用程序通常有一个单独的应用程序 send/emit 向 Kafka 主题发送消息,另一个 consumes/processes 来自该主题的消息。对于较大的应用程序,我可以看到单独的生产者和消费者应用程序的情况,但是较小的应用程序呢?

例如:我是一个处理 HTTP 请求的简单应用程序 => 将请求发送到第三方服务,但为了确保可重试性,我将请求放在 Kafka 队列中,并使用 @Retryable 注释?

由于它在 Spring 框架上,还有哪些其他考虑因素可能会起作用?

注意:正如您的问题所述,我要说的更多是基于我的信念和经验的建议,而不是一成不变的绝对真理。

您的用例看起来更像是 proxy 而不是具有业务逻辑的实际应用程序。您应该 确保将其设为异步服务是有意义的 - 也许它足以保持连接直到您收到来自 3p 的响应,并让您的客户端处理重试(如果收到)一个错误 - 当然,您也可以重试直到超时。

这将避免常见的异步问题,例如让您的客户需要 poll 或具有 webhook 才能获得结果,或者使确保在中断或高消费者延迟后经过很长时间后处理记录仍然有意义。

如果您的客户不关心结果,只要完成就可以了,并且您不希望任何一方 high-throughput,那么一个 Spring Boot 应用程序就足以处理生产者和消费者双方 - 同时保持简单。

如果您确实期望高吞吐量,我会考虑构建一个 WebFlux based application with the reactor-kafka 库 - 高吞吐量代理是 reactive applications.

的绝佳用例

另一种选择是有一个简单的 serverless function 来处理 http 请求并生成记录,以及一个标准的 Spring Boot 应用程序来使用它们。

TBH,我没有看到有两个 full-fledged java 应用程序来处理代理职责的用例会得到回报,除非你有一个真正的声音轻松管理它们的基础架构,拥有两个应用程序而不是一个应用程序并没有什么不同,使用更多资源也不是问题。

实际上,如果您希望流量很高并且 serverless function 行不通,或者您可能想坚持使用 Java-based 解决方案,那么您可以使用简单的 WebFlux -based 应用程序来处理 http 请求和发送消息,以及标准 Spring Boot 或另一个 WebFlux 应用程序来处理消费。这样您就可以扩展前者以适应高流量,并根据您的性能要求独立扩展后者。

至于重试部分,如果你坚持使用 non-reactive Spring Kafka 应用程序,你可能需要查看 non-blocking retries feature from Spring Kafka. This will enable your consumer application to process other records while waiting to retry a failed one - the @Retryable approach is deprecated in favor of DefaultErrorHandler,两者都会在等待时阻止消费。

请注意,这样做会失去顺序保证,因此只有在处理请求的顺序不重要时才使用它。