我有一个演员,当他收到一个消息,他开始在一个循环中做来计算,他这样做了一段时间(像100倍,他这样做)。现在我需要他对其他消息作出React,可能会尽快。最好的办法是在他的循环中添加一些指令,如“如果有一个消息在队列React,然后返回这里”,但我还没有看到这样的功能。
我认为演员可以发送消息给自己,而不是做一个循环,然后这样的消息将排队在最后,他会对其他人之间的React,但我听说沟通是坏的(比计算更耗时),不知道是否与自我沟通算作这样。
我的问题是,你对这种解决方案有什么看法?你对如何处理计算之间的通信有什么其他想法吗?
3条答案
按热度按时间avwztpqn1#
不应在主接收方法中执行耗时的计算,因为这会降低系统的响应速度。请将计算放在阻塞
Future
或Task
或其他异步对象中,并在计算完成时向参与者发送消息。参与者可以在计算在其他线程上继续时尽快继续处理消息。如果参与者需要在计算运行时(响应消息)修改计算,这会变得更加复杂,但解决方案取决于计算是什么以及需要什么样的修改,因此实际上不可能给予一个通用的答案。
vaj7vani2#
一般来说,在Akka中,您希望限制“每单位”完成的工作量,在本例中为单位:
Future
/Task
中完成的工作或相同的回调过长的工作单元会消耗一个线程,从而很容易限制整个系统的响应能力。对于不消耗CPU但被阻塞等待I/O的任务,这些任务可以在不同的线程池中执行,但对于执行一些消耗CPU的工作,这实际上没有帮助。
因此,如果你正在执行一个循环,最广泛的方法是将循环的状态挂起到一个消息中,并将其发送给你自己。这会带来一个小的性能损失(构造消息、将其发送给你自己(保证是本地发送)和解构它的延迟可能是微秒量级的,而系统在其他情况下是空闲的),但可以改善整体系统延迟。
例如,假设我们有一个参与者,他将计算第
n
个斐波纳契数。我使用Akka Typed实现了这个过程,但在Classic中也应用了广泛的原则:注意,对于相同数目的多个请求(如果时间上足够接近)将仅被计算一次,并且对于中间结果的时间上接近的请求将不会导致额外的计算。
wnrlj8wa3#
一个选项是委派任务,例如:
Future
,并使用一个单独的ExecutionContext,其中的fixed-pool-size
(可在application.conf
中配置)等于CPU(或内核)的数量,以便使用可用的内核高效地完成计算。另一个选择是让路由器后面的另一个参与者执行计算,同时将被路由者的数量限制为CPU的数量。
一个简单的例子: