简体   繁体   English

Akka stream 由 websocket 消息控制的动态源和流的最佳实践

[英]Akka stream best practice for dynamic Source and Flow controlled by websocket messages

I'm trying to understand what is the best way to implement with akka stream and alpakka the following scenario (simplified):我试图了解使用 akka stream 和 alpakka 实现以下场景(简化)的最佳方法是什么:

  1. The frontend opens a websocket connection with the backend前端打开与后端的websocket连接
  2. Backend should wait an initialization message with some parameters (for example bootstrapServers , topicName and a transformationMethod that is a string parameter)后端应该等待带有一些参数的初始化消息(例如bootstrapServerstopicName和作为字符串参数的transformationMethod
  3. Once these informations are in place, backend can start the alpakka consumer to consume from topic topicName from bootstrapServers and applying some transformation to the data based on transformationMethod , pushing these results inside the websocket一旦这些信息到位,后端可以启动 alpakka 消费者从bootstrapServers的主题topicName消费,并根据transformationMethod对数据进行一些转换,将这些结果推送到 websocket
  4. Periodically, frontend can send through the websocket messages that changes the transformationMethod field, so that the transformation algorithm of the messages consumed from Kafka can dynamically change, based on the value of transformationMethod provided into the websocket.前端可以周期性地通过websocket消息发送改变transformationMethod字段的消息,从而根据提供给websocket的transformationMethod值动态改变从Kafka消费的消息的转换算法。

I don't understand if it's possible to achieve this on akka stream inside a Graph, especially the dynamic part, both for the initialization of the alpakka consumer and also for the dynamic changing of the transformationMethod parameter.我不明白是否有可能在 akka stream 内实现这一点,尤其是动态部分,既用于初始化 alpakka 消费者,也用于动态更改transformationMethod参数。

Example:例子:

Frontend establish connection, and after 10 second it sends trough the socket the following:前端建立连接,并在 10 秒后通过套接字发送以下内容:

{"bootstrapServers": "localhost:9092", "topicName": "topic", "transformationMethod": "PLUS_ONE"}

Because of that, Alpakka consumer is instantiated and starts reading messages from Kafka.因此,Alpakka 消费者被实例化并开始从 Kafka 读取消息。

Messages are flowing in Kafka, so it arrives 1 and in the websocket the frontend will receive 2 (because of the PLUS_ONE transformation method, that is probably placed in a map or a via with a Flow), then 2 and so frontend receives 3 and so on.消息在 Kafka 中流动,因此到达1 ,在 websocket 中,前端将收到2 (由于PLUS_ONE转换方法,可能放置在map或带有 Flow 的via中),然后是2 ,因此前端收到3和很快。

Then, frontend sends:然后,前端发送:

{"transformationMethod": "SQUARE"}

So now, from Kafka arrives 3 and the frontend will receive 9 , then 4 and so the output will be 16 ecc...所以现在,从 Kafka 到达3 ,前端将收到9 ,然后是4 ,所以 output 将是16 ecc ...

This is more or less the flow of what I would like to obtain.这或多或少是我想要获得的流程。

I am able to create a websocket connection with Alpakka consumer that perform some sort of "static" transformations and push back the result to the websocket, it's straightforward, what I miss is this dynamic part but I'm not sure if i can implement that inside the same graph or if I need more layers (maybe with some Actor that manages the flow and will activate/change the behavior of the Alpakka consumer in real time sending messages?)我能够创建与 Alpakka 消费者的 websocket 连接,该消费者执行某种“静态”转换并将结果推回 websocket,这很简单,我想念的是这个动态部分,但我不确定我是否可以实现它在同一个图表内或者如果我需要更多层(也许有一些管理流程的 Actor 会激活/更改 Alpakka 消费者的行为,实时发送消息?)

Thanks谢谢

I would probably tend to implement this by spawning an actor for each websocket, prematerializing a Source which will receive messages from the actor (probably using ActorSource.actorRefWithBackpressure ), building a Sink (likely using ActorSink.actorRefWithBackpressure ) which adapts incoming websocket messages into control-plane messages (initialization (including the ActorRef associated with the prematerialized source) and transformation changes) and sends them to the actor, and then tying them together using the handleMessagesWithSinkSource on WebsocketUpgrade .我可能倾向于通过为每个 websocket 生成一个 actor 来实现这一点,预先实现一个Source它将接收来自 actor 的消息(可能使用ActorSource.actorRefWithBackpressure ),构建一个Sink (可能使用ActorSink.actorRefWithBackpressure ),它将传入的 ZBF56D570E62CDB573C86B1852Z6296 消息调整为控件-平面消息(初始化(包括与预物化源关联的ActorRef )和转换更改)并将它们发送给actor,然后使用WebsocketUpgrade上的handleMessagesWithSinkSource将它们绑定在一起。

The actor you're spawning would, on receipt of the initialization message, start a stream which is feeding messages to it from Kafka;您正在生成的演员将在收到初始化消息后启动 stream,它从 Kafka 向其提供消息; some backpressure can be fed back to Kafka by having the stream feed messages via an ask protocol which waits for an ack;通过让 stream 通过等待 ack 的 ask 协议提供消息,可以将一些背压反馈给 Kafka; in order to keep that stream alive, the actor would need to ack within a certain period of time regardless of what the downstream did, so there's a decision to be made around having the actor buffer messages or drop them.为了让 stream 保持活动状态,无论下游做什么,actor 都需要在一定时间内确认,因此需要决定让 actor 缓冲消息还是丢弃它们。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM