本章是Mix和OTP教程的一部分,它依赖这个教程的前面章节。要获得更多信息,请阅读本教程的第一章,或者查看本教程的章节索引。
在本章,我们将实现代码来分析我们在第一章描述的命令:
|
|
分析做完后,我们将修改我们的服务器来派发被分析的命令给我们前面已经构建的 :kv 应用。
本章是Mix和OTP教程的一部分,它依赖这个教程的前面章节。要获得更多信息,请阅读本教程的第一章,或者查看本教程的章节索引。
在本章,我们将实现代码来分析我们在第一章描述的命令:
|
|
分析做完后,我们将修改我们的服务器来派发被分析的命令给我们前面已经构建的 :kv 应用。
本章是Mix和OTP教程的一部分,它依赖这个教程的前面章节。要获得更多信息,请阅读本教程的第一章,或者查看本教程的章节索引。
在本章,我们将学习如何使用Erlang的 :gen_tcp 模块来处理请求。这提供一个很好的机会来探索Elixir的Task模块。在将来的章节我们将扩展我们的服务器以便使得它可以真正地处理命令。
本章是Mix和OTP教程的一部分,它依赖这个教程的前面章节。要获得更多信息,请阅读本教程的第一章,或者查看本教程的章节索引。
在本章,我们将讨论用Mix如何管理依赖。
我们的 kv 应用已经完成,所以是时候实现一个服务器,它将处理在第一章我们定义的请求:
|
|
但是,我们不是增加更多代码到 kv 应用里,而是将构建一个TCP服务器作为另一个应用,它是 kv 应用的一个客户端。因为整个运行时和Elixir生态是面向应用的,因此把我们的项目分成一起运作的更小的应用比构建一个巨大单一的应用有意义。
构建我们新应用前,我们必须讨论Mix如何处理依赖。在实践中,我们通常运用两种依赖:内部依赖和外部依赖。Mix支持运用这两种依赖。
本章是Mix和OTP教程的一部分,它依赖这个教程的前面章节。要获得更多信息,请阅读本教程的第一章,或者查看本教程的章节索引。
每次我们需要查询一个bucket,我们需要发送一个消息给registry。这样的话,我们的registry被多个进程并发地访问,registry可能成为瓶颈!
在本章,我们将学习ETS(Erlang数据存储)并且学习如何使用它来作为缓存机制。
警告:不要贸然使用ETS作为缓存!记录并分析你应用的性能并识别哪部分是瓶颈,这样你就知道你应该在哪里缓存,你应该缓存什么。本章只是在你一旦需要的情况下,ETS如何被使用的一个例子。
本章是Mix和OTP教程的一部分,它依赖这个教程的前面章节。要获得更多信息,请阅读本教程的第一章,或者查看本教程的章节索引。
到目前为止,我们的应用有一个registry,它可以监测数十个而不是数百个bucket。虽然我们认为我们的当前的实现是非常棒的,但是没有软件是没有bug的,失败一定会发生。
当失败发生时,你的第一反应可能是:“让我们补救这些失败”。但是在Elixir中,我们避免挽救异常的防御型编程习惯,这在其他语言中常常见到。相反,我们说“让它崩溃”。如果有bug导致我们的registry崩溃,我们没有什么可担心的,因为我们将设置一个监督者,它会重启一个新的registry。
在本章,我们将学习监督者和应用。我们不止创建一个监督者,而是创建两个监督者,并使用它们来监督我们的进程。
本章是Mix和OTP教程的一部分,它依赖这个教程的前面章节。要获得更多信息,请阅读本教程的第一章,或者查看本教程的章节索引。
在上一章我们用agent来表示我们的bucket(容器)。在第一章中,我们指出了我们要命名每个bucket,这样我们就可以做到以下几点:
|
|
既然agent是进程,那么每个bucket有一个进程标识符(pid),但是它没有名字。我们已经在进程那一章中了解了的名字注册,你可能会倾向于使用此注册来解决这个问题。例如,我们可以像下面这样来创建一个bucket:
|
|
然而,这是一个可怕的想法!在Elixir中进程的名字必须是原子,这意味着我们需要将bucket的名字(通常是从外部客户端接收过来的)转换为原子,而我们不应该将用户输入转换为原子。这是因为原子没有垃圾回收。一个原子一旦被创建,它就再也不会被回收。从用户的输入来生成原子将意味着用户可以注入足够多的不同名字来耗尽我们系统的内存!
在实践中,更可能的是你会耗尽内存也就是使得你的系统崩溃之前达到Erlang虚拟机的原子的最大数量的限制。
我们不滥用名字注册的功能,反而是创建我们自己的注册进程,它持有一个映射来关联bucket的名字和bucket的进程。
注册需要保证字典内容总是最新的。例如,一个bucket进程因为bug而崩溃了,注册必须清理字典来避免数据被污染。在Elixir中,我们描述这一点,说注册表需要监视每个bucket。
我们将使用一个 GenServer 来创建一个注册进程,它可以监测bucket进程。GenServer提供工业级强度的功能来构建Elixir和OTP里的服务器。
本章是Mix和OTP教程的一部分,它依赖这个教程的前面章节。要获得更多信息,请阅读本教程的第一章,或者查看本教程的章节索引。
在本章,我们将创建一个名为 KV.Bucket 的模块。这个模块将以某种方式存储我们的键值对实体,并允许其他进程读取和修改它们。
如果你跳过了入门教程或已经读过了很长时间,你应该重新读一下进程这一章。我们将用它作为起始点。
在本教程里,我们将学习如何构建一个完整的Elixir应用,该应用有自己的监督树、配置、测试等等。
这个应用是一个分布式键值对存储。我们将组织键值对到容器中,然后跨多节点分布这些容器。我们也将构建一个简单的客户端来让我们连接到那些节点中的任何一个,并且像如下所示发送请求:
|
|
为了构建我们的键值对应用,我们将使用三个主要工具:
在本章里,我们将用Mix创建我们的第一个项目,然后逐步探索OTP、Mix和ExUnit里的不同特性。
注意:本教程需要Elixir v1.2.0 或者更高版本。你可以用 elixir –version 来检查你的Elixir版本并且如果需要的话,你可以按 Elixir入门教程第一章里 描述的步骤安装一个最新的版本。
如果你对本教程有任何疑问或改进建议请到诸如 Elixir论坛 或 问题跟踪 告诉我们。你的建议对我们的教程真的很重要。
最后,本教程的代码在这个仓库里,你可以把它当做参考。
Elixir提供了非常棒的与Erlang的库交互的能力。实际上,Elixir不鼓励简单地封装Erlang的库,而是提倡直接与Erlang代码交互。本文我们将介绍一些最常见和有用的而在Elixir里找不到的Erlang功能。
当你逐渐熟悉了Elixir,你可能想要探索Erlang的STDLIB指引手册来获得更多细节。