GAE是一个Web应用程序托管服务。其中,“Web应用程序”指的是通过Web(通常是利用Web浏览器)访问的一个应用程序或服务,比如,带有购物车功能的网上商店、社交网站、多人游戏、移动应用、投票应用、项目管理、协作、出版等其他一切能够利用Web的东西也都是可以的,只要我们想得出就行。虽然App Engine也适用于诸如文档和图片等传统网站内容,但它实际上是专门针对实时动态应用程序而设计的。
GAE主要是针对那些拥有大量并发用户的应用程序而设计的。当某个应用程序在有大量并发用户的情况下性能没有降低,我们则认为其“伸展”了。为App Engine所编写的应用程序都是可以自动伸缩的。某个应用程序的使用人数越多,App ngine为其分配的资源也就越多,同时它还会对那些资源进行管理。而应用程序本身则无需了解它所使用的那些资源到底是怎么回事。
与传统的Web托管或自管服务器不同,使用GAE时,你只需为那些实际用到的资源付费。这些资源均会换算成GB,无须按月付费或预付费。可供购买的资源包括CPU使用率、每月存储容量、出入口带宽以及其他特定于App Engine服务的资源。为了便于人们了解GAE,每个开发人员都能免费获得一些资源,这些资源已经足以应付那些流量不大的小应用了。Google公司曾对此进行过评估,使用这些免费资源的应用程序能够应对每月500 万左右的PV量。
我们可以把App Engine描述为三大块:运行时环境、数据存储区以及可伸缩的服务。在这一章中,我们将从宏观的角度来观察每个部分。我们还将讨论App Engine的一些特性,包括Web应用程序的部署管理,以及集成其他服务(例如Apps和Account)等。
运行时环境
App Engine会对Web请求作出响应。当客户端(一般就是用户的Web浏览器)通过一个HTTP请求(比如获取某个指定URL的网页)联系应用程序时,Web请求就开始了。当App Engine接收到请求时,会根据其地址中的域名确定具体的应用程序,这个域名可以是一个.appspot.com子域名(任何应用程序都可以免费使用),也可以是你自己注册并设置到Apps的自定义域名的某个子域名。App Engine会从许多可用服务器中选出一个来处理该请求,选择的依据是看哪个服务器最可能作出快速响应。然后,它将使用该HTTP请求中的内容去调用应用程序,并接收来自应用程序的响应数据,跟着再将响应返回给客户端。
从应用程序的角度来看,运行时环境在请求处理器(request handler)启动时出现,并在其结束时消失。App Engine提供了至少两种用于持久化请求之间存储数据的方式(稍后再讨论),不过它们都不是在运行时环境内部实现的。由于不会在运行时环境内部保留请求与请求之间的状态(其实本来就不想保留),因此App Engine可以将流量分布到多个服务器上去,这样它就可以同等对待每一个请求了,而无须关心到底一次处理了多大的流量。
从传统意义上来讲,应用程序代码是不能访问其所在的服务器的。虽然应用程序能够通过文件系统读取其自己的文件,不过却不能写文件,而且也不能读取属于其他应用程序的文件。虽然应用程序可以通过App Engine看到环境变量集,不过对这些变量所作出的修改操作不能在请求与请求之间持久化。应用程序不能访问服务器硬件中的网络设备, 但是可以通过相关服务来完成网络操作。
简单地说,每个请求都住在自己的“沙盒”中。这就使得App Engine可以(根据其自己的判断)选择能够提供快速响应的服务器去处理请求了。即使两个请求来自同一个客户端,而且几乎同时到达,也没有办法保证会由相同的服务器硬件来处理它们。
沙盒还允许App Engine在同一个服务器上运行多个应用程序,且一个应用程序的行为不会影响到别的应用程序。除了限制对操作系统的访问以外,运行时环境还会限制单个请求所能用到的时钟时间、CPU使用率以及内存等。App Engine会灵活地使用这些限制, 对那些占用太多资源的应用将作出更为严格的限制,以确保共享资源不会被“脱缰野马”所累。
一个请求拥有多达30秒的时间向客户端作出响应。这对于Web应用程序而言也许时间已经算是很长了,实际上,App Engine对那些响应时间小于1秒的应用程序是有专门优化的。此外,如果某个应用程序占用了许多CPU周期,App Engine则可能会放慢其执行速度,这样,该应用程序就不会霸占服务器上的处理器了。跟独享处理器的方式相比,这里执行CPU密集型任务所需的时钟时间可能会更多,而且具体的时间长短还可能会发生变化,因为App Engine会侦测CPU使用率并据此进行调配。
GAE为应用程序提供了两种运行时环境:一个是Java环境,另一个是Python环境。具体如何选择得取决于你所选择的编程语言,以及你在开发应用程序时所希望用到的相关 技术。
Java环境可以运行基于Java 6 Virtual Machine(JVM)构建的应用程序。应用程序可以使用Java编程语言开发,也可以用其他任何能够以编译或别的什么方式在JVM上运行的语言来开发,比如PHP(通过Quercus)、Ruby(通过JRuby)、JavaScript(通过解释器)、Scala以及Groovy等。应用程序通过基于Web行业标准的接口(包括Java Servlet和Java Persistence API,即JPA)访问环境及服务。任何能够在沙盒限制下工作的Java技术都能在App Engine上运行,这也就是App Engine能够兼容许多现有框架和库的原因。此外,App Engine完全支持GWT。GWT是一个针对富Web应用程序的框架,它使你能够用Java语言编写应用程序的全部代码(包括用户界面),还能让你的富图形应用程序无需插件就能工作于所有主流浏览器之上。
Python环境可以运行用Python 2.5编程语言编写的应用程序,这里会用到CPython(官方Python解释器)的一个自定义版本。App Engine通过CGI(一种受到广泛支持的应用程序接口标准)调用Python应用程序。应用程序能够使用Python大量且优秀的标准库,以及丰富的用于访问服务、数据建模的API和库。Python领域中许多开源Web应用程序框架都能工作在App Engine上,如Django、web2py以及Pylons等,此外App Engine本身也带有一个简单的框架。
Java和Python环境使用相同的应用程序服务器模型:请求路由到某个应用程序服务器, 应用程序在服务器上启动(如果需要)并被调用以处理该请求和产生响应,然后这个响应再返回给客户端。这两个环境都在沙盒限制下运行其解释器(JVM或Python解释器),因此,任何试图使用语言或库中那些需要访问沙盒外部的功能都会失败并得到一个异常。
虽然为每个请求使用不同的服务器能够得到很好的可伸缩性,不过为每个请求启动一个新的应用程序实例也是很耗费时间的。App Engine通过将应用程序足够久地保留在服务器内存中以及智能化重用服务器等方法来降低启动成本。当服务器需要回收资源时,首先会清除掉最近最少使用的那些应用程序。所有应用程序服务器都会在请求到达服务器之前预先加载运行时环境(JVM或Python解释器),因此在一台新服务器上只有应用程序本身才需要加载。
应用程序可以利用缓存功能通过全局(静态)变量将数据直接缓存在应用程序服务器上。由于应用程序可能会在两个请求之间被赶出服务器(低流量的应用程序经常会被赶出去),而且由于无法保证某个请求一定会由某个特定的服务器来处理,因此用全局变量来缓存初始资源(比如已解析的配置文件)就显得非常有用了。
我可没说App Engine究竟用的是什么操作系统或硬件配置。虽然有办法知道某个服务器用的是什么操作系统,不过根本就没这个必要:运行时环境是操作系统“之上”的一个抽象,它使App Engine在管理资源分配、计算、请求处理、伸缩以及负载分布时完全不用把应用程序也扯进来。对于那些需要用到操作系统信息的功能,要么由运行时环境外部的服务提供,要么由标准库调用来提供或模拟,要么就直接在沙盒的定义中被限制掉了。
静态文件服务器
大部分网站都有那种“需要发送给浏览器但却不会因为日常操作而发生变化”的资源。用于描绘网站外观的图片和CSS文件、在浏览器中运行的JavaScript代码、不含动态组件的HTML网页文件等都属于这样的资源,人们将之统称为静态文件(static file)。由于发送这些文件时不会用到应用程序代码,因此没有必要把它们放到应用程序服务器上,实际上,那样的做法是很低效的。
为此,App Engine另外提供了一组服务器专门用来发送静态文件。为了处理对静态资源的请求,这些服务器专门对内部架构和网络技术进行了优化。对客户端而言,静态文件跟应用程序所提供的其他资源没什么两样。
你可以在上传应用程序代码的时候上传静态文件。在静态文件的处理方式上,你可以进行许多方面的配置,比如内容类型、静态文件的URL等;此外,为了降低流量并提高页面呈现速度,还可以指定浏览器对这些文件副本的缓存时间。
数据存储区
大部分Web应用程序都需要在处理请求的时候存储信息,以便在处理后续请求时能够直接使用。小网站通常都有这样的服务器布置:一台用于整个网站的数据库服务器,以及一台或几台连接到数据库服务器上的Web服务器(存储或检索数据)。使用单个中心数据库服务器可以让网站仅有一份标准数据,这样用户在访问不同服务器时也就可以看到一致且最新的信息了。 不过,中心服务器在达到其并发连接上限时是很难扩展的。
过去十年中,Web应用程序最为常用的数据存储系统是关系型数据库,由行和列组成的表赋予了它空间上的高效性和简洁性,它还拥有索引以及用于执行查询的原生计算功能,尤其是“连接”查询,它能够将多个相关的记录当做一个可查询单元来处理。其他的数据存储系统还有层次数据存储(文件系统、XML数据库)和对象数据库等。每种数据库都各有优劣,对于某个应用程序而言,究竟哪种最适合,这取决于应用程序数据的本质及其访问方式。此外,每种数据库都有自己的一套技术用于处理“服务器不能与时俱进”的问题。
GAE的数据库系统看上去非常像一个对象数据库。它与能进行连接查询的关系型数据库不同,如果你在开发Web应用程序时用惯了关系型数据库(就像我这样的),那就有必要改变一下对应用程序数据的思考方式了。跟运行时环境一样,App Engine数据存储区的设计目标也是“抽象”的,它让App Engine去处理应用程序在分布和扩展等方面的细节问题,这样你的代码就可以专注于其他事情了。
实体和属性
App Engine应用程序将其数据保存为一个或多个数据存储区实体(entity)。实体拥有一个或多个属性(property),每个属性都有一个名字和一个值,这个值可以是任何一种基本值类型。每个实体都有一个命名类别(kind),它用于在查询中对实体进行分类。乍一看上去,这跟关系型数据库没什么不同:同一类别的实体就像是表中的行,而属性就像是列(字段)。实际上,实体和行之间有两个显著的区别:第一,同类别的两个实体无须拥有相同的属性;第二,两个实体的同名属性可以拥有不同类型的值。这样,数据存储区实体就成“无架构”的了。你很快就会看到,这种设计既提供了强大的灵活性,同时也带来了一些维护上的问题。
实体跟表行之间的另一个区别在于:实体中的某个属性可以拥有多个值。这个功能有点诡异,不过当你弄明白之后就会发现它的作用其实非常大。每个数据存储区实体都有一个唯一键,它既可以由应用程序提供,也可以由App Engine 生成(随你高兴)。跟关系型数据库不同,这个键不是“字段”也不是属性,而是实体的一个独立元素。如果知道实体的键,就能够快速地将其取出来,还可以执行基于键值的查询。
实体的键在其创建之后就不能修改了,其类别也一样。App Engine通过实体的类别和键去判断它究竟存储在一大堆服务器中的什么位置(不过,键和类别都不能保证某两个实体会存储在同一台服务器上)。
查询和索引
数据存储区查询将返回零个或多个单一类别的实体。它也可以只是返回查询所得的实体的键。查询不仅可以根据条件(必须匹配实体属性的值)进行过滤,还可以根据属性值对返回的实体进行排序。查询也可以通过键来进行筛选和排序。
在传统的关系型数据库中,查询会实时地根据数据表(由开发人员决定如何对其进行存储)进行计划和执行。开发人员还可以让数据库在指定的列上创建和维护索引以提高相关查询的执行速度。
App Engine的做法与此大不相同。在App Engine中,每个查询都有一个与之对应的由数据存储区维护的索引。当应用程序执行查询时,数据存储区将会找出该查询的索引,扫描并找到第一个与之匹配的行,然后逐行返回索引中的实体,直到发现与查询不匹配的行为止。
当然了,这需要App Engine预先掌握应用程序将要执行哪个查询才行。虽然它无须预先知道具体的筛选条件,不过却需要知道查询中实体的类别、用于筛选或排序的属性、筛选器的操作符以及排列顺序等。
默认情况下,App Engine会根据各类实体的既有属性为简单查询提供一组索引。为了执行更复杂的查询,应用程序必须在其配置文件中添加索引声明。当你在本地计算机上利用App Engine SDK所提供的那个开发版Web服务器测试应用程序时,App Engine SDK会监视所执行的查询并帮你生成一份配置文件。在你上传应用程序的时候,数据存储区就会自动地为测试时执行过的每条查询生成索引,你也可以手工编辑索引配置文件。
当应用程序创建了新实体或是更新了现有实体时,数据存储区会更新相应的索引。这也就使得查询变得非常快(每个查询都是一个简单的表扫描),而实体的更新操作则反之(一个小小的修改就可能会使很多表都需要更新)。事实上,基于索引的查询性能并不受数据存储区中实体数量的影响,而只会受到结果集大小的影响。
索引是值得关注的,因为它们会占用空间,而且会增加实体更新操作所需的时间。我们将在第5章中详细讨论索引。
事务
当某个应用程序拥有大量需要同时读写相同数据的客户端时,保持数据的一致性状态就显得极为重要了。用户永远都不该看到由于其他用户的操作还没完成而产生的没写完的或是没有意义的数据。
当应用程序更新了某个实体之后,App Engine会确保该实体上的所有更新要么全部执行成功,要么全部失败且该实体恢复到更新执行之前的状态。在整个修改操作成功完成之前,其他用户将看不到该操作的效果。
换句话说,单个实体上的一次更新操作是在一个事务(transaction)中发生的。每个事务都是原子性的(atomic):事务要么全部成功,要么全部失败,而不能以更小的单位成功或失败。
应用程序可以在单个事务中读取或更新多个实体,不过它必须在创建这些实体的时候就告诉App Engine哪些实体将会一起更新。应用程序是通过在实体组(entity group)中创建实体来实现这一功能的。App Engine使用实体组来控制实体在服务器间的分布方式,这样做可以保证组上的事务全部成功或失败。用数据库的术语来说,App Engine数据存储区原生支持本地事务(local transaction)。
应用程序调用数据存储区API去更新实体时,在事务成功或失败之前,控制权是不会交回给应用程序的。另外,调用会返回成功或失败的信息。对于更新操作而言,这就意味着应用程序在做其他事情之前只能等待所有实体和索引被完整更新。
当其他用户的实体更新操作正在处理的时候,如果某个用户也试图去更新那个实体的话,数据存储区将会立即返回一个并发失败异常。应用程序通常应该在提示出错之前重试几次失败的事务,在事务中计算新值并在更新之前预先读取那些可能已经被修改过的数据。又用数据库的术语来说,App Engine数据存储区使用的是乐观并发控制(optimistic concurrency control)。
读取实体绝不会因为并发而失败,应用程序只会看到实体的最新稳定状态。你也可以在事务中执行多次读取操作,以确保在该事务中所读取的全部数据都是最新的和一致的。
大多数情况下,重试某个受争夺实体上的事务都是会成功的。但是,如果某个应用程序被设计为允许大量用户更新单个实体,那么这个应用程序越受欢迎,其用户就越有可能得到并发失败的结果。所以设计实体组来避免并发失败就显得很重要了,尤其是在用户数量很大的情况下。
应用程序可以将多个数据存储区操作放到一个事务中。比如说,应用程序可以启动一个事务,读取一个实体,根据最后一次读取的值更新一个属性,保存该实体,然后提交该事务。在这个例子中,只有当整个事务成功时(即没有与别的事务发生冲突),保存操作才会被执行。如果出现了一个冲突,且应用程序想要再试一次,那么就应该重试整个事务:再次读取那个实体(说不定已经被更新过了),使用新的值进行计算,然后再尝试一次更新。
由索引和乐观并发控制我们可以看出,App Engine的数据存储区是专为那些需要快速读取数据的应用程序而设计的,它将确保应用程序所看到的数据是一致的,而且能够根据用户数量以及数据大小自动伸缩。这些特点跟关系型数据库有点不同,它们尤其适用于Web应用程序。
服务
数据存储区跟运行时环境之间的联系其实就是一个服务:应用程序通过API去访问一个独立系统,该系统会管理其自身(独立于运行时环境)全部的可伸缩性需求。GAE还含有许多其他的对Web应用程序有帮助的自动伸缩型服务。
内存缓存(也就是memcache)服务是一种短期的键-值型存储服务。它相对于数据存储区的主要优点就是快,对简单的存储和检索操作而言,它要比数据存储区快得多。为了使访问的速度更快,memcache将值存放在内存中而不是硬盘上。与数据存储区一样,它也是分布式的,因此每个请求都能看到相同的键和值。然而,与数据存储区不同的是, 它是非持久化的:如果服务器出问题了(比如电源出现了故障),内存也就被擦掉了。
它在原子性和事务性方面比数据存储区差。从名字上就可以看出,memcache服务最适合于缓存那些需要频繁执行的查询或计算的结果。应用程序会检查缓存值,如果找不到这样的值,就去执行查询或计算,并将结果值存放到缓存中以便今后使用。
App Engine应用程序可以使用URL Fetch服务去访问其他的Web资源。该服务会向互联网上其他的服务器发出HTTP请求,比如获取网页或与Web服务(web service)进行交互。
由于远程服务器在响应的时候可能会很慢,URL Fetch API支持后台获取URL,以便请求处理器能够在此期间去做其他的事情。不过,不管怎么样,这个获取操作的启动和结束都必须在同一个请求处理器的生命周期中完成。应用程序还可以设置一个最后期限,如果远程主机在最后期限到达之时还没有作出响应,调用就会被取消。
App Engine应用程序可以使用Mail服务来发送消息。应用程序和用户都能发送消息。许多Web应用程序都会使用电子邮件去提醒用户、确认用户的操作,或是验证联系人信息等。
应用程序也可以接收电子邮件消息。如果应用程序被配置为允许接收电子邮件,发送给该应用程序的电子邮件就都会被路由到Mail服务,它会将这些消息以HTTP请求(以便请求处理器能够使用)的形式转发给应用程序。
App Engine应用程序可以通过支持XMPP协议的聊天服务(比如GTalk)收发即时消息。
应用程序通过对XMPP服务的调用来发送XMPP聊天消息。跟电子邮件的接收一样,如果某人向该应用程序的地址发送了一个消息,XMPP服务会调用相应的请求处理器以将该消息转发给应用程序。
图像处理服务可以做一些轻量级的图像数据转换工作,比如为已经上传的照片生成缩略图之类的。用于完成图像处理任务的基础架构可以很快地得到结果。我们不会在本书中介绍图像服务API,因为Google公司的官方文档已经把这个简单易用的服务说得很清楚了。
GAccount
App Engine可以与GAccount(也就是GMail、GDocs以及GCalendar等它自己的应用程序所采用的用户账户系统)集成。可以把GAccount用作你的应用程序的账户系统,这样就不必再自己构建一套了。而且,如果用户已经有了账户,就可以直接使用那个账号登录你的应用程序了,无须再单独为你的应用程序而注册一个新账户。当然了,绝对不是非用GAccount不可,你仍然可以构建自己的账户系统,或是找一个OpenID提供商。
当使用Apps为你的公司或组织开发应用程序时,GAccount会显得特别有用。通过Apps,组织成员能够使用同一个账户访问你的自定义应用程序以及他们自己的电子邮件、日历和文档等。
任务队列和计划任务
为了可以给坐在浏览器前的用户提供一个流畅的体验,Web应用程序都必须能够非常快速地响应Web请求(通常要小于1秒,如果只有几十毫秒那就更好了)。也就是说,应用程序在干活的时候不会有多少时间。甚至有时候根本就没有时间去完成那么多的工作。
在这种情况下,全部工作在几秒、几分钟或是几小时内完成都无关紧要了,因为用户只是等着来自服务器的响应而已。但是,用户需要得到“全部工作都会被完成”的保证。
针对这种类型的任务,App Engine提供了任务队列。任务队列使请求处理器可以将工作描述为“稍后在Web请求之外进行处理”。队列将保证每个任务都会被处理,如果某个任务失败了,队列将重试该任务直到其成功为止。你可以配置队列的执行速率以便将工作量分散到一天的不同时段。
队列通过调用请求处理器的方式来执行任务。任务的数据由创建任务的代码提供,即以HTTP请求的形式传送给相应请求处理器的那些数据。跟其他请求处理器一样,任务的请求处理器也会受到一些限制(比如30秒时间限制)。
任务队列最为强大的功能就是它可以在数据存储区事务中将任务排入队列。这就确保了只有在数据存储区事务成功之后,任务才会被加入到队列当中。有些数据存储区操作必须跟事务保持一致,但又不必拥有数据存储区本地事务那么强的一致性保证,这些操作就可以用事务型任务来进行处理了。
App Engine还有一个用于在每天特定时间执行任务的服务,即计划任务(也叫做cron jobs,这个词来源于Unix操作系统中一个类似的功能)。根据你在上传应用程序时所给出的一个计划,计划任务服务可以在一天、一周或者一月中的某个指定时间调用请求处理器。计划任务非常适合于日常维护工作或是发送定期提醒消息。
我们将在第13章中详细讨论这些功能,并将介绍一些非常强大的用法。
开发人员工具
Google公司提供了一些免费的用于开发App Engine应用程序的工具(Java和Python)。可以根据你的操作系统以及所选择的语言从Google公司的网站下载到这个软件开发包(SDK)。
Java用户可以下载以Eclipse集成开发环境插件形式给出的Java SDK。使用Windows或Mac OS X的Python用户可以下载以GUI应用程序形式给出的Python SDK。这两种SDK都有ZIP文件的形式。
这两个SDK都含有一个用于开发的Web服务器,它使你能够在本地计算机上运行应用程序,模拟运行时环境、数据存储区以及其他各种各样的服务。该服务器将会自动侦测源代码文件上的修改,并根据需要重新加载这些文件,因此,在开发应用程序的时候,你可以把它一直开着。
如果你使用的是Eclipse,那么就可以运行交互式调试器中的Java开发服务器了,还可以在应用程序代码中设置断点。通过PyDev(这是一个Eclipse扩展,它含有一个交互式Python调试器),你也可以使用Eclipse来开发Python应用程序。(本书不会讲解如何使用PyDev,不过Google公司的网站上有相关的介绍。)
在应用程序执行查询时,开发版的数据存储区可以自动为这些查询生成索引配置信息,App Engine将会使用这些信息预先给相关的查询生成索引。如果只是为了测试查询在配置文件中是否拥有相应的索引,也可以将这个功能关掉。
开发版Web服务器带有一个内建的Web应用程序,这是为了检查数据存储区(模拟的) 的内容。出于测试的目的,你也可以通过这个界面来创建新的数据存储区实体。
这两个SDK中都有一个用于与正在App Engine上运行着的应用程序交互的工具。该工具主要用于将应用程序代码上传到App Engine。你也可以用这个工具来下载在线应用程序的日志数据或者管理在线应用程序的索引。
Python SDK和Java SDK都含有一个用于对在线应用程序进行远程编程访问的功能,该功能可以用于应用程序。Python SDK还含有利用该功能进行大批量数据操作(比如上传文本文件形式的新数据、下载大量数据以便备份或是迁移)的工具。此外,Python SDK 还含有一个用于测试、调试或手工处理在线数据的交互式命令行Shell工具。(虽然这些工具都是Python SDK中的,但是通过Java版中的远程访问功能也能用在Java应用程序上。)你可以编写带有远程访问功能的脚本和程序去完成大型的数据转换工作或其他维护工作。
管理控制台
当你的应用程序已经准备好公开亮相的时候,只需创建一个管理员账户并将应用程序安装到App Engine上即可。你可以通过管理员账户去创建和管理应用程序,查看其访问量、资源使用情况、消息日志…… 所有这些都是通过一个叫做管理控制台(Administration Console)的Web界面实现的。
使用GAccount即可登录管理控制台。如果你已经有了一个GAccount,直接用就是了,当然,你也可以专门为你的应用程序创建一个新的(也许你想要在电子邮件的“发件人”那里用到这么一个)。在管理控制台中创建了一个应用程序之后,你还可以添加其他管理员的GAccount。任何管理员都能访问该控制台,而且都能上传该应用程序的最新版本。
管理控制台使你能够看到有关应用程序的实时性能数据,还能看到由应用程序所产生的日志数据。你还可以在这里查询在线应用程序的数据存储区、检查数据存储区索引的状态。(在大数据集上创建新索引是需要时间的。)
当你通过SDK上传应用程序的新代码时,它们将会被赋予一个版本标识符,该标识符是由你在应用程序配置文件中指定的。只要主版本号被选为“默认”,那么它就是在线应用程序所使用的版本了(可以通过管理控制台来更换“默认” 的版本)。此外,还可以通过含有版本标识符的特殊URL去访问非默认版本,这就使你可以在正式发布应用程序的新版本之前,先在App Engine上对其测试一番了。
通过管理控制台,你可以设置并管理应用程序的缴费账户。当你准备让应用程序使用免费额度以外的更多资源时,可以通过信用卡以及GAccount设置一个缴费账户。缴费账户的拥有者可以设置一个预算,也就是一个可以按日历日记账的最大费用额度。在预算内,你可以分配应用程序可以使用的CPU时间、带宽、存储以及电子邮件收件人数量等。你只需为应用程序在免费资源以外所实际用到的资源付费。
App Engine暂时还做不到的事情
人们在刚开始使用App Engine的时候,问到了许多App Engine做不到的事情。有一些G 公司可能会在近期实现,而另外的那些则与App Engine的设计目标有点冲突,也就不大可能会被加进去了。要在一本书中将这些功能都列出来是比较困难的,因为当你拿到这本书的时候,Google公司可以已经把它们给做出来了。不过,这里还是有必要说明一下这些功能的,尤其是相应的变通方案。
App Engine支持.appspot.com子域名上的安全连接(HTTPS),但还不支持自定义域名上的安全连接。GAccount的登录页面所使用的就是安全连接。
应用程序可以使用URL Fetch服务向其他网站发起HTTPS请求,不过App Engine并不会去验证远程服务器所使用的证书。
应用程序可以在多个地址上接收电子邮件和XMPP聊天记录。但是直到编写本书为止,这些地址中没有哪个可以使用自定义域名。关于电子邮件和XMPP的地址方面的信息,请参见第11章。
通过Apps,应用程序可以在自定义域名上接收Web请求。Apps会把自定义域名的一个子域名映射到应用程序上,这个子域名可以是www(如果你喜欢的话)。不过目前还不支持“裸”域名,比如。它也不支持自定义域名上任意的三级域名()。App Engine支持appspot.com上的任意子域名,例如foo.app-id.appspot.com。
App Engine不支持长时间运行的后台处理。任务队列和计划任务都能在用户请求之外调用请求处理器,也能驱动部分类型的批处理。然而,在小的批处理作业中执行大的日常操作,这跟完全分布式计算任务有很大的不同。我们将在第12章中讨论批处理。
App Engine不支持不间断的或长时连接。如果客户端支持,那么应用程序可以通过XMPP以及一个XMPP服务(如GTalk)向客户端传送状态更新。也可以通过轮询的方法来实现这个功能,客户端根据定时基准请求应用程序的更新。不过,轮询很难扩展(每5秒有5 000个模拟用户轮询=每秒1 000次查询),而且这并不适用于所有应用程序。还要注意一点,请求处理器在处理其他计算任务的时候是不能跟客户端通信的。服务器端只有在请求处理器将控制权交回之后才能向客户端发出响应。
App Engine仅支持HTTP或HTTPS上的Web请求,以及其相关服务上的电子邮件和XMPP 消息。它不支持其他类型的网络连接。比如说,客户端不能通过FTP连接App Engine应用程序。
App Engine数据存储区不支持全文搜索技术(这种技术可以为内容管理系统实现一个搜索引擎)。长文本值是不会被索引的,而短文本值也只是为等于和不等于查询进行了索引而已。在应用程序中通过创建搜索索引的方式是可以实现文本搜索的,不过要在大量动态数据中以一种可扩展的方式实现就很困难了。
使用入门
在开始为GAE开发应用程序时,你还不用创建账户。你所需要做的仅仅是根据自己喜欢的语言找到合适的App Engine SDK而已,可以在App Engine的网站免费下载。
登录之后,根据你所选择的语言找到相应的“Getting Started Guide”,它说明了如何创建应用程序以及如何使用App Engine的功能。
在第2章中,我们将从头到尾地讲解如何创建一个新项目,包括如何创建账户、如何上传应用程序以及如何在App Engine上运行它等。
阅读(1831) | 评论(0) | 转发(0) |