简体   繁体   English

了解Elixir

[英]Understanding Elixir

Can Java frameworks like SpringBoot and Play handle multiple requests at the same time by leveraging all the cores on the machine ? SpringBoot和Play等Java框架可以通过利用机器上的所有内核同时处理多个请求吗? If they can do that, then what unique problem is Elixir solving with respect to concurrency? 如果他们能够做到这一点,那么Elixir在并发方面解决了什么独特的问题? Is it just a different language? 它只是一种不同的语言吗? Or there is any difference in the computing paradigm itself that brings us lower server costs with Elixir? 或者计算范例本身有什么不同,可以让我们用Elixir降低服务器成本?

Here is the report: https://www.techworld.com/apps-wearables/how-elixir-helped-bleacher-report-handle-8x-more-traffic-3653957/ 以下是报告: https//www.techworld.com/apps-wearables/how-elixir-helped-bleacher-report-handle-8x-more-traffic-3653957/

There are three main differences. 主要有三个不同之处。

Lightweight processes 轻量级流程

Elixir's processes should not be confused with operating system processes. Elixir的流程不应与操作系统流程混淆。 Processes in Elixir are extremely lightweight in terms of memory and CPU (even compared to threads as used in many other programming languages). Elixir中的进程在内存和CPU方面非常轻量级(甚至与许多其他编程语言中使用的线程相比)。 Because of this, it is not uncommon to have tens or even hundreds of thousands of processes running simultaneously. 因此,同时运行数十甚至数十万个进程并不罕见。 https://elixir-lang.org/getting-started/processes.html - https://elixir-lang.org/getting-started/processes.html

Fault-tolerance 容错

Erlang and hence Elixir uses the concept of the supervision tree , assuring the crash of a single process would not bring any harm to the whole application; ErlangElixir使用监督树的概念,确保单个过程的崩溃不会对整个应用程序造成任何伤害; even more, Erlang philosophy explicitly states “Let it crash” as its motto. 更进一步,Erlang哲学明确指出“让它崩溃”作为其座右铭。 That basically means you should not care about error handling to some extent. 这基本上意味着你不应该在某种程度上关心错误处理。

The supervisors have a built-in mechanism to limit the number of restarts which can occur in a given time interval. 主管有一个内置机制来限制在给定时间间隔内可能发生的重启次数。 This is determined by the values of the two parameters MaxR and MaxT. 这由两个参数MaxR和MaxT的值确定。 If more than MaxR number of restarts occur in the last MaxT seconds, then the supervisor shuts down all the children it supervises and dies. 如果在最后的MaxT秒内发生超过MaxR重启次数,则主管关闭其监督并死亡的所有子项。 http://erlang.org/documentation/doc-4.9.1/doc/design_principles/sup_princ.html - http://erlang.org/documentation/doc-4.9.1/doc/design_principles/sup_princ.html

Message passing 消息传递

Instead of data sharing, Erlang processes are completely isolated and the only mechanism to interchange between is to pass messages; Erlang进程完全是隔离的 ,而不是数据共享,唯一的机制是传递消息; that makes the memory management extremely effective and performant. 这使内存管理非常有效和高效。

Each process has its own input queue for messages it receives. 每个进程都有自己的输入队列,用于接收的消息。 New messages received are put at the end of the queue. 收到的新消息放在队列的末尾。 When a process executes a receive, the first message in the queue is matched against the first pattern in the receive. 当进程执行接收时,队列中的第一条消息将与接收中的第一个模式进行匹配。 If this matches, the message is removed from the queue and the actions corresponding to the pattern are executed. 如果匹配,则从队列中删除该消息,并执行与该模式相对应的动作。 http://erlang.org/doc/getting_started/conc_prog.html#message-passing - http://erlang.org/doc/getting_started/conc_prog.html#message-passing

