Erlang-China

erlang 中文社区

【转】Concurrency and Erlang


好久之前就发现了这篇大作,可惜上次机器重装,不慎弄丢了,现在好容易给找回来。赶紧记下来。

基本上, 这篇(及其参考资料)对于 Concurrency 领域的 N 多问题给出了一个全景层面的描写。透过它的那些链接,能找到这一领域关于这些问题的(几乎)所有技术文章。强!


Erlang新书及[无责任]前景预测


Programming ErlangErlang 领域最近有一个大好消息,那就是 Joe Armstrong 终于要出第二本书了。

这是一件奇妙的事情,因为距离第一本的出版,好像已经快有10多年了(第一本好像是198x年出的)。说起来,在软件领域,恐怕这也算是比较罕见的了。一门语言的创立着,在多年以后,还像 Joe Armstrong 一样,积极的活跃在第一线。着实让人敬佩。

为什么在这么多年之后,又有了出版这门语言另一本书的必要呢?或许,我们可以从另外一个角度来解读,这种语言与众不同的特质与命运。

先卖个关子,就让我们从计算机目前的发展趋势说起。


【转】Erlang 的分布通讯安全策略


原文地址:avindev.javaeye.com
原文作者:AvinDev

Erlang的分布式通讯安全策略,可以归结为 All or None。要不拥有全部的权限,要不就完全没有。

它的节点安全设置,是通过一个magic cookie来实现的。这个文件默认放到
$HOME/.erlang.cookie ,文件内容是字符串。

当启用分布通讯的时候,这个magic cookie就很重要了。如果在命令行里面带上 -setcookie ,则在当前节点使用这个cookie值,否则会使用 $HOME/.erlang.cookie


Erlang/OTP R11B-4 发布


修正了不少bug,可以到 http://www.erlang.org/download.html 下载


目录结构习惯的Make解决


自从用惯了ant,就习惯把代码的目录结构整成:

project/
builid.xml
/src
/bin
/jar

这样的目录结构。然后,随时随地的一 ant,爽得不得了。而在 erlang 的 erl 中,貌似并不是这样,erlc自动编译在当前目录,一怒之下写了一个 .bat 来干 build 的活,倒也快活。

del ebin\*.beam
erlc -o ebin -I include src/game_server.erl
erlc -o ebin -I include src/game_admin.erl
erlc -o ebin -I include src/game_client.erl

最近,又觉得有些不爽——这多别扭呢。还想用 ant 来着,不过,今天又随手翻了下文档,原来人早有方案,也叫 make 。难怪 joe armstrong 说当他用完 prolog 的 compiler 之后,就再也用不到它了——都可以在 erlang 环境中完成嘛。新的文件路径是:


Erlang用于重写MySQL-HA


从MailList中看到:

On another note, I’m working on a rewrite of my HA project for MySQL in
erlang, also as a learning experience. This is still green, but if
anyone wants to let me know what you think
about the code, you can browse the svn repository here:
https://svn.sourceforge.net/svnroot/mysql-ha/trunk/mysql-ha-erl/
The script tabs.sh lets you replace \t (I use vim for programming) for
any given amount of whitespace.

目前看来,相当多的 Erlang 项目,集中于软件体系的基础架构部分,如 xmpp 的 mq 等“基础软件”。

下一篇,我来”大胆预期” Erlang 在未来可能的应用领域。


【转】Erlang网络编程-packet参数


原文地址:avindev.javaeye.com
原文作者:AvinDev

gen_tcp:listen(Port, Options),Options 为一个参数列表

之前介绍过 {active, Boolean} 这个 opt,现在介绍一下 {packet, PacketType}

引用

{packet, PacketType} (TCP/IP sockets)
Defines the type of packets to use for a socket. The following values are valid:
raw | 0
No packaging is done.
1 | 2 | 4
Packets consist of a header specifying the number of bytes in the packet, followed by that number of bytes. The length of header can be one, two, or four bytes; the order of the bytes is big-endian. Each send operation will generate the header, and the header will be stripped off on each receive operation.
asn1 | cdr | sunrm | fcgi | tpkt | line
These packet types only have effect on receiving. When sending a packet, it is the responsibility of the application to supply a correct header. On receiving, however, there will be one message sent to the controlling process for each complete packet received, and, similarly, each call to gen_tcp:recv/2,3 returns one complete packet. The header is not stripped off.
The meanings of the packet types are as follows:
asn1 - ASN.1 BER,
sunrm - Sun’s RPC encoding,
cdr - CORBA (GIOP 1.1),
fcgi - Fast CGI,
tpkt - TPKT format [RFC1006],
line - Line mode, a packet is a line terminated with newline, lines longer than the receive buffer are truncated.

之前介绍过一个愚蠢的方案,用于演示Binary的匹配。现在完全可以这样做:


【转】Erlang网络编程-Binary


