前言
Preface
我建立的第一个Web应用是Terrania,访问者可以在网站上创建一个定制的虚拟生物,然后在一个虚拟的世界中跟踪这个生物的成长过程。它会四处游荡,吃些植物(或其他动物)打打仗,或与其他玩家的生物交配。系统汇总生物当天发生的事件,每天两次通过电子邮件发送给玩家。
称之为Web应用可能有些过了,当然,我当时也不会把它这样分类。游戏的核心部分用C++编写,运行在单个机器上,从单个文件加载游戏数据,处理游戏林林总总的事,并将一切再保存到单个文本文件中。当我开始构建这个游戏时,运行时肯定是要成为C/S游戏架构的服务器端的。当时的网络编程中,数据交换非常困难,仅仅为了在服务器与客户端之间交换字符串就需要编写大量的机械代码(当时还没有.NET)。
Web给应用程序开发人员提供了一个随时可用的平台,该平台可以在网络上传输数据,避免了C/S应用程序的麻烦部分。我们可以按自己喜欢的方式建立服务器,让它完成有趣的工作,而使用简单的HTML建立客户端,可以完成相对来说比较琐碎的工作。Terrania中传统意义上属于客户端的部分现在被移到了服务器端,只需简单地访问原服务器端使用的文本文件。对于“客户端”程序的大部分页面,我们只需将文件加载到内存,解析出这个玩家感兴趣的生物,然后以HTML形式展现一些静态信息。创建一个新的生物只要将一块数据添加到下一个文件的末尾即可,服务器每次运行时,都会读取这个文件,并进行处理,将新生物添加到游戏中。所有的游戏处理逻辑,包括汇报成长状态的电子邮件,都是由服务器组件完成的。Web服务器的“客户端”接口只是简单的C++ CGI应用程序,它用几百行的源代码就可以解析游戏数据文件了。
这个系统是相当令人满意的,或许由于当时没有遇到什么问题,所以我没有注意到其局限性。一般来说Web接口会缺乏互动性,但对这个系统,它没造成什么大问题,因为这本就是游戏设计时考虑过的问题。惟一要由玩家进行写操作的就是创建生物的初始部分,之后的游戏对玩家而言就是只读的。另一个没有遇到的问题是并发性。由于Terrania是大型的只读游戏,可能有任意数目的玩家同时生成页面。所有这些写操作都是简单的文件附加操作,比较迅速,因而不会造成长时间轮询等待加锁的情况。此外,游戏玩家也不会多到两个玩家同时读或写。
过了一些年,我才有机会进行一些更加类似于Web应用程序开发的工作。我在一家新媒体办事处工作时被要求修改一个留言板产生的一些HTML输出,该留言板使用了UBB(Ultimate Bulletin Board来自Groupee, Inc.)技术。UBB用Perl编写,以CGI方式运行。应用程序数据条目,如用户账户,以及组成讨论的消息,都以定制格式存储在文本文件中。这个应用程序中的一些网页是动态的,从使用中的文本文件读取数据进行创建。其他页面,如讨论本身,还是文本格式的HTML文件,在需要时由应用程序写入磁盘。这种“写入磁盘”的技巧目前仍然在一些需要低写入/高读取的应用中使用,比如说博客,对它而言,动态产生被读取页面的成本高于将文件写入磁盘的成本(和读相比,写操作可是非常慢的操作)。
UBB的出彩之处在于它是用“脚本”语言Perl写的。源代码无需编译,这大大加快了开发周期,能够更加容易地进行修订,而不用每次修改就得花好多天。它的源代码被组织成三个主要文件:用户实际请求的终端脚本和两个类文件,类文件中包含了工具类函数(并被认真地命名为ubb_library.pl和ubb_library2.pl)。
我为几个商业客户服务时使用了UBB并得到一些相关的经验之后,较深入地参与了留言板“黑客”团体——他们是一群奇怪的人,花费时间来为现有的留言板软件添砖加瓦。我和另一个人建立了一个叫做UBB Hackers的站点,他后来成为Infopop的程序员,并编写了下一个版本的UBB。
早期的UBB并行能力很差,因为它依赖不可移植的文件加锁代码,而这些代码无法在Windows上工作(它也是目标平台之一)。如果两个用户同时回复同一个线程,该线程的数据文件就可能会损坏,并会导致数据丢失。随着系统用户数目的增加,数据损坏和竞争条件的几率也随之增加。对于真正活跃的系统,向磁盘写入HTML文件的操作很快会在文件I/O方面导致瓶颈。从现在的眼光来看,下一步该如何做是显然的,但当时可不是如此。
MySQL 3为Web应用程序带来很多变化。在有MySQL之前,使用数据库来存放Web应用程序的数据可不容易。当时可用的数据库技术如果不是非常昂贵(Oracle),就是缓慢而难以使用(FileMaker),或者就是配置和维护复杂得让人难以置信(Postgre SQL)。MySQL 3可用之后,事情逐渐发生了变化。PHP 4得到广泛接受, phpMyAdmin项目也启动了。phpMyAdmin意味着Web应用程序开发者不需要FileMaker的可视化设计工具,也不需要学习那些从命令行界面进行控制所需的晦涩的SQL语法,便可以开始使用数据库。即使到现在,我也记不起创建一个表格或者给予一个新用户访问权限的正确语法,但我已不需要记这些东西了。
MySQL为开发者带来并发的能力,让我们可以同时读数据和写数据,而不会无意中损坏数据。随着MySQL的发展,我们将能得到更高的并行能力和更好的性能,远远超出文本文件和写磁盘技术所能达到的极限。通过索引技术,我们可以选出任意的集合数据,并随心所欲地加以排序,而不用把这些数据全部加载到内存中和遍历相应数据结构。
当前的Web应用程序还在不断挑战现有的极限,这个目标可以通过所谓的扩展性、功能性和互操作性达成。随着公有API的激增,组合多个程序以创建新服务的能力带来了面向服务的风尚。API服务模型清晰地向我们展现了该如何设计应用程序的体系结构,以获得灵活性和低成本。
当前最大也是最受欢迎的Web应用程序,比如Flickr、Friendster、MySpace和Wikipedia,每天处理数十亿的数据库查询,有超大的数据集合,并且运行在由经济型的硬件设备组成的大型硬件平台之上。Google可算作超大型应用程序中的骄子,而其他相对较小(实际上还是规模巨大)的应用程序正在成为下一代应用程序的标杆,被打上了Web 2.0的标签。随着读/写交互性的增加网络能力的提高以及开发式的API,下一代的Web应用程序开发将会是非常有趣的。
这本书讲什么
What This Book Is About
本书主要内容是Web应用程序设计:对Web应用程序的软件和硬件系统的设计。我们会讨论程序体系结构、开发实践、技术、Unicode和通用的基础性的工作。书中同等重要的是Web应用程序的开发:建立硬件平台的实践和实现我们所设计的软件系统。尽管应用程序设计的原理很好(也是整个过程的基础部分),但还是要认识到在构建大型应用程序的过程中实现扮演着非常重要的角色,而且要在设计过程中时刻牢记这一点。如果是在设计一些无法构建的对象,那么就无从判断设计是否正确。
本书并不是关于编程的,至少不完全是。和讨论代码片段、函数名称等相比,实际的重点在于探讨构建Web应用程序所需的通用技术和方法。虽然本书确实包含了一些示例代码片段,但他们也仅仅是示例而已。书中大多数示例代码都只能在更大的应用程序中或者在底层框架中使用。
将要探讨的很多内容都和设计应用程序体系结构和构建应用程序的底层框架有关。在Web应用程序领域,底层框架大多是指硬件平台、软件平台、维护和开发实践的组合。我们会考虑如何将它们整合在一起为大型应用程序构建一个无缝的底层框架。
本书中最长的章节(第9章)只谈和应用程序扩展相关的内容:以可扩展性为目的的体系结构的设计方法,以及可以帮助扩展现有系统的技术和技巧。虽然这个领域很难用单个章节进行全面的探讨(即使一整本书也只能覆盖基础部分),但对那些需求较常见的应用程序我们还是挑选出了一些最为有效的方式方法。但要注意,本书不是针对扩展的详尽指南,除了提到的内容,还有很多东西要学。如果想要一份全面的对可扩展的底层框架的介绍,你可以选择这本书看看,Performance by Design: Computer Capacity Planning by Example(Prentice Hall)。
在本书末尾(第10章和第11章),讨论的是如何保持Web应用程序长期运行,并提供事件监测和长期统计,以进行容量和性能规划。如果想要创建一个应用程序并且长期管理它,那么监测和警戒是你所需要的核心技能。对于有定制组件的应用程序,或者只是有很多组件的应用程序,设计和构建探测器、监测器的任务往往落在应用程序设计人员的头上,因为他们最了解哪些是需要追踪的,以及什么状态是警戒状态。对于系统中的每个组件,都需要设计出某种方式,来检查它能工作并且在正常工作。
在最后一章,讨论了数据共享技术,还有通过数据订阅地址和读/写API,允许其他应用程序整合我们的应用程序的技术。本书中,我们一直在考虑,在处理我们应用程序中的不同组件时,如何进行组件API的设计,但在最后一章中,则在研究各种不同的方法,来把这些接口以一种安全和可访问的方式展现给外部世界。我们还会看到演化得来的用于数据导出和交互的各种标准,以及如何在应用程序中使用它们。
你需要知道的
What You Need to Know
本书不适用于刚刚开始构建第一个动态Web站点的人。对于新手已有很多不错的书,因此我们不打算讲述那些基础内容。所以,你得有一些构建动态Web站点或应用程序的经
验。至少你应有通过Web页面展现给用户编辑的数据和管理用户数据的经验。虽然本书的重心不在于具体实现,但还是提供了很多实际的示例。要能完全消化这些示例,需要基本编程方面的知识。固然不需要continuation或者参数currying方面的知识,但你至少得有些简单的控制结构和基础的冯•诺伊曼输入—处理—存储—输出体系方面的工作经验。
除了示例代码,还要看相当多的基于Unix命令行环境的示例。如果能访问一台Linux机器(或者其他Unix变种),那会让你的生活轻松好多。有一台可用的服务器让你输入那些命令和代码,会让所有内容都更加容易理解,并且能立即给你实际使用的体会。本书假定读者有命令行的工作经验,书中不会讲解如何启动一个shell,执行一个命令,或杀掉一个进程。如果你在命令行方面是个新手,那在进一步学习之前应该选择一本介绍性的书——命令行的经验对基于Unix的应用程序是基础,即使对基于Windows的应用程序命令行也正变得越来越重要。
本书中讲述的技巧也适用于其他的现代技术,但书中的示例和讨论将主要使用4种核心技术,很多最大型的应用程序是基于它们建立起来的。PHP在大多数示例代码中是主要的胶水性语言——如果以前没有用过PHP,你也不用担心,只要曾经用过其他C风格的语言。比如你曾经用C、C++、Java、JavaScript或者Perl工作过,你就能立即上手PHP,并且随即就能理解它的语法。
对于略为次要的代码和工具方面的工作,有一些示例采用了Perl。虽然Perl也能作为主要的应用程序语言使用,但大多数情况下它还是扮演命令行脚本和数据整理的角色,因此它往往是构建管理工具的明智之选。如果你用过C风格的语言,那么Perl的语法就很容易掌握,所以暂时还没有跑出去买那本著名的骆驼书的必要。
对于应用程序中的数据库组件,虽然也会涉及其三个常用数据库(Oracle、SQLServer和PostgreSQL),但重点还是放在MySQL上。MySQL并不是适用于所有工作的万灵丹,但和其他数据库相比,它毕竟有很多优点。它易于安装,足以应付通常的需要,最重要的是它是免费的。如果想要建立原型或者构建小型应用程序,那么MySQL安装和管理的低成本加上像phpMyAdmin(http://www.phpmyadmin.net)这样的工具,使得它成为非常有吸引力的一个选择。我们并不是说其他数据库技术在Web应用程序开发中就毫无用武之地,这4种数据库都有广泛的应用,但很重要的一点是,您得注意到MySQL可以用在大型应用程序中——互联网上很多最大型的应用程序都选择了它。对SQL基础知识和数据库原理的了解能在阅读本书时提供很多帮助,如果能有一个MySQL的实例让你可以进行试验和连接到PHP示例脚本那就更好了。
为了和Unix环境保持一致,所有的示例都假定你使用Apache作为HTTP服务器。某种程度上来讲,Apache是工具链中最不重要的一环,因为我们不会在如何配置或扩展它上面花费很多精力(这本身又是一个大的领域)。虽然对Apache的经验在阅读本书时能有所助益,但这并不是必须的,您只要有任何一种Web服务器软件的经验就足够了。
实际使用过这些软件并非唯一要求。要能从本书中获得更多,您需要对它们背后的原理有一定的认识。对每个涉及的核心协议和标准,我都会引用相关的RFC或者规范(这些东西可能比较枯燥乏味和难以理解),并且在大多数情况下,会推荐这个领域中的一些重要书籍。虽然我会对HTTP、TCP/IP、MIME和Unicode进行一定程度的讲解,但其他提到的协议都只是一笔带过(你将会看到超过200个缩写词)。要想完全理解这些相关问题,建议您自己努力去阅读这些协议和标准。
本书约定
Conventions Used in This Book
书中的条目有时采用不同显示风格,以区分常规文本。它们看起来像这样:
斜体
用于对书籍、文献、命令、邮件地址、URLs、文件名称、重要文本、首次对术语的引用
等宽字体
用于文字、常量值、代码列表和XML标记
等宽斜体
用于可替换的参数和变量名称
等宽粗体
用以高亮当前讨论的代码列表中的一部分
表示一个提示、建议,或者一般性说明。例如,用这种方式告诉你某种设置是否是版本特定的。
表示一个警告或者提醒。例如,用这种方式告诉你一种特定的设置是否对系统有某种负面影响。
使用示例代码
Using Code Examples
本书的目的是帮助你完成工作。一般情况下,你可以在程序和文档中使用书中的代码。除非你需要大量重复使用书中代码,否则无需联系我们以取得使用许可。例如,你编写了一个程序,它使用了书中的几处代码,这不需要许可。但销售和发放CD-ROM,它们当中包含来自O’Reilly书中的示例,这需要许可。引用本书和书中的示例代码回答问题,不需要许可。但将书中大量的示例代码包含在您的产品文档中,就需要许可。
我们会表示感激,但并不刻意要求您说明来源。关于来源的说明往往包含标题、作者、出版社和ISBN。例如:“Building Scalable Web Sites by Cal Henderson. Copyright 2006 O'Reilly Media, Inc., 0-596-10235-6.”
如果您觉得您对示例代码的使用超出了这儿给出的一般性许可范围,欢迎您联系我们,邮件地址是permissions@oreilly.com。
联系我们
How to Contact Us
我们已尽力核验本书所提供的信息,尽管如此,仍不能保证本书完全没有瑕疵,而网络世界的变化之快,也使得本书永不过时的保证成为不可能。如果读者发现本书内容上的错误,不管是赘字、错字、语意不清,甚至是技术错误,我们都竭诚虚心接受读者指教。如果您有任何问题,请按照以下方式与我们联系。
奥莱理软件(北京)有限公司
北京市 海淀区 知春路49号 希格玛公寓B座809室
邮政编码:100080
网页:http://www.oreilly.com.cn
E-mail:info@mail.oreilly.com.cn
与本书有关的在线信息如下所示。
http://www.oreilly.com/catalog/web2apps(原书)
http://www.oreilly.com.cn/book.php?bn=978-7-121-05154-9(中文版)
北京博文视点资讯有限公司(武汉分部)
湖北省 武汉市 洪山区 吴家湾 邮科院路特1号 湖北信息产业科技大厦1402室
邮政编码:430074
电话:(027)87690813 传真:(027)87690595
读者服务信箱:
reader@broadview.com.cn (读者信箱)
bvtougao@gmail.com (投稿信箱)
答谢
Acknowledgments
我很感谢最初的Flickr/Ludicorp团队——Stewart Butterfield、George Oates和Eric Costello——能让我参与构建如此优秀的产品,让我有机会制造人们喜爱的事物。很多较大规模的系统设计工作都来自于和其他伙伴的商讨,他们是Ludicorpers John Allspaw、 Serguei Mourachov、Dathan Pattishall和Aaron Straup Cope。
我还要感谢长期以来任劳任怨的伴侣Elina,在我写这本书的几个月里,她没有因为我忽视她而抱怨。
| 回书目 上一节 下一节 |