Erlang 与 Web 开发

来源:互联网 发布:软件规模大小 编辑:程序博客网 时间:2024/06/11 01:09

Erlang 语言的很多特性,决定了它开发服务器端(Server)的程序极其地方便,故此,基于 Erlang的各种服务应用正雨后春笋般涌现。这里我们就大家最熟悉的 Web 开发展开话题。考虑到 Erlang并不广为人知,这里以脱盲为主,如果某个话题引起你的兴趣,建议你参考相关文档继续深入下去。有任何希望讨论的地方,可以在 erlang-china或 ecug 这两个 google groups 中讨论。本文重点介绍的是 Yaws 和 MochiWeb,其他内容做概要介绍。

Erlang

编译与安装

  • 下载 Erlang
wget http://erlang.org/download/otp_src_R12B-2.tar.gz
  • 安装 bison, flex, openssl, ncurses
sudo apt-get install bison
sudo apt-get install flex
sudo apt-get install libssl-dev
sudo apt-get install ncurses-dev

  • 编译 erlang/otp
tar zxvf otp_src_R12B-2.tar.gz
cd otp_src_R12B-2
./configure
sudo make install

Inets httpd

之所以首先介绍 Inets httpd 服务器,是因为这是 Erlang OTP 自带的 Web Server。我们知道 ErlangOTP 是一个平台,而不止是一个语言。它带有很多管理用的小工具,多数情况下这些工具以 Web 方式提供。而这些工具通常是基于 Inetshttpd 的。

用Inets httpd你会觉得和Apache有点象。确实如此。我曾经写了一篇文章介绍 Inets httpd,这里不在重复,欲了解请参阅:http://erlana.googlecode.com/svn/trunk/doc/Erlang%20Inets/。

Yaws