原文地址:avindev.javaeye.com
原文作者:AvinDev

在Erlang里面,Binary支持强大的模式匹配,这为编写网络通讯程序提供了便利。

比如一个协议串,格式如下
HEADER(2 Bytes) ID (1 Byte) MESSAGE(10 Bytes)
可以这样匹配
<>

有一些协议,头部是接下来数据的长度,这样就更简单了
<>

一个IPV4的头部可以这样表示
引用
<
Identification:16, FlagX:1, FlagD:1, FlagM:1,
FragmentOffset:13, TTL:8, Protocol:8,
HeaderCheckSum:16, SourceAddress:32,
DestinationAddress:32, Rest/binary>> = Packet.

具体应用
比如定义了一个协议,头部2字节为长度,接下来是Body。要接收这样一个包,有可能会不全,也有可能2个包一起接收了,这时候可以这样做:

代码

1. loop(Socket, Buffer) ->
2. RecvBinary = gen_tcp:recv(Socket,0),
3. Binary = list_to_binary(binary_to_list(Buffer) ++ binary_to_list(RecvBinary)),
4. case Binary of
5. <> ->
6. handleMessage(Body),
7. loop(Socket, Remain);
8. <<_/binary>> ->
9. loop(Socket, Binary)
10. end.

这个解决方案还是相当笨拙的,Erlang本身有更好的解决方案,这里只是为了演示。


【转】Erlang 中的 half-sync/half-async 和 Leader/Followers 模式


原文地址:avindev.javaeye.com
原文作者:AvinDev

http://www.javaeye.com/article/60414 里面,谈到了半同步/半异步和领导者/追随者模式,在Erlang里面可以很简单得实现它

下面看看 half-sync/half-async 的例子

代码
  1. start() ->
  2. case gen_tcp:listen(80, [binary,
  3. {nodelay,true},
  4. {packet, 0},
  5. {reuseaddr, true},
  6. {active, false}]) of
  7. {ok, Listen} ->
  8. io:format(“Listning port 80 @ ~p~n”, [self()]),
  9. accept_loop(Listen);
  10. Error -> io:format(“Error occur: ~p~n”, [Error])
  11. end.
  12. accept_loop(Listen) ->
  13. case gen_tcp:accept(Listen) of
  14. {ok, Socket} ->
  15. io:format(“Socket ~p connected~n”, [Socket]),
  16. spawn(?MODULE, handler, [Socket]),
  17. accept_loop(Listen);
  18. Other -> exit(oops)
  19. end.
  20. handler(Socket) ->
  21. io:format(“Waiting incoming message @ ~p~n”, [self()]),
  22. inet:setopts(Socket, [{nodelay,true}, {active, false}]),
  23. case gen_tcp:recv(Socket, 0) of
  24. {ok, Packet} ->
  25. io:format(“Receive msg ~p~n”, [binary_to_list(Packet)]),
  26. gen_tcp:send(Socket, Packet),
  27. gen_tcp:close(Socket),
  28. handler(Socket);
  29. {error, Reason} ->
  30. io:format(“Socket ~p error ~p~n”, [Socket, Reason])
  31. end.

在许多“网络编程”的教程里面,都会给出类似这样的例子。首先当前线程先监听一个端口,然后accept外来Socket连接,并将Socket传 递到新的线程中处理。在C、Java这样的语言中,创建一个线程的开销是很大的,一般来说,会使用线程池来处理短连接,一些Web Server就是基于这样的模式。然而在Erlang里面,创建一个Proces的开销极少,进程间切换完全在用户态实现,这样减少了用户态和核心态间切 换的开销,使得这种模式成为了可能。


【转】轻松实现可伸缩性,容错性,和负载平衡的大规模多人在线系统


原文地址:www.devmaster.net/articles/mmo-scalable-server/
原文作者:Joel Reymont
译文地址:blog.mylkcn.net/senzung.php
翻译作者:神宗冥浩

简介:

本文以我的OpenPoker项目为例介绍另一种构建大规模多人在线系统的方案。OpenPoker是一个大型多人扑克网游,内建支持了容错能力,负载平衡和无限制的规模大小。OpenPoker的源代码遵循GPL协议可以从我的网站下载,大约包含一万行代码,有三分之一是用来测试的。

在Openpoker最终版出台之前,我花了很大精力设计参考,尝试过Delphi, Python, C#,C/C++还有Scheme。我甚至还用Common Lisp完成了一个可运行的Poker引擎。虽然我花了9个多月研究设计,最终代码编写却只用了6个星期,这最后的高效率要归功于选择了Erlang作为编写平台。

根据比较,老版本的OpenPoker需要4~5个人的小组9个月时间完成。原班人马还另外完成了一个Windows版的客户端,就算把这个开发时间的一半(1个半月)算进去,也比预期的18个月少得多,就当今游戏开发的客观环境,如此可观的时间节省不可小看!