<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	>

<channel>
	<title>Erlang-China</title>
	<atom:link href="http://erlang-china.org/feed" rel="self" type="application/rss+xml" />
	<link>http://erlang-china.org</link>
	<description>erlang 中文社区</description>
	<pubDate>Tue, 22 Jul 2008 02:14:11 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.6</generator>
	<language>en</language>
			<item>
		<title>erl 的 log4*, bt 以及杂七杂八</title>
		<link>http://erlang-china.org/misc/log4erl_erltorrent_and-so-on.html</link>
		<comments>http://erlang-china.org/misc/log4erl_erltorrent_and-so-on.html#comments</comments>
		<pubDate>Thu, 17 Jul 2008 04:01:47 +0000</pubDate>
		<dc:creator>jackyz</dc:creator>
		
		<category><![CDATA[misc]]></category>

		<guid isPermaLink="false">http://erlang-china.org/?p=198</guid>
		<description><![CDATA[etorrent 是最近相当活跃(常能在 maillist 见到 ann )的一个项目，它是用 erlang 实现的一个 bittorrent 客户端。记得刚刚接触 erlang 的时候就觉得它貌似很适合用来写 bittorrent 客户端(分布式/TCP/并发)，深入了解一番了之后，又觉得比起 C 来 erlang 并没有太明显的优势(GUI/CPU Heavy/IO/File)，加之后来见到堪称完美的 uTorrent 横空出世(说实话，除了网上银行，唯一想让我回到 windows 平台的东西就是它了)让人不再有动力作“写 torrent 客户端”之想，没想到时隔一年，还真见到了这样的项目，让人感慨。现在的 etorrent 已经是第二个公开发布的版本了，从它的 change log 看到，特性增强很厉害，以“ 20 个 torrent 占用 50－80M 内存”这样的指标来说，已经相当接近实用水平了。或许日后的 etorrent 再配上一个好用的 frontend 能够打造出像 xmms2 那样强大的软件也说不定呢。
log4erl 是一个 log4* 的 erlang 实现。对于广大习惯了 log4* 的 erlang 使用者来说，确是一个福音。不过，从某种程度上讲，这也可以算是某种“重复建设”—— erlang 自身已经内置了相当强大的日志机制。注意，只是强大，我并没有说易用。因为对于广大 log4* 爱好者们而言，只有能使用 [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://code.google.com/p/etorrent/" target=_blank>etorrent</a> 是最近相当活跃(常能在 maillist 见到 ann )的一个项目，它是用 erlang 实现的一个 bittorrent 客户端。记得刚刚接触 erlang 的时候就觉得它貌似很适合用来写 bittorrent 客户端(分布式/TCP/并发)，深入了解一番了之后，又觉得比起 C 来 erlang 并没有太明显的优势(GUI/CPU Heavy/IO/File)，加之后来见到堪称完美的 uTorrent 横空出世(说实话，除了网上银行，唯一想让我回到 windows 平台的东西就是它了)让人不再有动力作“写 torrent 客户端”之想，没想到时隔一年，还真见到了这样的项目，让人感慨。现在的 etorrent 已经是第二个公开发布的版本了，从它的 change log 看到，特性增强很厉害，以“ 20 个 torrent 占用 50－80M 内存”这样的指标来说，已经相当接近实用水平了。或许日后的 etorrent 再配上一个好用的 frontend 能够打造出像 xmms2 那样强大的软件也说不定呢。</p>
<p><a href="http://code.google.com/p/log4erl/" target=_blank>log4erl</a> 是一个 log4* 的 erlang 实现。对于广大习惯了 log4* 的 erlang 使用者来说，确是一个福音。不过，从某种程度上讲，这也可以算是某种“重复建设”—— erlang 自身已经内置了相当强大的日志机制。注意，只是强大，我并没有说易用。因为对于广大 log4* 爱好者们而言，只有能使用 grep/awk/perl 这些标准 unix tool chain 来处理的，格式化的，每条一行的(问题是，以我的经验来说，&#8221;每条一行&#8221;这种限制常常会逼人多费半天劲，或者多写一大堆)才是易用的日志。而 erlang 自身内置的日志机制说实话也毫不逊色，只是用来颇有一些不同(加之文档组织得别出心裁，让人不易找到)，各自属于不同的风格。既被拔到了“风格”层面，也就参杂了情感因素，无法以简单的方式来区分高下(君不见 csdn 上 x vs y 的口水仗层出不穷无休无止?)。本是见仁见智的事，大家看个人的喜好各取所需就是了。</p>
<p>顺便说说 erlang 自身的日志机制，极简的例子看上去象这样：</p>
<div class="hl-title">&#19979;&#36733;: <a href="http://erlang-china.org/wp-content/plugins/coolcode/coolcode.php?p=198&amp;download=elog.config">elog.config</a></div><div class="hl-surround"><div class="hl-main"><span style="color: #ffa500;">%% text erorr log</span><span style="color: Gray;"><br /></span><span style="color: Olive;">[</span><span style="color: Gray;">{</span><span style="color: Blue;">kernel</span><span style="color: Gray;">,<br />&nbsp; </span><span style="color: Olive;">[</span><span style="color: Gray;">{</span><span style="color: Blue;">error_logger</span><span style="color: Gray;">,<br />&nbsp;&nbsp; &nbsp;{</span><span style="color: Blue;">file</span><span style="color: Gray;">, </span><span style="color: #8b0000;">&quot;</span><span style="color: Red;">debug.log</span><span style="color: #8b0000;">&quot;</span><span style="color: Gray;"> }}</span><span style="color: Olive;">]</span><span style="color: Gray;">}</span><span style="color: Olive;">]</span><span style="color: Gray;">.</span></div></div>
<p>这好比是 log 的配置文件，然后，这样用：</p>
<div class="hl-surround"><div class="hl-main">erl -config elog.config<br />1&gt; error_logger:error_report([{tag1,data1},a_term,{tag2,data}]).<br />ok<br />2&gt; error_logger:error_report(&quot;Serious error in my module&quot;).<br />ok<br />3&gt; q().<br />ok</div></div>
<p>这样，在 debug.log 里面就有了：</p>
<div class="hl-surround"><div class="hl-main">$ more debug.log<br /><br />=ERROR REPORT==== 17-Jul-2008::11:32:11 ===<br />&nbsp;&nbsp; &nbsp;tag1: data1<br />&nbsp;&nbsp; &nbsp;a_term<br />&nbsp;&nbsp; &nbsp;tag2: data<br /><br />=ERROR REPORT==== 17-Jul-2008::11:32:31 ===<br />Serious error in my module</div></div>
<p>差不多就是这样了，更多配置，相关工具，以及更 “The Erlang Way” 的用法，可以参看文档 <a href="http://www.erlang.org/doc/apps/sasl/index.html" target=_blank>SASL</a> 的部分。</p>
<p>btw，升级 wp 时从 incoming link 里发现一个 &#8220;默默无闻的领悟Erlang传说&#8221; 的中文 blog <a href="http://www.toquick.com/" target=_blank>ToQuick</a> (图快?)，主人 cheng 同学治“程”(程序)态度严谨，细密，文章写得勤也写的好，值得推荐。下面对于 log4erl 的代码观感就转自图快：</p>
<blockquote><p>
log4erl代码非常精简，保持了erlang代码的风格，log4erl包括1个supervisor和2个gen_server和1个gen_event。<br />
log4erl.erl为gen_server和application behaviour的callback，其作为主要的module，<br />
log4erl_sup.erl为supervisor,启动log4erl,初始时将通过log4erl_sup:add_file_logger启动default_logger 日志记录器。<br />
log4erl_sup:add_file_logger/1会动态添加file_logger_guard和file_logger两个child process。
</p></blockquote>
<p>have fun.</p>
]]></content:encoded>
			<wfw:commentRss>http://erlang-china.org/misc/log4erl_erltorrent_and-so-on.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>经由 Erlang 开源项目之间的合作“铸就”更好的 key-value 存储系统？</title>
		<link>http://erlang-china.org/news/next_key-value_store_system.html</link>
		<comments>http://erlang-china.org/news/next_key-value_store_system.html#comments</comments>
		<pubDate>Mon, 14 Jul 2008 08:25:45 +0000</pubDate>
		<dc:creator>jackyz</dc:creator>
		
		<category><![CDATA[news]]></category>

		<guid isPermaLink="false">http://erlang-china.org/news/next_key-value_store_system.html</guid>
		<description><![CDATA[自从 Amazon 的 Dynamo 横空出世，开源的 Erlang 的 Key-Value 存储机制(毕竟有一些区别，因此我并不愿意把这个东西称作数据库)似乎已经成为了一个炙手可热的研究领域。先是有 CouchDB (本站多次介绍，已经被 apache 接纳的开源项目)，现在又有了 Kai 。如果算上 Alexander Reinefeld 在 erlang exchange 2008 上展示的项目，很短的时间之内，这一领域已经产生了三个 open source 项目了，可谓进展神速。
说起来，这个新出的 Kai 乃与是我们“一衣带水”的日本同行们的作品。加之此前听说的 Orto，以及零星听说的具有超强并发能力的 tokyocabinet，等。老实说，对于他们在 opensource 领域所表现出来的整体活力，确实有些惊讶。可惜不懂日文，未能对此作进一步的了解。(召唤日语达人整理一下)
话说这几个项目共同关注的是一个相同的问题，然而各自的侧重又略有不同。比如说，Kai 项目实现的乃是(又是) memcache 的访问接口和协议，主要侧重在利用 Erlang 来提升系统在“分布和容错”方面的特性。而 couchDB 则首先关注于实现 key-value 的数据存储本身，在此基础上建立完全不同于 RDBMS 的查询机制，并以优雅的 RESTful 访问接口而著称(Alexander 的项目资料不多，尚不明朗)。应该说是各有特色，而且具有很好的互补性，实在让人很难在这两者之间进行取舍。所以当 couchDB 团队的 Jan Lehnardt 向 Kai 团队的 Takeru Inoue 提出 [...]]]></description>
			<content:encoded><![CDATA[<p>自从 Amazon 的 Dynamo 横空出世，开源的 Erlang 的 Key-Value 存储机制(毕竟有一些区别，因此我并不愿意把这个东西称作数据库)似乎已经成为了一个炙手可热的研究领域。先是有 <a href="http://incubator.apache.org/couchdb/" target=_blank>CouchDB</a> (本站多次介绍，已经被 apache 接纳的开源项目)，现在又有了 <a href="http://kai.wiki.sourceforge.net/" target=_blank>Kai</a> 。如果算上 <a href="http://www.erlang-exchange.com/alexander-reinefeld" target=_blank>Alexander Reinefeld 在 erlang exchange 2008 上展示的项目</a>，很短的时间之内，这一领域已经产生了三个 open source 项目了，可谓进展神速。</p>
<p>说起来，这个新出的 Kai 乃与是我们“一衣带水”的日本同行们的作品。加之此前听说的 <a href="http://ejohn.org/files/orto.pdf">Orto</a>，以及零星听说的具有超强并发能力的 <a href="http://tokyocabinet.sourceforge.net/" target=_blank>tokyocabinet</a>，等。老实说，对于他们在 opensource 领域所表现出来的整体活力，确实有些惊讶。可惜不懂日文，未能对此作进一步的了解。(召唤日语达人整理一下)</p>
<p>话说这几个项目共同关注的是一个相同的问题，然而各自的侧重又略有不同。比如说，Kai 项目实现的乃是(又是) memcache 的访问接口和协议，主要侧重在利用 Erlang 来提升系统在“分布和容错”方面的特性。而 couchDB 则首先关注于实现 key-value 的数据存储本身，在此基础上建立完全不同于 RDBMS 的查询机制，并以优雅的 RESTful 访问接口而著称(Alexander 的项目资料不多，尚不明朗)。应该说是各有特色，而且具有很好的互补性，实在让人很难在这两者之间进行取舍。所以当 couchDB 团队的 Jan Lehnardt 向 Kai 团队的 Takeru Inoue 提出 Collaborate 的建议时，对于广大使用者而言，确实是最为“喜闻乐见”的情形。</p>
<p>或许我们很快就能见到 CouchDB Powered Kai 又或者是 Kai Powered CouchDB，两个项目的特性得到融合，也许，两者之间会形成一种如同 innoDB 之于 mysql 那样的合作关系，谁知道呢？未来充满可能，值得我们期待。开源的 Erlang 就是这么精彩。</p>
]]></content:encoded>
			<wfw:commentRss>http://erlang-china.org/news/next_key-value_store_system.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>上干货 slides on Erlang-Exchange-2008</title>
		<link>http://erlang-china.org/news/slides_on_erlang-exchange-2008.html</link>
		<comments>http://erlang-china.org/news/slides_on_erlang-exchange-2008.html#comments</comments>
		<pubDate>Mon, 30 Jun 2008 03:27:40 +0000</pubDate>
		<dc:creator>jackyz</dc:creator>
		
		<category><![CDATA[news]]></category>

		<guid isPermaLink="false">http://erlang-china.org/news/slides_on_erlang-exchange-2008.html</guid>
		<description><![CDATA[Erlang-Exchange-2008(别点了，超流量被关啦)刚刚结束，对于我们这些无法亲临现场的“干粉”(干粉＝＝只能干瞪眼的粉丝)而言，等的就是会议结束，各路 slide 纷纷出炉的这一刻。这个场景多少让我想起小时候，看着别人放完炮，一大堆小屁孩就一拥而上，吸溜着鼻涕猛捡那些还没炸完的零碎小鞭炮的岁月。所不同的是，数字时代，每个人都可以捡到“第一手”的干货，不会为了分赃不均而打上一架。不过，任何一个时代，找到干货或者捡到鞭炮的快乐都是相同的，简单而纯粹。下面就是快乐的“干货大放送”(远未集齐，所缺部分希望各位能继续跟帖完善)。
由 Jamaal 同学补充：
在 video.google.com 上搜索 Erlang eXchange 能找到一堆演示视频，虽然没有 PPT/PDF 会略有遗憾，但胜在真人出演，也相当不错。懒得搜索的同学可以点[这里]。
Armstrong on Software: Erlang &#038; SMP,
Joe Armstrong
Introducing Erlang to Motorola: The Journey to Success,
Nicholas Gunder &#038; Torben Hoffman
Erlang- D-Trace,
Garry Bulmer
Erlang &#038; Robotics: The ROSEN Framework at the Eurobot 2008 Competion,
Corrado Santoro
Erlang/OTP Vs Google App Engine, The CEO View,
Gordon Guthrie
Building Web Applications in Erlang,
Xingdong Bian [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.erlang-exchange.com/" target=_blank>Erlang-Exchange-2008</a>(别点了，超流量被关啦)刚刚结束，对于我们这些无法亲临现场的“干粉”(干粉＝＝只能干瞪眼的粉丝)而言，等的就是会议结束，各路 slide 纷纷出炉的这一刻。这个场景多少让我想起小时候，看着别人放完炮，一大堆小屁孩就一拥而上，吸溜着鼻涕猛捡那些还没炸完的零碎小鞭炮的岁月。所不同的是，数字时代，每个人都可以捡到“第一手”的干货，不会为了分赃不均而打上一架。不过，任何一个时代，找到干货或者捡到鞭炮的快乐都是相同的，简单而纯粹。下面就是快乐的“干货大放送”(远未集齐，所缺部分希望各位能继续跟帖完善)。</p>
<p>由 Jamaal 同学补充：<br />
在 video.google.com 上搜索 Erlang eXchange 能找到一堆演示视频，虽然没有 PPT/PDF 会略有遗憾，但胜在真人出演，也相当不错。懒得搜索的同学可以点[<a href="http://video.google.com/videosearch?q=Erlang+eXchange" target=_blank>这里</a>]。</p>
<p>Armstrong on Software: Erlang &#038; SMP,<br />
Joe Armstrong</p>
<p>Introducing Erlang to Motorola: The Journey to Success,<br />
Nicholas Gunder &#038; Torben Hoffman</p>
<p>Erlang- D-Trace,<br />
Garry Bulmer</p>
<p>Erlang &#038; Robotics: The ROSEN Framework at the Eurobot 2008 Competion,<br />
Corrado Santoro</p>
<p>Erlang/OTP Vs Google App Engine, The CEO View,<br />
Gordon Guthrie</p>
<p><a href="http://erlangweb.sourceforge.net/doc/ErlangWeb.pdf">Building Web Applications in Erlang</a>,<br />
Xingdong Bian &#038; Michal Slaski</p>
<p>Erlang in Financial Applications,<br />
Dr. Erik Stenman</p>
<p><a href="http://docs.google.com/Presentation?id=ddqg9x35_97fnjs9jgh" target=_blank>Erlang and Ajax Web Applications</a>,<br />
Roberto Saccon</p>
<p>Quick Check for Erlang,<br />
John Hughes</p>
<p>Introduction using Faxien &#038; Sinan: Erlang Project Build &#038; Packaging Systems,<br />
Eric Merrit &#038; Martin Logan</p>
<p>Roktalk, Erlang Powered Mobile Conferencing,<br />
Jay Fenton</p>
<p>Wrangerl, The Erlang Refactoring Tool,<br />
Simon Thompson</p>
<hr />
<p>Enterprise Integration,<br />
Steve Vinoski</p>
<p>Erlang &#038; Tail-F,<br />
Klacke Wikström</p>
<p>Presenting RabbitMQ: An Erlang Based Implementation of AMQP,<br />
Matthias Radestock</p>
<p>EUnit – Lightweight Unit Testing for Erlang,<br />
Richard Carlsson,</p>
<p>ejabberd for web 2.0 development,<br />
Mickael Remond</p>
<p>Load Testing of Web Applications,<br />
Karthik Ramachandra,</p>
<p><a href="http://people.apache.org/~dennisbyrne/erlang_exchange/erlang_exchange_jinterface.ppt">Using Jinterface to Bridge Erlang and Java</a>,<br />
Dennis Byrne</p>
<p>Quick Check Tutorial: Using QuickCheck to Test Erlang Programs,<br />
John Hughes &#038; Thomas Arts,</p>
<p>Using Faxien and Sinan, A Hands-on Approach,<br />
Martin Logan &#038; Eric Merrit</p>
<p><a href="http://jan.prima.de/Erlang_eXchange_2008_CouchDB.pdf">Couch DB at 10,000 feet</a>,<br />
Jan Lehnardt</p>
<p>Building a transactional distributed data store with Erlang,<br />
Alexander Reinefeld</p>
<p>Tsung Tutorial,<br />
Mickael Remond,</p>
<p>Erlang Enterprise Integration Panel Discussion,<br />
Garry Bulmer</p>
]]></content:encoded>
			<wfw:commentRss>http://erlang-china.org/news/slides_on_erlang-exchange-2008.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>Good News &#8212; Mnesia Unlimited!</title>
		<link>http://erlang-china.org/news/mnesia_unlimited.html</link>
		<comments>http://erlang-china.org/news/mnesia_unlimited.html#comments</comments>
		<pubDate>Mon, 23 Jun 2008 16:31:46 +0000</pubDate>
		<dc:creator>jackyz</dc:creator>
		
		<category><![CDATA[news]]></category>

		<guid isPermaLink="false">http://erlang-china.org/news/mnesia_unlimited.html</guid>
		<description><![CDATA[我们知道 mnesia 为很多人诟病的一个问题是——它有着诸多让人费解的限制。比如说，在 32 位的系统上，你最多只能存储 4G 的数据。又比如传说中磁盘表让人胆战心惊的修复过程。这些缺陷常常让人在试图推广 erlang 时，总觉得有些底气不足。虽然说，在实用的角度， 4G 其实也够用了，况且还可以分块。但无论怎么说，这种限制毕竟让人不爽。但其实，这些让人尴尬的限制其实并不是 mnesia 代码的问题（冤枉 mnesia 同学了），而是由它底层的存储机制 ets 和 dets 的特性所决定的(好比 mysql 之于 myisam / innodb 的关系)。现在好了，我们可以说，这些让人不快的限制已经可以被抛在脑后了。
Joel Reymont 就是那位在 05 年写出惊到大家的《Writing Low-Pain Massively Scalable Multiplayer Servers》一文的作者。(此文本站亦有中文翻译《轻松实现可伸缩性，容错性，和负载平衡的大规模多人在线系统》，感谢译者“神宗冥浩”)。他这次带给大家的是一个让人惊叹的大礼包——超乎想象的 mnesia 补丁包 mnesiaex 。这个东西解除了加在 mnesia 数据库系统上所有的限制(虽说上面已经提到，实际上 mnesia 代码本身没有什么真正的限制)——你现在可以用 SleepyCat/BerkeleyDB/MySQL/Amazon S3/Tokyo Cabinet/&#8230; 甚至是你自己喜欢的某种东西来当作 mnesia 的后端，就像 ets/dets 一样。而访问的接口仍保持不变——继续沿用 mnesia 的接口，一行也不用改。 DIY 这种扩展也变得相当容易，写一个 behavior [...]]]></description>
			<content:encoded><![CDATA[<p>我们知道 mnesia 为很多人诟病的一个问题是——它有着诸多让人费解的限制。比如说，在 32 位的系统上，你最多只能存储 4G 的数据。又比如传说中磁盘表让人胆战心惊的修复过程。这些缺陷常常让人在试图推广 erlang 时，总觉得有些底气不足。虽然说，在实用的角度， 4G 其实也够用了，况且还可以分块。但无论怎么说，这种限制毕竟让人不爽。但其实，这些让人尴尬的限制其实并不是 mnesia 代码的问题（冤枉 mnesia 同学了），而是由它底层的存储机制 ets 和 dets 的特性所决定的(好比 mysql 之于 myisam / innodb 的关系)。现在好了，我们可以说，这些让人不快的限制已经可以被抛在脑后了。</p>
<p>Joel Reymont 就是那位在 05 年写出惊到大家的《<a href="http://www.devmaster.net/articles/mmo-scalable-server/" target=_blank>Writing Low-Pain Massively Scalable Multiplayer Servers</a>》一文的作者。(此文本站亦有中文翻译《<a href="http://erlang-china.org/study/erlang-mmorpg.html" target=_blank>轻松实现可伸缩性，容错性，和负载平衡的大规模多人在线系统</a>》，感谢译者“神宗冥浩”)。他这次带给大家的是一个让人惊叹的大礼包——超乎想象的 mnesia 补丁包 <a href="http://code.google.com/p/mnesiaex/" target=_blank>mnesiaex</a> 。这个东西解除了加在 mnesia 数据库系统上所有的限制(虽说上面已经提到，实际上 mnesia 代码本身没有什么真正的限制)——你现在可以用 SleepyCat/BerkeleyDB/MySQL/Amazon S3/Tokyo Cabinet/&#8230; 甚至是你自己喜欢的某种东西来当作 mnesia 的后端，就像 ets/dets 一样。而访问的接口仍保持不变——继续沿用 mnesia 的接口，一行也不用改。 DIY 这种扩展也变得相当容易，写一个 behavior 就成了。</p>
<p>感谢 Joel Reymont 将这些工作回馈到开源社区。让我们一起祈祷 OTP Team 将这堆 patch 合并到 Erlang 的下一个发布版本中去吧。</p>
<p>顺便 blah 一下：</p>
<p>关于 Erlang</p>
<p>Erlang 就好像是 Ericsson 的私生子，从出生之日起就一直不得宠。在 AXD301 中的耀眼光芒，还是逃脱不了被弃用的命运(Ericsson 又转回去用 C 写交换机了，别让我猜中是因为公司政治)。失败了的 Joe 一伙人被迫离开自组 BlueTail 公司，绝望之中以 Open Source 协议公布了 Erlang 的代码，这个挫折使得它在编程语言的坟场寂寞的躺了多年，但仍然保留着翻盘的火种。默默无闻的完善了多年(加入SMP支持之类)，一直不为人所知。直到碰上 CPU 多核变革的机遇，这才重新捡回半条命，并渐渐被人提起。但别忘了，Erlang 直到现在仍然都是由 Ericsson 所拥有(整个的 OTP Team 都是他的员工)和操纵的(你能看到 Erlang 的 souce code 但能访问 Erlang source code 的 SVN 么？)。而比 Sun 的 Java 更加糟糕的是老态龙钟的 Ericsson 从来也没有意识到 Erlang 这个私生子身上所蕴含的潜力。麻烦哪位消息人士请一定转告 Ericsson 的老爷爷们，现在连 Sun 都已经完全开源了 Java ，请抓紧赶上吧，把那些没用的遮遮掩掩全都扔掉。因为对于一个程序设计语言而言，只有 Open Source Community 的程序员们，只有这些人，才是它生命力的真正源泉。在此祈祷 Open Source Erlang 项目朝着更 Open Source Way 的方向前进。</p>
<p>关于 Mnesia</p>
<p>因为工作关系，最近又有机会再来近距离审视 mnesia 这坨神奇的东西。Joe 老头在他的书中说：“关于 Mnesia 的更多内容，恐怕还要再写一本书才能讲得清楚”，现在我(部分地)知道这句话的分量了——我发现自己之前对于 Mnesia 的认识完全错了，而基于新的认识，好多东西都要推翻了重来(害我多做了那么多蹩脚的实现，写了那么多苍白的代码)。我的感觉(现在的)是—— mnesia 根本就不是什么数据库，这只是一个善意的谎言(以它出现的时代来说，太激进，会把人都吓跑了)。实际上，它根本就是一个 Erlang 的 hibernate 。换句话说，这个东西就不应该被拿来当作“数据库”用，而是应该拿来当作“数据层”用。一字之差，谬以千里，熟悉 Java/SSH 编程的同学们相信都能明白我在说什么。实际上，我私下里在怀疑这是 mnesia 最初的设计目的之一，但为了某种原因而故意不去点破这一层。但愿在这个问题上我只是个可耻的阴谋论者。</p>
]]></content:encoded>
			<wfw:commentRss>http://erlang-china.org/news/mnesia_unlimited.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>[荐]《对“A History of Erlang”的评论》</title>
		<link>http://erlang-china.org/misc/commentary-on_a-history-of-erlang.html</link>
		<comments>http://erlang-china.org/misc/commentary-on_a-history-of-erlang.html#comments</comments>
		<pubDate>Sun, 22 Jun 2008 14:26:19 +0000</pubDate>
		<dc:creator>jackyz</dc:creator>
		
		<category><![CDATA[misc]]></category>

		<guid isPermaLink="false">http://erlang-china.org/misc/commentary-on_a-history-of-erlang.html</guid>
		<description><![CDATA[原文在这里。貌似“功夫网”并未“河蟹”——既然能访问，俺就不盗版了。
这篇文章是 Robert Zubek 对 Joe Armstrong 在 07 年某个会上 show 的 “A History of Erlang”  PDF 的评论(更象是写了一个“注”)。基本上，相比著名的 “Joe Thesis 2003” (本站提供了中文翻译，感谢段先德同学)而言，这篇 PDF 中并没有太多的新内容，只能算是一个精编浓缩 remix 版而已。
但对 Joe Thesis 2003 这篇略嫌艰深的博士论文来说， Robert Zubek 的文章提供了很好的“补充视角”。也就是说，从 Joe Thesis 中我们能看到 Erlang 在“一系列问题”上做出了与众不同的选择。但如果没有一定的背景知识，我们或许没怎么觉得这“一系列问题”又有什么大不了的。而这一篇正好(部分地)补充了这些背景知识。
照例，对于这篇文章的干货，还是打捞一下。
But this paper really conveys the feel for what that means: huge collections of loosely coupled finite-state machines, [...]]]></description>
			<content:encoded><![CDATA[<p>原文在<a href="http://robert.zubek.net/blog/2008/06/21/commentary-on-a-history-of-erlang/" target=_blank>这里</a>。貌似“功夫网”并未“河蟹”——既然能访问，俺就不盗版了。</p>
<p>这篇文章是 Robert Zubek 对 Joe Armstrong 在 07 年某个会上 show 的 <a href="http://www.cs.chalmers.se/Cs/Grundutb/Kurser/ppxt/HT2007/general/languages/armstrong-erlang_history.pdf">“A History of Erlang” </a> PDF 的评论(更象是写了一个“注”)。基本上，相比著名的 <a href="http://www.erlang.org/download/armstrong_thesis_2003.pdf">“Joe Thesis 2003”</a> (本站提供了<a href="http://erlang-china.org/study/joe-armstrong_thesis_cn.html" target=_blank>中文翻译</a>，感谢段先德同学)而言，这篇 PDF 中并没有太多的新内容，只能算是一个精编浓缩 remix 版而已。</p>
<p>但对 Joe Thesis 2003 这篇略嫌艰深的博士论文来说， Robert Zubek 的文章提供了很好的“补充视角”。也就是说，从 Joe Thesis 中我们能看到 Erlang 在“一系列问题”上做出了与众不同的选择。但如果没有一定的背景知识，我们或许没怎么觉得这“一系列问题”又有什么大不了的。而这一篇正好(部分地)补充了这些背景知识。</p>
<p>照例，对于这篇文章的干货，还是打捞一下。</p>
<blockquote><p>But this paper really conveys the feel for what that means: huge collections of loosely coupled finite-state machines, all running in parallel, doing little bits of protocol validation here and there, but mostly staying dormant.</p></blockquote>
<p>英文的描述，如果写得好了，会有一种准确精妙难以言表的感觉，通常很难原汁原味的译为相对应的中文。不过，这句太经典，我还是想翻来看看。</p>
<blockquote><p>这篇文档所传达的要义(用 Erlang 构造系统的感觉)是：一大堆并行运行着的有限状态机，各处做一做协议验证，彼此松散耦合，通常大部分的有限状态机都处在休眠状态。</p></blockquote>
<p>作者提到他对这篇 “A History of Erlang” 中“有感觉”的几点是：</p>
<blockquote><li>First, there’s strong emphasis on easily tracking and manipulating the flow of control, rather than data.</li>
<li>Second, I enjoyed the explanation of one particular detail of Erlang: in the message-passing implementation, individual processes don’t handle messages immediately.</li>
<li>Third, Erlang is somewhat infamous for its distributed error handling mechanism.</li>
</blockquote>
<p>这只是起头，精妙在于剖析。任何一个设计决策都是有 trade off 的，对这些设计决策正反两面的分析，或许能够部分解释“为什么 Erlang 会这么怪异”，相当值得一读。</p>
<p>顺便说一句，我“有感觉”的一点是 “Erlang 天生就是以消息驱动模型来架构的系统” 而 “消息驱动的编程模型” 如何应用于互联网编程环境，正是值得我们深思的问题。</p>
]]></content:encoded>
			<wfw:commentRss>http://erlang-china.org/misc/commentary-on_a-history-of-erlang.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>用 SSH 来连接 Erlang Shell</title>
		<link>http://erlang-china.org/study/using_ssh_connect_the_erlang_shell.html</link>
		<comments>http://erlang-china.org/study/using_ssh_connect_the_erlang_shell.html#comments</comments>
		<pubDate>Fri, 06 Jun 2008 03:34:49 +0000</pubDate>
		<dc:creator>jackyz</dc:creator>
		
		<category><![CDATA[study]]></category>

		<guid isPermaLink="false">http://erlang-china.org/study/using_ssh_connect_the_erlang_shell.html</guid>
		<description><![CDATA[Erlang 的 SSH 支持 “很好很强大” ——可以让 Erlang 在 22 (或其他指定的)端口启动 Erlang 自己的 sshd ，然后，当你通过 Putty 之类的 ssh 客户端连上去时，就能直接得到 Erlang Shell 。很酷吧，更酷的是，这个功能完备的 Erlang Shell 已经支持了 Public-Key Authorization 以及 “One Password Rule Them All” 的 “超级密码” Authorization 。尤其对于那些需要伺候集群中 N 多台 Erlang 服务器的 “ IT 农场工人” ，这会是一个极度 “系统管理员友好” 的功能。那么，具体来说，整个步骤又是怎么样的呢？
下面是我们的前方记者从 “不明地带” 发回的 —— 现场 “流水帐”  。

第一回
启动：
1&#62; ssh_sshd:listen(9999).{ok,&#60;0.38.0&#62;}
连接：
$ ssh [...]]]></description>
			<content:encoded><![CDATA[<p>Erlang 的 SSH 支持 “很好很强大” ——可以让 Erlang 在 22 (或其他指定的)端口启动 Erlang 自己的 sshd ，然后，当你通过 Putty 之类的 ssh 客户端连上去时，就能直接得到 Erlang Shell 。很酷吧，更酷的是，这个功能完备的 Erlang Shell 已经支持了 Public-Key Authorization 以及 “One Password Rule Them All” 的 “超级密码” Authorization 。尤其对于那些需要伺候集群中 N 多台 Erlang 服务器的 “ IT 农场工人” ，这会是一个极度 “系统管理员友好” 的功能。那么，具体来说，整个步骤又是怎么样的呢？</p>
<p>下面是我们的前方记者从 “不明地带” 发回的 —— 现场 “流水帐” <img src='http://erlang-china.org/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> 。</p>
<p><span id="more-171"></span></p>
<p><strong>第一回</strong></p>
<p>启动：</p>
<div class="hl-surround"><div class="hl-main"><span style="color: Maroon;">1</span><span style="color: Gray;">&gt; </span><span style="color: Blue;">ssh_sshd</span><span style="color: Gray;">:</span><span style="color: Blue;">listen</span><span style="color: Olive;">(</span><span style="color: Maroon;">9999</span><span style="color: Olive;">)</span><span style="color: Gray;">.<br />{</span><span style="color: Blue;">ok</span><span style="color: Gray;">,&lt;</span><span style="color: Maroon;">0.38.0</span><span style="color: Gray;">&gt;}</span></div></div>
<p>连接：</p>
<div class="hl-surround"><div class="hl-main">$ ssh -o Port=9999 localhost</div></div>
<p>得到：</p>
<div class="hl-surround"><div class="hl-main"><span style="color: Maroon;">2</span><span style="color: Gray;">&gt;<br />=</span><span style="color: Blue;">ERROR</span><span style="color: Gray;"> </span><span style="color: Blue;">REPORT</span><span style="color: Gray;">==== </span><span style="color: Maroon;">6</span><span style="color: Gray;">-</span><span style="color: Blue;">Jun</span><span style="color: Gray;">-</span><span style="color: Maroon;">2008</span><span style="color: Gray;">::</span><span style="color: Maroon;">10</span><span style="color: Gray;">:</span><span style="color: Maroon;">39</span><span style="color: Gray;">:</span><span style="color: Maroon;">26</span><span style="color: Gray;"> ===<br /></span><span style="color: Blue;">Error</span><span style="color: Gray;"> </span><span style="color: Blue;">in</span><span style="color: Gray;"> </span><span style="color: Blue;">process</span><span style="color: Gray;"> &lt;</span><span style="color: Maroon;">0.39.0</span><span style="color: Gray;">&gt; </span><span style="color: Blue;">with</span><span style="color: Gray;"> </span><span style="color: Blue;">exit</span><span style="color: Gray;"> </span><span style="color: Blue;">value</span><span style="color: Gray;">: {</span><span style="color: Blue;">badarg</span><span style="color: Gray;">,</span><span style="color: Olive;">[</span><span style="color: Gray;">{</span><span style="color: Blue;">ets</span><span style="color: Gray;">,</span><span style="color: Blue;">lookup</span><span style="color: Gray;">,</span><span style="color: Olive;">[</span><span style="color: Blue;">crypto_server_table</span><span style="color: Gray;">,</span><span style="color: Blue;">port</span><span style="color: Olive;">]</span><span style="color: Gray;">},{</span><span style="color: Blue;">crypto</span><span style="color: Gray;">,</span><span style="color: Blue;">control</span><span style="color: Gray;">,</span><span style="color: Maroon;">2</span><span style="color: Gray;">},{</span><span style="color: Blue;">crypto</span><span style="color: Gray;">,</span><span style="color: Blue;">mod_exp</span><span style="color: Gray;">,</span><span style="color: Maroon;">3</span><span style="color: Gray;">},{</span><span style="color: Blue;">crypto</span><span style="color: Gray;">,</span><span style="color: Blue;">mod_exp</span><span style="color: Gray;">,</span><span style="color: Maroon;">3</span><span style="color: Gray;">},{</span><span style="color: Blue;">ssh_transport</span><span style="color: Gray;">,</span><span style="color: Blue;">dh_gen_key</span><span style="color: Gray;">,</span><span style="color: Maroon;">3</span><span style="color: Gray;">},{</span><span style="color: Blue;">ssh_transport</span><span style="color: Gray;">,</span><span style="color: Blue;">server_kex</span><span style="color: Gray;">,</span><span style="color: Maroon;">3</span><span style="color: Gray;">},{</span><span style="color: Blue;">ssh_transport</span><span style="color: Gray;">,</span><span style="color: Blue;">kex_negotiate</span><span style="color: Gray;">,</span><span style="color: Maroon;">8</span><span style="color: Gray;">}</span><span style="color: Olive;">]</span><span style="color: Gray;">}<br />...</span></div></div>
<p>看来和一个 crypto 啥的有关系。关门，放 google &#8230;&#8230;。原来 ssh 的加密体系依赖于 crypto app 需要先启动它。</p>
<p><strong>第二回</strong></p>
<p>启动：</p>
<div class="hl-surround"><div class="hl-main"><span style="color: Maroon;">1</span><span style="color: Gray;">&gt; </span><span style="color: Blue;">crypto</span><span style="color: Gray;">:</span><span style="color: Blue;">start</span><span style="color: Olive;">()</span><span style="color: Gray;">.<br /></span><span style="color: Blue;">ok</span><span style="color: Gray;"><br /></span><span style="color: Maroon;">2</span><span style="color: Gray;">&gt; </span><span style="color: Blue;">ssh_sshd</span><span style="color: Gray;">:</span><span style="color: Blue;">listen</span><span style="color: Olive;">(</span><span style="color: Maroon;">9999</span><span style="color: Olive;">)</span><span style="color: Gray;">.<br />{</span><span style="color: Blue;">ok</span><span style="color: Gray;">,&lt;</span><span style="color: Maroon;">0.41.0</span><span style="color: Gray;">&gt;}</span></div></div>
<p>连接：</p>
<div class="hl-surround"><div class="hl-main">$ ssh -o Port=9999 localhost</div></div>
<p>得到：</p>
<div class="hl-surround"><div class="hl-main"><span style="color: Maroon;">3</span><span style="color: Gray;">&gt;<br />=</span><span style="color: Blue;">ERROR</span><span style="color: Gray;"> </span><span style="color: Blue;">REPORT</span><span style="color: Gray;">==== </span><span style="color: Maroon;">6</span><span style="color: Gray;">-</span><span style="color: Blue;">Jun</span><span style="color: Gray;">-</span><span style="color: Maroon;">2008</span><span style="color: Gray;">::</span><span style="color: Maroon;">10</span><span style="color: Gray;">:</span><span style="color: Maroon;">47</span><span style="color: Gray;">:</span><span style="color: Maroon;">12</span><span style="color: Gray;"> ===<br />** </span><span style="color: Blue;">Generic</span><span style="color: Gray;"> </span><span style="color: Blue;">server</span><span style="color: Gray;"> &lt;</span><span style="color: Maroon;">0.45.0</span><span style="color: Gray;">&gt; </span><span style="color: Blue;">terminating</span><span style="color: Gray;"><br />** </span><span style="color: Blue;">Last</span><span style="color: Gray;"> </span><span style="color: Blue;">message</span><span style="color: Gray;"> </span><span style="color: Blue;">in</span><span style="color: Gray;"> </span><span style="color: Blue;">was</span><span style="color: Gray;"> {</span><span style="color: #8b0000;">'</span><span style="color: Red;">EXIT</span><span style="color: #8b0000;">'</span><span style="color: Gray;">,&lt;</span><span style="color: Maroon;">0.42.0</span><span style="color: Gray;">&gt;,{</span><span style="color: Blue;">error</span><span style="color: Gray;">,</span><span style="color: Blue;">eacces</span><span style="color: Gray;">}}<br />...</span></div></div>
<p>这个 eacces 貌似很可疑，关门，再放 google &#8230;&#8230;。原来 sshd 默认会访问 /etc/ssh 以获取 “host files that identifies the host for ssh” ，而 /etc/ssh 只有 root 能访问，当然是会失败的。必须加上一个 system_dir 参数指定一个新位置。</p>
<p><strong>第三回</strong></p>
<p>启动：</p>
<div class="hl-surround"><div class="hl-main"><span style="color: Maroon;">1</span><span style="color: Gray;">&gt; </span><span style="color: Blue;">crypto</span><span style="color: Gray;">:</span><span style="color: Blue;">start</span><span style="color: Olive;">()</span><span style="color: Gray;">.<br /></span><span style="color: Blue;">ok</span><span style="color: Gray;"><br /></span><span style="color: Maroon;">2</span><span style="color: Gray;">&gt; </span><span style="color: Blue;">ssh_sshd</span><span style="color: Gray;">:</span><span style="color: Blue;">listen</span><span style="color: Olive;">(</span><span style="color: Maroon;">9999</span><span style="color: Gray;">, </span><span style="color: Olive;">[</span><span style="color: Gray;">{</span><span style="color: Blue;">system_dir</span><span style="color: Gray;">, </span><span style="color: #8b0000;">&quot;</span><span style="color: Red;">.</span><span style="color: #8b0000;">&quot;</span><span style="color: Gray;">}</span><span style="color: Olive;">])</span><span style="color: Gray;">.<br />{</span><span style="color: Blue;">ok</span><span style="color: Gray;">,&lt;</span><span style="color: Maroon;">0.41.0</span><span style="color: Gray;">&gt;}</span></div></div>
<p>连接：</p>
<div class="hl-surround"><div class="hl-main">$ ssh -o Port=9999 localhost</div></div>
<p>得到：</p>
<div class="hl-surround"><div class="hl-main"><span style="color: Maroon;">3</span><span style="color: Gray;">&gt;<br />=</span><span style="color: Blue;">ERROR</span><span style="color: Gray;"> </span><span style="color: Blue;">REPORT</span><span style="color: Gray;">==== </span><span style="color: Maroon;">6</span><span style="color: Gray;">-</span><span style="color: Blue;">Jun</span><span style="color: Gray;">-</span><span style="color: Maroon;">2008</span><span style="color: Gray;">::</span><span style="color: Maroon;">10</span><span style="color: Gray;">:</span><span style="color: Maroon;">57</span><span style="color: Gray;">:</span><span style="color: Maroon;">10</span><span style="color: Gray;"> ===<br />** </span><span style="color: Blue;">Generic</span><span style="color: Gray;"> </span><span style="color: Blue;">server</span><span style="color: Gray;"> &lt;</span><span style="color: Maroon;">0.45.0</span><span style="color: Gray;">&gt; </span><span style="color: Blue;">terminating</span><span style="color: Gray;"><br />** </span><span style="color: Blue;">Last</span><span style="color: Gray;"> </span><span style="color: Blue;">message</span><span style="color: Gray;"> </span><span style="color: Blue;">in</span><span style="color: Gray;"> </span><span style="color: Blue;">was</span><span style="color: Gray;"> {</span><span style="color: #8b0000;">'</span><span style="color: Red;">EXIT</span><span style="color: #8b0000;">'</span><span style="color: Gray;">,&lt;</span><span style="color: Maroon;">0.42.0</span><span style="color: Gray;">&gt;,{</span><span style="color: Blue;">error</span><span style="color: Gray;">,</span><span style="color: Blue;">enoent</span><span style="color: Gray;">}}<br />...</span></div></div>
<p>enoent，想起来 “host files that identifies the host for ssh” 在 . 目录下根本没有，需要生成之。关门，又放 google &#8230;&#8230;。原来要如此这般的生成 ssh host 文件：</p>
<div class="hl-surround"><div class="hl-main">ssh-keygen -f ssh_host_rsa_key -t rsa -N ''<br />ssh-keygen -f ssh_host_dsa_key -t dsa -N ''</div></div>
<p>得到了 4 个 ssh_host_xxx 文件，分别对应 rsa 和 dsa 加密算法。</p>
<p><strong>第四回</strong></p>
<p>启动：</p>
<div class="hl-surround"><div class="hl-main"><span style="color: Maroon;">1</span><span style="color: Gray;">&gt; </span><span style="color: Blue;">crypto</span><span style="color: Gray;">:</span><span style="color: Blue;">start</span><span style="color: Olive;">()</span><span style="color: Gray;">.<br /></span><span style="color: Blue;">ok</span><span style="color: Gray;"><br /></span><span style="color: Maroon;">2</span><span style="color: Gray;">&gt; </span><span style="color: Blue;">ssh_sshd</span><span style="color: Gray;">:</span><span style="color: Blue;">listen</span><span style="color: Olive;">(</span><span style="color: Maroon;">9999</span><span style="color: Gray;">, </span><span style="color: Olive;">[</span><span style="color: Gray;">{</span><span style="color: Blue;">system_dir</span><span style="color: Gray;">, </span><span style="color: #8b0000;">&quot;</span><span style="color: Red;">.</span><span style="color: #8b0000;">&quot;</span><span style="color: Gray;">}</span><span style="color: Olive;">])</span><span style="color: Gray;">.<br />{</span><span style="color: Blue;">ok</span><span style="color: Gray;">,&lt;</span><span style="color: Maroon;">0.41.0</span><span style="color: Gray;">&gt;}</span></div></div>
<p>连接：</p>
<div class="hl-surround"><div class="hl-main">$ ssh -o Port=9999 localhost</div></div>
<p>得到：</p>
<div class="hl-surround"><div class="hl-main">The authenticity of host '[localhost]:9999 ([127.0.0.1]:9999)' can't be established.<br />DSA key fingerprint is 48:71:fa:f7:2b:b1:99:af:10:c7:ea:67:48:57:fa:68.<br />Are you sure you want to continue connecting (yes/no)? yes<br />Warning: Permanently added '[localhost]:9999' (DSA) to the list of known hosts.<br />Eshell V5.5.5&nbsp; (abort with ^G)<br />1&gt;</div></div>
<p>BINGO! 搞定！</p>
<p><strong>延伸问题</strong></p>
<p>上述方式启动的 ssh_sshd 仍然存在问题——当 q(). 退出 erlang shell in ssh 时，会让 ssh_sshd 退出，但同时也会报错。why？how to fix？</p>
<p>上述方式启动的 sshd 登录时，如何采用 public key 或者用户名/密码验证？</p>
<p>有兴趣了解的同学，自己做一下实验吧。</p>
<p>BTW. ssh application 目前正在 refactor 之中，有 OTP team 的 mail 为证：</p>
<blockquote><p>
Hi!</p>
<p>Thank you for reporting this and other issues in previous mails. We are in the process of refactoring the ssh-application and there is much room for improvement of the documentation, we will look over this.</p>
<p>Regards Ingela - Erlang/OTP, Ericsson
</p></blockquote>
<p>主要的 refactor 方向是（基于情报进行合理的大胆假设）：“更优雅的整和 ssh_sshd 和 ssh_sftpd 系统” 以及更 “customize 友好的架构” ，比如：ssh/sftp 连上去的不再是 erlang shell/real file system 而是一个 “定制的环境” 。ssh as a protocol (like http)? sounds great!</p>
]]></content:encoded>
			<wfw:commentRss>http://erlang-china.org/study/using_ssh_connect_the_erlang_shell.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>[荐] &#8220;RPC is bad&#8221; 续篇 —— joe 老爷爷如是说</title>
		<link>http://erlang-china.org/misc/rpc-is-bad_joe-post.html</link>
		<comments>http://erlang-china.org/misc/rpc-is-bad_joe-post.html#comments</comments>
		<pubDate>Tue, 27 May 2008 04:30:06 +0000</pubDate>
		<dc:creator>jackyz</dc:creator>
		
		<category><![CDATA[misc]]></category>

		<guid isPermaLink="false">http://erlang-china.org/misc/is_rpc_bad_joe_follow.html</guid>
		<description><![CDATA[继 Steve 大叔的 “RPC is bad” 开腔惊起娃声一片之后，Joe 老爷爷抓当前的大好形势又写了一篇“大字报”，“掀起了Erlang主义建设的新高潮”(第二声部唱：新高潮，新高潮)。不过，Joe 老爷爷的 Blog 建在 BlogSpot ，有“伟大的火墙”“护着”，我们可以免受这些“不良内容”的毒害，为方便大家学习，特将这篇文章盗版如下，供大家批判。(召唤翻译达人)：
]]></description>
			<content:encoded><![CDATA[<p>继 Steve 大叔的 “RPC is bad” 开腔惊起娃声一片之后，Joe 老爷爷抓当前的大好形势又写了一篇“大字报”，“掀起了Erlang主义建设的新高潮”(第二声部唱：新高潮，新高潮)。不过，<a href="http://armstrongonsoftware.blogspot.com/" target=_blank>Joe 老爷爷的 Blog</a> 建在 BlogSpot ，有“伟大的火墙”“护着”，我们可以免受这些“不良内容”的毒害，为方便大家学习，特将这篇文章盗版如下，供大家批判。(召唤翻译达人)：</p>
]]></content:encoded>
			<wfw:commentRss>http://erlang-china.org/misc/rpc-is-bad_joe-post.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>[荐]RPC is bad?</title>
		<link>http://erlang-china.org/misc/is_rpc_bad.html</link>
		<comments>http://erlang-china.org/misc/is_rpc_bad.html#comments</comments>
		<pubDate>Sat, 24 May 2008 02:54:19 +0000</pubDate>
		<dc:creator>jackyz</dc:creator>
		
		<category><![CDATA[misc]]></category>

		<guid isPermaLink="false">http://erlang-china.org/misc/is_rpc_bad.html</guid>
		<description><![CDATA[偶像 Steve Vinoski 在 maillist 的回帖中一不留神就泄漏了他为 ErlangeXchange 准备的 session ，我们可以先一睹为快。Steve 大拿是 CORBA 界的牛人，对 RPC 是 bad 很有发言权地。这篇文章也写得很漂亮，水分相当少，我就不干“损失味道”的事情了。
为方便阅读，将 mail 内容盗版如下：

Well, if you had time you could dig through my various IEEE Internet Computing columns from the past 6 years and find many reasons listed there. For example, &#8220;RPC Under Fire&#8220;(note that it&#8217;s PDF) from the Sep/Oct [...]]]></description>
			<content:encoded><![CDATA[<p>偶像 Steve Vinoski 在 maillist 的回帖中一不留神就泄漏了他为 ErlangeXchange 准备的 session ，我们可以先一睹为快。Steve 大拿是 CORBA 界的牛人，对 RPC 是 bad 很有发言权地。这篇文章也写得很漂亮，水分相当少，我就不干“损失味道”的事情了。</p>
<p>为方便阅读，将 mail 内容盗版如下：</p>
<p><span id="more-169"></span></p>
<p>Well, if you had time you could dig through my various IEEE Internet Computing columns from the past 6 years and find many reasons listed there. For example, &#8220;<a href="http://steve.vinoski.net/pdf/IEEE-RPC_Under_Fire.pdf" target=_blank>RPC Under Fire</a>&#8220;(note that it&#8217;s PDF) from the Sep/Oct 2005 lists a number of problems:</p>
<p>Also, pretty much any of my columns that cover REST to any degree would also contain mentions of RPC&#8217;s shortcomings. All the columns can be found <a href="http://steve.vinoski.net/blog/internet-computing-columns/" target=_blank>here</a>:</p>
<p>But if you don&#8217;t have the time or energy, the fundamental problem is that RPC tries to make a distributed invocation look like a local one. This can&#8217;t work because the failure modes in distributed systems are<br />
quite different from those in local systems, so you find yourself having to introduce more and more infrastructure that tries to hide all the hard details and problems that lurk beneath. That&#8217;s how we got<br />
Apollo NCS and Sun RPC and DCE and CORBA and DSOM and DCOM and EJB and SOAP and JAX-RPC, to name a few off the top of my head, each better than what came before in some ways but worse in other ways, especially footprint and complexity. But it&#8217;s all for naught because no amount of infrastructure can ever hide those problems of distribution. Network partitions are real, timeouts are real, remote host and service<br />
crashes are real, the need for piecemeal system upgrade and handling version differences between systems is real, etc. The distributed systems programmer *must* deal with these and other issues because<br />
they affect different applications very differently; no amount of hiding or abstraction can make these problems disappear. As I said about such systems in a recent column:</p>
<p>&#8220;The layers of complexity required to maintain the resulting leaky illusion of local/remote transparency are reminiscent of the convoluted equations that pre-Copernican astronomers used to explain how the Sun and other planets revolved around the Earth.&#8221; (from &#8220;<a href="http://dsonline.computer.org/portal/pages/dsonline/2008/02/w1tow.html" target=_blank>Serendipitous Reuse</a>&#8220;)</p>
<p>RPC systems in C++, Java, etc. also tend to introduce higher degrees of coupling than one would like in a distributed system. Typically you have some sort of IDL that&#8217;s used to generate stubs/proxies/skeletons<br />
&#8211; code that turns the local calls into remote ones, which nobody wants to write or maintain by hand. The IDL is often simple, but the generated code is usually not. That code is normally compiled into each app in the system. Change the IDL and you have to regenerate the code, recompile it, and then retest and redeploy your apps, and you typically have to do that atomically, either all apps or none, because versioning is not accounted for. In an already-deployed production system, it can be pretty hard to do atomic upgrades across the entire system. Overall, this approach makes for brittle, tightly-coupled systems.</p>
<p>Such systems also have problems with impedance mismatch between the IDL and whatever languages you&#8217;re translating it to. If the IDL is minimal so that it can be used with a wide variety of programming<br />
languages, it means advanced features of well-stocked languages like Java and C++ can&#8217;t be used. OTOH if you make the IDL more powerful so that it&#8217;s closer to such languages, then translating it to C or other<br />
more basic languages becomes quite difficult. On top of all that, no matter how you design the IDL type system, all the types won&#8217;t &#8212; indeed, can&#8217;t &#8212; map cleanly into every desired programming language. This turns into the need for non-idiomatic programming in one or more of the supported languages, and developers using those languages tend to complain about that. If you turn the whole process around by using a programming language like Java for your RPC IDL in an attempt to avoid the mismatch problems, you find it works only for that language, and that translating that language into other languages is quite difficult.</p>
<p>There&#8217;s also the need with these systems to have the same or similar infrastructure on both ends of the wire. Earlier posters to this thread complained about this, for example, when they mentioned having to have CORBA ORBs underneath all their participating applications. If you can&#8217;t get the exact same infrastructure under all endpoints, then you need to use interoperable infrastructure, which obviously relies on interoperability standards. These, unfortunately, are often problematic as well. CORBA interoperability, for example, eventually became pretty good, but it took about a decade. CORBA started out with<br />
no interoperability protocol at all (in fact, it originally specified no network protocol at all), and then we suffered with interop problems for a few years once IIOP came along and both the protocol itself and implementations of it matured.</p>
<p>Ultimately, RPC is a leaky abstraction. It can&#8217;t hide what it tries to hide, and because of that, it can easily make the overall problem more difficult to deal with by adding a lot of accidental complexity.</p>
<p>In my previous message I specifically mentioned Erlang as having gotten it right. I believe that to be true not only because the handling of distribution is effectively built in and dealt with directly, but also because Erlang makes no attempt to hide those hard problems from the developer. Rather, it makes them known to the<br />
developer by providing facilities for dealing with timeouts, failures, versioning, etc. I think what Erlang gives us goes a very long way and is well beyond anything I&#8217;ve experienced before. Erlang really doesn&#8217;t provide RPC according to the strict definition of the term, BTW, because remote calls don&#8217;t actually look like local ones.</p>
<p>(BTW, this is the kind of stuff I&#8217;ll be talking about at Erlang eXchange next month.)</p>
]]></content:encoded>
			<wfw:commentRss>http://erlang-china.org/misc/is_rpc_bad.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>Facebook chat 跟踪报导 —— comet with mochiweb</title>
		<link>http://erlang-china.org/misc/facebook_comet_in_mochiweb.html</link>
		<comments>http://erlang-china.org/misc/facebook_comet_in_mochiweb.html#comments</comments>
		<pubDate>Fri, 16 May 2008 02:19:27 +0000</pubDate>
		<dc:creator>jackyz</dc:creator>
		
		<category><![CDATA[misc]]></category>

		<guid isPermaLink="false">http://erlang-china.org/misc/facebook_comet_in_mochiweb.html</guid>
		<description><![CDATA[话说 facebook 推出了支持高并发的 web im 引起众“hacker”(与 linux hacker 中的 hacker 相同的那个词)的一片哗然，纷纷出手研究其秘密。互联网上迅速的出现了一批“拆解 facebook webim”的文章。这里就是其中相当有意思的一篇。其中的干货如下：
1 作者放出 firebug 发现，http header 的 server 字段赫然写着 MochiWeb/1.0 的字样。
2 作者开动脑筋，在 mochiweb 基础之上，写了一个“最简单”的 facebook webim 概念模型，mochi loop 的核心代码如下：
...'GET' -&#62;&#160; case Path of&#160;&#160; &#160;&#34;chat&#34; -&#62;&#160;&#160; &#160; &#160;% 1) subscribing&#160;&#160; &#160; &#160;Room ! {self(), subscribe},&#160;&#160; &#160; &#160;% 2) waiting&#160;&#160; &#160; &#160;receive&#160;&#160; &#160; &#160; &#160;Message -&#62;&#160;&#160; [...]]]></description>
			<content:encoded><![CDATA[<p>话说 facebook 推出了支持高并发的 web im 引起众“hacker”(与 linux hacker 中的 hacker 相同的那个词)的一片哗然，纷纷出手研究其秘密。互联网上迅速的出现了一批“拆解 facebook webim”的文章。<a href="http://yoan.dosimple.ch/blog/2008/05/15/" target=_blank>这里</a>就是其中相当有意思的一篇。其中的干货如下：</p>
<p>1 作者放出 firebug 发现，http header 的 server 字段赫然写着 MochiWeb/1.0 的字样。</p>
<p>2 作者开动脑筋，在 mochiweb 基础之上，写了一个“最简单”的 facebook webim 概念模型，mochi loop 的核心代码如下：</p>
<div class="hl-surround"><div class="hl-main"><span style="color: Gray;">...<br /></span><span style="color: #8b0000;">'</span><span style="color: Red;">GET</span><span style="color: #8b0000;">'</span><span style="color: Gray;"> -&gt;<br />&nbsp; </span><span style="color: Green;">case</span><span style="color: Gray;"> </span><span style="color: Blue;">Path</span><span style="color: Gray;"> </span><span style="color: Green;">of</span><span style="color: Gray;"><br />&nbsp;&nbsp; &nbsp;</span><span style="color: #8b0000;">&quot;</span><span style="color: Red;">chat</span><span style="color: #8b0000;">&quot;</span><span style="color: Gray;"> -&gt;<br />&nbsp;&nbsp; &nbsp; &nbsp;</span><span style="color: #ffa500;">% 1) subscribing</span><span style="color: Gray;"><br />&nbsp;&nbsp; &nbsp; &nbsp;</span><span style="color: Blue;">Room</span><span style="color: Gray;"> ! {</span><span style="color: Blue;">self</span><span style="color: Olive;">()</span><span style="color: Gray;">, </span><span style="color: Blue;">subscribe</span><span style="color: Gray;">},<br />&nbsp;&nbsp; &nbsp; &nbsp;</span><span style="color: #ffa500;">% 2) waiting</span><span style="color: Gray;"><br />&nbsp;&nbsp; &nbsp; &nbsp;</span><span style="color: Green;">receive</span><span style="color: Gray;"><br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;</span><span style="color: Blue;">Message</span><span style="color: Gray;"> -&gt;<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span style="color: #ffa500;">% 3) everything went right</span><span style="color: Gray;"><br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span style="color: Blue;">Req</span><span style="color: Gray;">:</span><span style="color: Blue;">ok</span><span style="color: Olive;">(</span><span style="color: Gray;">{</span><span style="color: #8b0000;">&quot;</span><span style="color: Red;">text/plain</span><span style="color: #8b0000;">&quot;</span><span style="color: Gray;">, </span><span style="color: Blue;">Message</span><span style="color: Gray;">}</span><span style="color: Olive;">)</span><span style="color: Gray;"><br />&nbsp;&nbsp; &nbsp; &nbsp;</span><span style="color: Blue;">after</span><span style="color: Gray;"> </span><span style="color: Maroon;">10000</span><span style="color: Gray;"><br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;</span><span style="color: #ffa500;">% 4) oOops, too long buddy.</span><span style="color: Gray;"><br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;</span><span style="color: Blue;">room</span><span style="color: Gray;"> ! {</span><span style="color: Blue;">self</span><span style="color: Olive;">()</span><span style="color: Gray;">, </span><span style="color: Blue;">unsubscribe</span><span style="color: Gray;">},<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;</span><span style="color: Blue;">Req</span><span style="color: Gray;">:</span><span style="color: Blue;">not_found</span><span style="color: Olive;">()</span><span style="color: Gray;"><br />&nbsp;&nbsp; &nbsp;</span><span style="color: Green;">end</span><span style="color: Gray;">;<br />...</span></div></div>
<p>简而言之就是：在 browser 和 mochiweb 之间保持 10 秒的长连接，这(10s的)期间收到的任何消息都会即时发送给 browser ，然后再由 browser 内的代码再次发起下一个连接。作者提供了完整例子代码的下载。PS.关于这一实现方式的更多说明也可以参考拙作“<a href="http://erlang-china.org/misc/server-push-the-google-way.html" target=_blank>the google way</a>”。</p>
<p>当然这只是一个“概念模型”，距离“实用价值”仍有一段距离。比如：这个 web 层如何与 ejabberd 接起来，如何识别同一个用户，如何增加更多的“聊天逻辑”。</p>
<p>有兴趣(有时间)深入研究的读者可以移步<a href="http://yoan.dosimple.ch/blog/2008/05/15/" target=_blank>阅读原文</a>。如果看不到原文，请留言，以便“进行盗版”。</p>
]]></content:encoded>
			<wfw:commentRss>http://erlang-china.org/misc/facebook_comet_in_mochiweb.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>Facebook 的 Erlang 加持</title>
		<link>http://erlang-china.org/misc/facebook_erlang_enchantment.html</link>
		<comments>http://erlang-china.org/misc/facebook_erlang_enchantment.html#comments</comments>
		<pubDate>Thu, 15 May 2008 03:54:40 +0000</pubDate>
		<dc:creator>jackyz</dc:creator>
		
		<category><![CDATA[misc]]></category>

		<guid isPermaLink="false">http://erlang-china.org/misc/facebook_erlang_enpower.html</guid>
		<description><![CDATA[这篇消息的两个要点是：
1. Facebook 总算推出了 developer&#8217;s blog，在大家都推出自己的“开发者博”之后。
2. 这个“facebook 开发者博”透出来的第一条消息是——纯正 PHP/LAMP 血统的 Facebook 在高度 realtime 的 Chat 应用中，终于用了 Erlang 来提高性能( ejarbberd backend? 估计是 process-one 的那帮法国人最近一直都在搞的定制项目 )，我知道他迟早都会要用的。
如果觉得“干货”不过瘾，时间充裕的朋友可以移步阅读更“ juicy ”的原文—— 《Real-World Erlang Applications - Scaling Facebook Chat to 70 Million Active Users Almost Overnight》。
PS. 这篇 blog 亦可看作是《challenges of scaling up a realtime application》，所以，如果有人花时间将其 i8n 一下，那将会非常棒。
update 20080516：有人说打不开，那就“被迫盗版”一下吧。[节约版面起见，请点“继续阅读”]

Facebook Chat

by Eugene Letuchy Tuesday, [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.facebook.com/notes.php?id=9445547199" target=_blank>这篇消息</a>的两个要点是：</p>
<p>1. Facebook 总算推出了 <a href="http://www.facebook.com/notes.php?id=9445547199" target=_blank>developer&#8217;s blog</a>，在大家都推出自己的“开发者博”之后。<br />
2. 这个“facebook 开发者博”透出来的第一条消息是——纯正 PHP/LAMP 血统的 Facebook 在高度 realtime 的 Chat 应用中，终于用了 Erlang 来提高性能( ejarbberd backend? 估计是 process-one 的那帮法国人最近一直都在搞的定制项目 )，我知道他迟早都会要用的。</p>
<p>如果觉得“干货”不过瘾，时间充裕的朋友可以移步阅读更“ juicy ”的原文—— 《<a href="http://www.facebook.com/notes.php?id=9445547199" target=_blank>Real-World Erlang Applications - Scaling Facebook Chat to 70 Million Active Users Almost Overnight</a>》。</p>
<p>PS. 这篇 blog 亦可看作是《challenges of scaling up a realtime application》，所以，如果有人花时间将其 i8n 一下，那将会非常棒。</p>
<p>update 20080516：有人说打不开，那就“被迫盗版”一下吧。[节约版面起见，请点“继续阅读”]</p>
<p><span id="more-167"></span></p>
<h1>Facebook Chat</h1>
<p></p>
<p>by <span>Eugene Letuchy</span></span> Tuesday, May 13, 2008 at 10:56pm</p>
<p>One of the things I like most about working at Facebook is the ability to launch products that are (almost) immediately used by millions of people. Unlike a three-guys-in-a-garage startup, we don&#8217;t have the luxury of scaling out infrastructure to keep pace with user growth; when your feature&#8217;s userbase will go from 0 to 70 million practically overnight, scalability has to be baked in from the start. The project I&#8217;m currently working on, Facebook Chat, offered a nice set of software engineering challenges:</p>
<h1>Real-time presence notification:</h1>
<p></p>
<p>The most resource-intensive operation performed in a chat system is not sending messages. It is rather keeping each online user aware of the online-idle-offline states of their friends, so that conversations can begin.</p>
<p>The naive implementation of sending a notification to all friends whenever a user comes online or goes offline has a worst case cost of O(average friendlist size * peak users * churn rate) messages/second, where churn rate is the frequency with which users come online and go offline, in events/second. This is wildly inefficient to the point of being untenable, given that the average number of friends per user is measured in the hundreds, and the number of concurrent users during peak site usage is on the order of several millions.</p>
<p>Surfacing connected users&#8217; idleness greatly enhances the chat user experience but further compounds the problem of keeping presence information up-to-date. Each Facebook Chat user now needs to be notified whenever one of his/her friends <br />
  (a) takes an action such as sending a chat message or loads a Facebook page (if tracking idleness via a last-active timestamp) or <br />
  (b) transitions between idleness states (if representing idleness as a state machine with states like &#8220;idle-for-1-minute&#8221;, &#8220;idle-for-2-minutes&#8221;, &#8220;idle-for-5-minutes&#8221;, &#8220;idle-for-10-minutes&#8221;, etc.). <br />
Note that approach (a) changes the sending a chat message / loading a Facebook page from a one-to-one communication into a multicast to all online friends, while approach (b) ensures that users who are neither chatting nor browsing Facebook are nonetheless generating server load.</p>
<h1>Real-time messaging:</h1>
<p></p>
<p>Another challenge is ensuring the timely delivery of the messages themselves. The method we chose to get text from one user to another involves loading an iframe on each Facebook page, and having that iframe&#8217;s Javascript make an HTTP GET request over a persistent connection that doesn&#8217;t return until the server has data for the client. The request gets reestablished if it&#8217;s interrupted or times out. This isn&#8217;t by any means a new technique: it&#8217;s a variation of <a href="http://en.wikipedia.org/wiki/Comet_(programming)" target="_blank" title="http://en.wikipedia.org/wiki/Comet_(programming)">Comet</a>, specifically <a href="http://en.wikipedia.org/wiki/Comet_(programming)#XHR_long_polling" target="_blank" title="http://en.wikipedia.org/wiki/Comet_(programming)#XHR_long_polling">XHR long polling</a>, and/or <a href="http://www.xmpp.org/extensions/xep-0124.html#technique" target="_blank" title="http://www.xmpp.org/extensions/xep-0124.html#technique">BOSH</a>.</p>
<p>Having a large-number of long-running concurrent requests makes the <b>A</b>pache part of the standard LAMP stack a dubious implementation choice. Even without accounting for the sizeable overhead of spawning an OS process that, on average, twiddles its thumbs for a minute before reporting that no one has sent the user a message, the waiting time could be spent servicing 60-some requests for regular Facebook pages. The result of running out of Apache processes over the entire Facebook web tier is not pretty, nor is the dynamic configuration of the Apache process limits enjoyable.</p>
<h1>Distribution, Isolation, and Failover:</h1>
<p></p>
<p>Fault tolerance is a desirable characteristic of any big system: if an error happens, the system should try its best to recover without human intervention before giving up and informing the user. The results of inevitable programming bugs, hardware failures, et al., should be hidden from the user as much as possible and isolated from the rest of the system.</p>
<p>The way this is typically accomplished in a web application is by separating the model and the view: data is persisted in a database (perhaps with a separate in-memory cache), with each short-lived request retrieving only the parts relevant to that request. Because the data is persisted, a failed read request can be re-attempted. Cache misses and database failure can be detected by the non-database layers and either reported to the user or worked around using replication.</p>
<p>While this architecture works pretty well in general, it isn&#8217;t as successful in a chat application due to the high volume of long-lived requests, the non-relational nature of the data involved, and the statefulness of each request.</p>
<p>For Facebook Chat, we rolled our own subsystem for logging chat messages (in C++) as well as an epoll-driven web server (in Erlang) that holds online users&#8217; conversations in-memory and serves the long-polled HTTP requests. Both subsystems are clustered and partitioned for reliability and efficient failover. Why Erlang? In short, because the problem domain fits Erlang like a glove. Erlang is a functional concurrency-oriented language with extremely low-weight user-space &#8220;processes&#8221;, share-nothing message-passing semantics, built-in distribution, and a &#8220;crash and recover&#8221; philosophy proven by two decades of deployment on large soft-realtime production systems.</p>
<h1>Glueing with Thrift:</h1>
<p></p>
<p>Despite those advantages, using Erlang for a component of Facebook Chat had a downside: that component needed to communicate with the other parts of the system. Glueing together PHP, Javascript, Erlang, and C++ is not a trivial matter. Fortunately, we have <a href="http://developers.facebook.com/thrift/" target="_blank" title="http://developers.facebook.com/thrift/">Thrift</a>. Thrift translates a service description into the RPC glue code necessary for making cross-language calls (marshalling arguments and responses over the wire) and has templates for servers and clients. Since going open source a year ago (we had the gall to release it on April Fool&#8217;s Day, 2007), the Thrift project has steadily grown and improved (with multiple iterations on the Erlang binding). Having Thrift available freed us to split up the problem of building a chat system and use the best available tool to approach each sub-problem. </p>
<h1>Ramping up:</h1>
<p></p>
<p>The secret for going from zero to seventy million users overnight is to avoid doing it all in one fell swoop. We chose to simulate the impact of many real users hitting many machines by means of a &#8220;dark launch&#8221; period in which Facebook pages would make connections to the chat servers, query for presence information and simulate message sends without a single UI element drawn on the page. With the &#8220;dark launch&#8221; bugs fixed, we hope that you enjoy Facebook Chat now that the UI lights have been turned on.</p>
<p><i> Eugene is a Facebook Engineer </i></p>
]]></content:encoded>
			<wfw:commentRss>http://erlang-china.org/misc/facebook_erlang_enchantment.html/feed</wfw:commentRss>
		</item>
	</channel>
</rss>