One of the difficulties of handling multiple requests on multiple cores is the fact that you now have multiple parts of your program running at the same time and modifying state. 在多个内核上处理多个请求的难点之一是,您现在可以同时运行程序的多个部分并修改状态。 So in come the mutexes and you now have to worry about whether or not a function is thread safe, and manage blocking/waiting/resuming on locks and mutexes. 因此,互联网和你现在必须担心一个函数是否是线程安全的,并管理锁和互斥锁上的阻塞/等待/恢复。 Which means you now have a bunch of potential bottle necks, and can that drive up costs and reduce (or even eliminate) what gains you were expecting from concurrency. 这意味着您现在拥有一堆潜在的瓶颈,这可以提高成本并减少(甚至消除)您从并发中获得的收益。

Erlang and Elixir have concurrency based on the 'Actor Model' . Erlang和Elixir基于'Actor Model'具有并发性。 An actor receives messages and from those messages can create new messages, determine how to handle the next message, modify their own internal state, or create more actors. actor接收消息,并从这些消息中创建新消息,确定如何处理下一条消息,修改自己的内部状态或创建更多actor。 What that boils down to is each Actor has its own state so you no longer need to worry about locks or mutexes. 归结为每个Actor都有自己的状态,因此您不再需要担心锁或互斥锁。 This helps to ease the mental burden of writing concurrent code, and as an abstraction makes it easier to reason about concurrency. 这有助于减轻编写并发代码的心理负担,并且作为抽象使得更容易推理并发。 The result is more effective concurrent code that is easier to maintain. 结果是更有效的并发代码更容易维护。 The actor model can be implemented in any language, but it's baked into Elixir and Erlang. 演员模型可以用任何语言实现,但它被融入Elixir和Erlang。

Further, Elixir and Erlang are functional languages. 此外,Elixir和Erlang是函数式语言。 In functional languages side-effects, lingering state from prior method calls, is generally avoidable. 在函数式语言中,副作用,来自先前方法调用的延迟状态通常是可以避免的。 What that means is that as long as you don't violate functional purity you have the ability to say that a method will return the same thing every time. 这意味着只要你不违反功能纯度,你就有能力说每次方法都会返回相同的东西。 Which means f(x) + f(x) == f(x)*2. 这意味着f(x)+ f(x)== f(x)* 2。 Which means that you can parallelize things to an greater degree without fear. 这意味着您可以更大程度地并行化事物而不用担心。 Running f(x) on one thread and g(x) on another CAN'T result in a race condition if they're functionally pure. 在一个线程上运行f(x)而在另一个线程上运行g(x)如果它们在功能上是纯的,则不会导致竞争条件。 Because neither one of them impacts state. 因为它们中没有一个会影响状态。

I'll try to give a short answer: Erlang/Elixir forces you to write asynchronous, non-blocking code, using actors. 我将尝试简短回答:Erlang / Elixir 强制您使用actor编写异步,非阻塞代码。

You can see actors as "micro"-microservices. 你可以将演员视为“微观” - 微服务。 Actors have their own state, they don't share data (in fact all variables are immutable) and therefore need to pass asynchronous messages between each other. Actor有自己的状态,它们不共享数据(事实上所有变量都是不可变的),因此需要在彼此之间传递异步消息。

Erlang/Elixir has its own virtual machine that can handle hundred thousands of threads and other optimizations (threads are not operating system threads, but virtual/lightweight ones and the virtual machine avoids copying of data in memory even though all variables are immutable, by only copying data when it is really necessary) Erlang / Elixir有自己的虚拟机,可以处理数十万个线程和其他优化(线程不是操作系统线程,但是虚拟/轻量级线程,虚拟机避免在内存中复制数据,即使所有变量都是不可变的,只有在真的有必要时复制数据)

I am not up to date with other Actor Systems, so I cannot tell if eg Akka on the JVM would get a similar performance. 我没有与其他Actor系统约会,所以我无法判断例如JVM上的Akka是否会获得类似的性能。 Virtual Actor Systems might also be able to handle a lot of work, Orleans is such a framework. Virtual Actor Systems也可能能够处理很多工作,Orleans就是这样一个框架。 (a virtual actor system can be compared to having a dependency injection for Actors, when you need them they are created and when they are not in used they are removed from the memory) https://github.com/dotnet/orleans (可以将虚拟actor系统与Actors的依赖注入进行比较,当你需要它们时,它们被创建,当它们没有被使用时,它们被从内存中删除) https://github.com/dotnet/orleans

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

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