ToPid ! Data
ToPid 是接受方进程的id , Data 可以是 Erlang 的任何类型,比如
Pid ! {name, "jb51.net"}.
也就是可以直接把任何数据结构当成消息发送,天生自带 RPC 通信。 (虽然本来 RPC 的含义是“远程过程调用”,不过其实反正就是帮你序列化了数据结构,Erlang 的 ! 操作符也是如此。)
进程端口映射
节点之间发消息在代码里面的表示也还是
ToPid ! Data
也就是在写代码的时候,根本不用考虑该进程是在哪台机器上面, 无论是本 Erlang 进程(这里的进程是操作系统级别的进程,不是 Erlang 的轻量进程) 内, 还是其他机器的进程,都不用管。 这是因为有 epmd 的存在。
Epmd是Erlang Port Mapper Daemon的缩写,在Erlang集群中相当于dns的作用,供给节点名称到端口的查询办事,epmd绑定在总所周知的4369端口上。
有了 epmd ,写分布式程序就好像写单机程序一样简单。
严密的模块化管理
Erlang 的模块类似 C++ 中的 namespace(命名空间),但是比命名空间更利于高效的软件工程管理。
在 Erlang 项目源码中处处可见如下代码。
-module(my_app).
-export([start/2, stop/1]).
-module 指明模块名,-export 指明导出的函数。 未被导出的函数都无法被外界调用。 从软件工程上看的话,这样使得模块功能和使用方法更加清晰。 使用者只需要关心如何 -export 里面的函数即可。 相比较之下 C++ 对这方面特别不规范,而 Java 通过对类声明为 public class 指明可以被外界使用, Node.js 也是使用 export 来显示声明可以被外界使用的函数。
行为模式
-module(ecomet_app).
-behaviour(application).
%% comment: Application callbacks
-export([start/2, stop/1]).
-behavior(application).
Erlang/otp 里面的【行为模式】概念等价于 OOP 里面的接口概念。 上面代码示例的意思就是该模块(ecomet_app)遵守的行为模式是(application)。 刚行为模式需要实现的两个接口函数就是 -export([start/2, stop/1]). 。
另一个示例如下是遵守监督者(supervisor)行为模式, 实现的一个接口函数是 -export([init/1]). 。
-module(ecomet_sup).
-behaviour(supervisor).
%% Supervisor callbacks
-export([init/1]).
监督者机制
Erlang/otp 的天生分布式特性在监督机制里面体现的很好, 每一个 otp 应用启动的时候,都是启动监督者(supervisor)和工作者(worker)。 他们的关系是树形结构,每个工作者的上级都会有监督者, 每个监督者的上级也可能有监督者。 当工作者异常退出的时候,监督者会根据相应的参数决定是否对工作者进行重启。 如果重启失败的话监督者也会退出,而更加上层的监督者收到信号后会对他们进行重启等处理。 这个监督者机制非常好理解,其实就是 OOP 编程里面的 try ... catch 异常处理机制。 当出现异常的时候一层一层的往上抛出,直到有人重启。










