嘿,伙计们,让我们了解一下akka流的基本知识。我希望你对Akka Actor有一个基本的了解。
什么是Akka流
Akka Streams是一个用于处理和传输元素序列的库。它建立在Akka Actors之上,使流的摄入和处理变得简单。由于它是建立在Akka Actors之上的,它为Akka现有的actor模型提供了一个更高层次的抽象。Akka流由3个主要部分组成--Source、Flow、Sink--任何非循环流至少由2个部分Source、Sink和任意数量的Flow元素组成。这里我们可以说Source和Sink是Flow的特殊情况。这里Flow位于Source和Sink之间,因为它们是应用于Source数据的转换。


Akka流的特点
- Akka-streams对于快速流数据非常有用。
- 它避免了管理角色所需的大量模板代码。
- 它最适合于基于大数据的应用。
- 由于它是建立在Akka工具包上的,我们将获得所有Akka工具包的好处,如反应性、分布式、位置透明性、集群、Remoting等。
- 它提供了可重用性,这意味着一旦我们设计了数据流图,我们就可以重复使用它的任何次数。
Akka-Streams中的术语
1.1.源。
这是你的流的入口。每个流中必须至少有一个源。它需要两个类型参数。第一个代表它所发射的数据类型,第二个是它在运行时可以产生的辅助值的类型。如果不产生,我们就使用Akka提供的NotUsed 类型。它只有一个输出点。源可以被认为是发布者。
val source : Source[Int, NotUsed] = (1 to 1000)
2.Sink :
这是你的流的出口点。每个流中必须至少有一个水槽。Sink 是我们流的最后一个元素。基本上,它是一个由源发送/处理的数据的订阅者。通常它将其输入输出到一些系统IO。它是一个流的终点,因此消耗数据。一个汇有一个单一的输入通道,没有输出通道。当我们想以可重复使用的方式指定数据收集器的行为时,特别需要汇,而且不需要评估流。水槽可以被认为是用户。
val sink: Sink[Int, Future[Done]] = Sink.foreach(println)
3.3.流:
流是流中的一个处理步骤。它结合了一个传入通道和一个传出通道,以及通过它的消息的一些转换。如果一个流被连接到一个源,一个新的源就是结果。同样地,一个流连接到一个汇,就会产生一个新的汇。而同时与一个源和一个汇相连的流的结果是RunnableFlow 。因此,它们位于输入和输出通道之间,但只要它们不与源或汇相连,它们本身就不对应于其中一种味道。这里,流位于源和汇之间,因为它们是应用于源数据的转换。
val flow: Flow[Int, Int, NotUsed] = Flow[Int].map(_ + 1)
4.4.RunnableGraph :
一个两端分别连接到Source和Sink的Flow可以被运行(),被称为RunnableGraph。即使通过连接所有的源、汇和不同的操作符来构建RunnableGraph,也不会有数据流经它。这就是Materialization的作用!
5.Materializer :
Akka流中的流和图就像准备一个蓝图/执行计划。流的物化是将流的描述和分配它所需的所有必要资源的过程,以便运行。这意味着启动处理的Actor,以及根据流的需要,在引擎盖下的更多内容。在运行(物化)RunnableGraph后,我们会得到指定类型的物化值。每个流操作者都可以产生一个物化的值。Akka有.toMat ,以表明我们要转换源和汇的物化值。
现在我们已经知道了什么是Akka流,它们是如何工作的等等。那么让我们看看Akka流的运行情况。
运行中的Akka流
import akka.{Done, NotUsed}
import akka.actor.ActorSystem
import akka.stream.ActorMaterializer
import akka.stream.scaladsl.{Flow, Sink, Source}
import scala.concurrent.Future
object Application extends App {
implicit val system: ActorSystem = ActorSystem("akka-streams-demo")
implicit val materializer: ActorMaterializer = ActorMaterializer()
val numberSource: Source[Int, NotUsed] = Source(1 to 100)
val sink: Sink[Int, Future[Done]] = Sink.foreach(println)
val flow: Flow[Int, Int, NotUsed] = Flow[Int].filter(number => isPrime(number))
numberSource.via(flow).to(sink).run()
private def isPrime(number: Int): Boolean = {
if (number <= 1) false
else if (number == 2) true
else !(2 until number).exists(i => number % i == 0)
}
}
输出。


- 我们已经在范围内创建了一个ActorSystem和一个ActorMaterializer实例来具体化图。
- 现在创建一个范围为1到100的源
- 只过滤质数的流
- 创建一个sink,使用
println,将其输入打印到控制台。 - 最后通过
flow将numberSource连接到sink并通过run()运行它。
总结
在这篇文章中,我们看到了akka-stream库。什么是akka-stream,akka-stream的特点,以及一个非常基本的例子来看看akka-reams的运行情况。我们定义了一个流程,结合流来过滤质数。然后,我们定义了一个作为流处理入口的Source和一个触发实际处理的Sink。