为什么Spray中每个请求的actor比每个请求的线程更好或更差(如在Tomcat中)。什么策略可以提供更好的性能?
答案 0 :(得分:1)
如果您使用HTTP,则您拥有无状态协议。因此,它非常适合演员。
我认为在写下每个方面之前。我将你重新定向到这个好的答案,这使我的陈述更加普遍。 How does Actors work compared to threads?
修改强>
演员基本上不共享状态,并且消息中的数据是不可变的。如果您正在使用线程,您可以轻松地在它们之间交换数据,还需要处理诸如生命周期和线程启动量之类的事情。共享状态(如果不是不可变的)可能导致死锁和其他并发情况,这是一个基本事实。我不会忘记你可以使用预先实现的ThreadPools来处理很多事情,包括ExecutionContext。许多人使用Threads错误包括我自己 - 我不是线程主题中的专家和所有并发问题。 https://docs.oracle.com/javase/tutorial/essential/concurrency/pools.html
一个演员应该小一点做一个"一个"东西/主题/用例非常好。它们以hirachircal的方式构建,这意味着你有一个ActorSystem,一个RootActor,它可以有许多不同类型的孩子,依此类推。它通过发送异步消息进行通信(您也可以使用阻塞样式)。如果您启动一个Actor,它将在一个Thread中运行。这意味着如果您发送10条需要处理1秒的消息,所有消息将在~10秒后处理。这不是很并发,因此你可以产生更多的Actors但现在如果你正确使用它们,它们将运行x共享线程。这可以防止线程被杀死并产生新的线程。它全部由引擎盖下处理,您可以通过TypesafeConfig进行配置。作为一个不切实际的例子,你可能会产生20个Actors,但它们运行的是4个线程 - 而不是20个。所有这些东西都是由akka-actors处理的,你只需要考虑你正在使用哪个Dispatcher,Router,Mailbox。这就是喷雾的作用。
返回HTTP:它是无状态的,这意味着,在建立TCP-Con之后,您发送HTTP-Request并获得HTTP响应。之后,此对话已过时且与HTTP无关。会话将通过HTTP-Headers进行识别,但协议本身不会对此做任何事情,会话内容是应用程序的工作。因此,对于处理请求 - repsonse spray将有一个带有几个Actors的Threads池,它们将处理请求并将其重定向到您的Routes。
您应该关注的一件事:Spray是一个REST / HTTP框架。 REST意味着如果您看到非常严格和直接的话,每条消息都应包含相应响应所需的所有信息。
我希望这会让事情变得清晰起来。如果你想深入了解喷涂所使用的ActorModel,你应该看看他们的网站(对不起,我没有链接)或浏览代码,这可以帮助很多。我知道它是我所说的非常基本但是在所有这些主题上有很好的博客条目,我认为这不是编写整本小说的正确背景。