Yaws(http://yaws.hyber.org/)是目前通用 Erlang Web Server 中最为名声显赫的一个,也是文档最为丰富的一个。Yaws 本身带的文档和样例都很详细,我这里另辟蹊径,将Yaws 和我们通常所说的 LAMP (Linux + Apache + MySQL + PHP)作为比照,来一个 LYMP (Linux +Yaws + MySQL + PHP)开发。

需要说明的是,LYMP 并不是 Yaws 最为推崇的开发模式,只是因为它是大家最为熟悉的一条路子。其实 Yaws 本身和 Inetshttpd 一样的思路,它倾向于一切都使用 Erlang 语言,即 LYME(Linux + Yaws + Mnesia +ErlScript)开发:用 Yaws 做 Web Server,用 Erlang Script(*.yaws)写页面,用 Mnesia来做数据存储。LYME 虽然和 LYMP 只差一个字母,但是此 M 非彼 M,两者大相径庭。

编译与安装

  • 下载 yaws, openpam
wget http://yaws.hyber.org/download/yaws-1.77.tar.gz
wget http://nchc.dl.sourceforge.net/sourceforge/openpam/openpam-20071221.tar.gz

  • 编译/安装 openpam
tar zxvf openpam-20071221.tar.gz
cd openpam-20071221
./configure
sudo make install

  • 编译/安装 yaws
tar zxvf yaws-1.77.tar.gz
cd yaws-1.77
vi c_src/epam.c,修改其中的 #include <pam_appl.h> 为 #include <security/pam_appl.h>
./configure
sudo make install

Yaws + PHP

  • 安装php cgi
sudo apt-get install php5-cgi
  • 修改Yaws配置(sudo vi /usr/local/etc/yaws.conf)
php_exe_path = /usr/bin/php-cgi     #加入这行,为了让yaws找到php
...
<server xxxx>
port = 80
listen = 0.0.0.0
allowed_scripts = php yaws cgi #加入这行,以便在该虚拟主机(server)中启用php cgi
....
</server>

  • 测试PHP支持:在 /usr/local/var/yaws/www 目录下,创建 test.php,内容如下:
<?php
echo "Hello, PHP!/n";
?>
  • 启动Yaws(命令行:sudo yaws -i),然后在浏览器地址栏输入 http://127.0.0.1/test.php,如果显示"Hello,PHP",那么恭喜你,你已经可以在 Yaws 这个Web服务器下写 PHP 了。

LYMP: Linux + Yaws + MySQL + PHP

有了PHP的支持,剩下来的问题可能是数据库(Database)了。但其实这个问题和Yaws关系不大。只要你安装了MySQL,并且PHP安装了MySQL扩展,就可以用 LYMP 进行 Web 开发了。

LYME v.s. LYMP

LYMP 优势:和大家熟悉的 LAMP 最接近,而且可以无缝切换。Web Server 是 Yaws,还是 Apache,或者是甚至是IIS? 基本不会对我们的开发产生太多的影响。而劣势是,Erlang 的优势在这里的体现并不明朗。因为一般 Web服务器的瓶颈主要在数据库(Database)上,前端的 Web Server 就算有瓶颈,一般也用负载均衡(LB)搞定,看起来不需要动用Erlang。

LYME优势:压力最重的数据库使用 Mnesia 这个分布式数据库来降低成为热点的可能性(当然具体还是会取决于你的设计)。而劣势是,对传统的 Web 开发人员而言,所有的东西都是新的,学习的成本过高。

ErlyWeb

ErlyWeb(http://code.google.com/p/erlyweb/)基于 Yaws,但是它倾向于 Linux + Yaws + MySQL + ErlTL 开发。也就是说,数据库用传统的 MySQL,其他用Erlang 进行开发。ErlyWeb 的作者对 Erlang 的兴致很高,主导了多个 Erlang 开源项目。而最引入瞩目的一个,可能要算twoorl (http://code.google.com/p/twoorl/): 它是一个开源的仿 Twitter 程序,并且是一个很好的基于 ErlyWeb 的样例。

MochiWeb

MochiWeb 是 MochiBot.com 公司的 Bob Ippolito 贡献的开源项目。 MochiBot.com 提供Flash 内容的访问统计和用户跟踪服务(你可以理解为这是针对 Flash 的 Google Analytics 服务),它们在MochiWeb 之上构建了一个定制化的 Web Server,并通过这个 Web Server 获取用户的访问数据(在这一点上有点象我发起的Erlana 项目)。由于 Analytics 服务的特殊性,你可以想象,这个 Web Server 需要很高的并发支持。 MochiWeb因此应运而生。 它针对的不是大家普遍意义上理解的 Web 开发。和传统的 LAMP 很不一样,你甚至可以不把它看作一个 WebServer,因为它几乎没有任何 Web 开发所有常用的基础设施。

但是 MochiWeb 最大卖点是非常轻量(高并发)而灵巧(易于定制),在特殊的场景下非常有用。目前 MochiWeb 已知的或者可以预见的应用包括:

  • Facebook 的 Web Chat(http://yoan.dosimple.ch/blog/2008/05/15/)
  • CouchDB(http://www.javaeye.com/news/459)
  • Erlana: Web Analytics服务(http://code.google.com/p/erlana/)
  • XXX Open Web API(RESTful): 为了提供Web API,你没有必要为此搭建一个通常意义的 Web Server。

Comet Programming: Web Chat

Comet 是一项很时髦的技术。其目的很简单:由于历史原因,目前 HTTP 协议信息都是客户端向服务器要(Poll),服务器没有办法推送信息给客户端(Sever Push)。这在实现某些应用的时候就会遇到麻烦。例如:

  • 当邮件服务器收到新的邮件时,及时报告给用户,如果他在线的话(GMail 这样做了)
  • 当 Web Chat 服务器收到新的信息时,及时发送信息到相应的在线用户(Web Chat 的基本需求)。
  • 聊天时提示你对方正在输入(时下 IM 客户端很时髦的一个功能)。

这里让我们假想要做一个 Web Chat。一个最笨的方法,就是客户端隔一段时间就向服务器请求(Request)一次,看看有没有新的信息,如果有则取回新信息,没有那么这次的请求就浪费了。这个方法无端增加了网络流量和服务器的负荷,显然并不可取。

那么 Comet 是如何做的呢? 有两种实现方式,一种叫 Streaming,一种叫 LongPolling。这里我们介绍后者。简单来说,Long Polling就是客户在初始化的时候向服务器发送一个请求(建立连接),该请求到服务器那里后被阻塞,直到有事件发生后才返回,客户端在获得事件并处理后,再重新建立一个新连接,如此反复。由于请求在没有事件的时候并不马上返回,这就大大减少了网络流量。当然这里有个细节,就是超时处理。因为现在路由器和防火墙都会自动断开时间比较长的连接。关于 Comet 技术更多的消息,可以参阅 http://cometdaily.com/。

Comet 技术对服务端的要求还是很高的,Long Polling减少了网络流量,但是服务端的连接数并没有减少。因此基于 Comet的应用,很容易在 Scale(伸缩性)上出现问题。使用 Erlang + MochiWeb,还是很好的利用了 Erlang可以轻松建立大量连接这个特性。需要指出的是,很可能 Comet 应用的时髦,将会很大程度上促进了业界对 Erlang 的关注。

基于 Erlang 的 Web Chat,Facebook 做了一个。这里有网上某人对 Facebook 之 Web Chat 的“模仿版”。研究这个 Web Chat,你将更清晰如何进行 Comet 编程:

下载并编译MochiWeb

svn co http://mochiweb.googlecode.com/svn/trunk mochiweb   #取得mochiweb源码
cd mochiweb
make
MOCHIWEB=`pwd`

Minimal Web Chat

wget http://yoan.dosimple.ch/blog/2008/05/15/chat.tgz
tar zxvf chat.tgz
cd chat/deps
ln -s -f $MOCHIWEB mochiweb-src
cd ..
make
./start.sh

这样,在 http://localhost:8000/ 就启动了一个 WebChat Server。你可以从多台机器连接该 Server进行聊天。

Template Engine for Erlang

虽然 Erlang 和传统的 Web 开发模式是可以结合的(如上面的 LYMP),但是多数基于 Erlang的开发似乎并不打算这样做。既然已经用了 Erlang,一个纯的 Erlang 应用也许是个更不错的主意。但是既然倾向于用 Erlang 取代PHP/JSP 来作为脚本引擎,那么基于 Erlang 的 Template Engine(模板引擎)就少不了了。目前基于 Erlang的主要 Template Engine 如下:

  • ErlTL(http://code.google.com/p/erlyweb/):是 ErlyWeb 作者专门为 Erlang Web 开发制作的模板引擎。
  • ErlyDTL(http://code.google.com/p/erlydtl/):基于著名的 Django Template Language(Python)的 Erlang 移植版。
  • sgte(http://code.google.com/p/sgte/):基于 StringTemplate(Java)的 Erlang 移植版。
  • Yaws ErlScript(http://yaws.hyber.org/):该模板引擎没有正式命名,姑且称之为Yaws ErlScript。类似 PHP,一个正常的 HTML 页面是一个合法的 Yaws ErlScript 文件。它通过在正常 HTML 中接入特殊标签,然后插 Erlang 脚本代码实现动态页面。