我有一个Flink应用程序,它使用多个分区的Kafka主题上的传入消息,进行一些处理,然后将它们发送到接收器,接收器通过HTTP将它们发送给外部服务。有时下游服务处于下行状态,需要停止处理,直到它恢复运行。
我正在考虑两种方法。
- 当Http接收器无法发送输出消息时抛出异常。这将导致任务和作业根据配置的重新启动策略重新启动。最终,下游服务将恢复,系统将继续运行
- 让接收器休眠并在失败时重试;它可以不断地这样做,直到下游服务返回
根据我的理解和我的PoC,用1。我将失去至少一次保证,因为水槽本身就是外部状态。据我所见,你不能让一个简单的HTTP端点成为事务性的,因为它需要实现TwoPhaseCommitSinkFunction。
与2。这不是一个问题,因为在接收器成功写入之前,管道不会继续,并且我可以依靠整个系统的背压来暂停从Kafka源检索消息。
我的主要问题是:
- 您不能为简单的HTTP端点创建TwoPhaseCommitSinkFunction,这是正确的假设吗
- 这两种策略中哪一种最有意义,或者两者都没有
- 我是否错过了更简单、显而易见的解决方案
我认为您可以在Flink中尝试AsyncIO-https://nightlies.apache.org/flink/flink-docs-master/docs/dev/datastream/operators/asyncio/.
一旦对请求完成了所有操作,就尝试让HTTP端点发送响应。例如,在HTTP服务器中,请求的过程已经完成,结果已经提交到DB。然后在AsyncIO操作符中使用http异步客户端。AsyncIO操作员将等待,直到操作员收到响应。如果发生任何错误,Flink流媒体管道将失败,并根据恢复策略重新启动管道。
所有到HTTP端点但未收到响应的请求都将在AsyncIO操作员的内部缓冲区中,一旦流管道失败,缓冲区中挂起的请求将以检查点状态保存。当内部缓冲器充满时,它也会触发背压。