RabbitMQ集群Erlang知识扩展-阿里云开发者社区

开发者社区> 安全> 正文

RabbitMQ集群Erlang知识扩展

简介:

Erlang是 一种通用的面向并发的编程语言

Erlang的推出则是为了打造一款高并发高扩展性的实时系统。例如应用于电信,银行,商业,即时通讯等场合。Erlang的运行时系统内置了对并发,分布式,容错等的处理。

Erlang的容错能力是它与生俱来的的能力,因为这是电信领域的重要需求。但是这并不代表Erlang是复杂的、不具表达力的。

OTP包含了一组库和实现方式,可以构建大规模、容错和分布式的应用程序,包含了许多强大的工具,能够实现H248,SNMP等多种协议,核心概念是OTP行为,可以看作一个用回调函数作为参数的应用程序框架,类似一个J2EE容器。行为负责解决问题的非函数部分,回调函数负责解决函数部分。

Erlang仅仅能在具有相同的magic cookie系统之间的直接对话。如果想要在几台机器之间运行相互通信的Erlang程序,最简单的方法就是放置一个名叫".erlang.cookie"的文件在每个机器的$HOME目录里,并且把该文件的权限设置为400,该文件的内容即cookie名字。400权限意味着该文件仅能被此文件的owner访问。 

引用

$ cd 
$ cat  .erlang.cookie 
this is very secret 
$ chmod 400 .erlang.cookie 



Erlang支持分布式通信的两大基石 
1. 进程间通过拷贝通信(Process communication by copying) 
2. 透明的位置信息(Location transparency) 

Erlang自己会保证进程标识符在运行网络上的唯一,即便是跨机器(Erlang guarantees that process identifiers are unique on the network, even across  machines.)也一样。 

每一个Erlang VM都叫作一个节点(Node),当两个或者多个Node都知道了对方之后,这些节点就形成了集群(Cluster)。Erlang集群默认情况下是完全连接(fully connected)的,即Erlang集群中的每一个节点都知道每一个其他的节点,并且相互之间能够直接通信。正因为如此,在实际中Erlang通常只有几十个节点,一般不会有几百个或者更多的节点,因为在完全连接的网络中,节点越多,保持节点之间的通信开销越大。 

但是可以通过某个特殊的节点,将多个cluster连接成一个更大的cluster,这样的cluster不是完全连接的,cluster直接是通过这个特殊的节点连接的。 

在Erlang集群中,节点不会主动去寻找其他节点,除非他寻找其他节点有事要做;在找到其他节点之后,他们会相互追踪对方,并且交换彼此所知道的其他节点信息,以便于形成一个完全连接的网络。 

每个节点都有自己的名字(Name),其他节点就是通过这个名字来查找到该节点,并且与之交互。通过内建函数node()可以取得当前节点的名字,节点的名字格式为: nodename@hostname。如果一个节点运行在非分布式模式下,则该节点的名字默认是nonode@nohost。在单台机器上允许同时运行多个节点。 

如何启动一个节点? 
启动一个节点可以使用命令 

引用

erl -name my_node_name


-name选项用在有DNS正常工作的普通网络中,即可以正常使用完全限定名(fully qualified name)的网络环境中。 
或者 

引用

erl -sname my_node_name


当完全限定名(fully qualified name)不起作用的时候,使用-sname选项。这种情况经常发生在局域网的生产环境中。比如在局域网中不能通过域名访问其他机器时,你只能使用短名称(sname)访问。 
只要所有节点都在同一个子网中,短名称就起作用。 

使用短名称和长名称的节点会使用不同的通信模式工作。在同一个Erlang集群中,所有节点必须使用统一的通信模式,或者使用长名称,或者都是用短名称,不可混用。 

当Erlang VM作为一个节点运行时,他的节点名称会显示在命令行提示符中,比如我启动了一个名叫guibin的短名称节点: 

引用

$ erl -sname guibin 
Erlang R14B01 (erts-5.8.2) [source] [smp:2:2] [rq:2] [async-threads:0] [hipe] [kernel-poll:false] 

Eshell V5.8.2  (abort with ^G) 
(guibin@localhost)1> 



Erlang nodes是如何找到对方并通信? 
负责Erlang节点间通信的是一个叫作epmd(Erlang Port Mapper Daemon)的后台线程。如下: 

引用

$ ps ax | grep epmd 
  305   ??  S      0:00.02 /opt/local/lib/erlang/erts-5.8.2/bin/epmd -daemon 
  513 s003  U+     0:00.00 grep epmd 


当启动一个node时,node会检查本机是否有epmd在运行,如果没有则启动epmd。epmd启动之后会跟踪记录所有本机运行的node和这些node被分配的端口号。 
当一个在本机的node想和远程的node通信时,本地的epmd首先会和远程的epmd通信(默认在4369端口上使用TCP/IP),询问是否有相应的node在那里运行。如果有,则远程的epmd会响应请求,并直接和本地的epmd通信。 
但是epmd不会自动去寻找其他的epmd,这些通信和寻找过程必须被node的查找操作触发。 

注意:Erlang默认的分布模型是基于所有集群中的机器都运行在一个被信任和可靠的网络中。如果实际运行的网络环境并非如此信任和可靠,而是通过广域网连接,则集群中的机器间通信应该直接使用TCP(或者UDP,或者SCTP)。或者也可以基于SSL、SSH或者IPsec建立隧道通信。 

Erlang基于cookie的安全系统 
如果在一台机器上至少启动过一次node之后,就会生成cookie文件。初次启动node,node会自动生成由随机字符串组成的cookie。默认情况下,一个node认为其他的能和他通信的node都具有相同的cookie。 
推荐只有owner才对cookie文件具有读的权限,即400。 

Erlang分布式控制常用命令选项 
命令erl用来启动Erlang的运行时系统(Erlang runtime system)。 

引用

-name NodeName


这个选项使得启动的Erlang的运行时系统处于分布式模式下,节点名称为NodeName@FullyQualifiedName。 

引用

-sname NodeName


这个选项使得启动的Erlang的运行时系统也处于分布式模式下,节点名称为NodeName@ShortName。 

引用

-setcookie Cookie


该选项设置当前节点的Magic Cookie为Cookie,而不使用默认的~/.erlang.cookie中的内容作为Cookie。 

引用

-connect_all false


这个选项设置该启动节点和其他Erlang节点的连接模式为非完全连接,即该节点仅仅保存和他直接通信的节点状态,非直接连接的节点状态不理会。 



本文转自 OpenStack2015 51CTO博客,原文链接:http://blog.51cto.com/andyliu/1902266,如需转载请自行联系原作者

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

分享:
+ 订阅

云安全开发者的大本营

其他文章