App Engine会对Web请求作出响应。当客户端(一般就是用户的Web浏览器)通过一个HTTP请求(比如获取某个指定URL的网页)联系应用程序时,Web请求就开始了。当App Engine接收到请求时,会根据其地址中的域名确定具体的应用程序,这个域名可以是一个.a p p s p o t.c o m子域名(任何应用程序都可以免费使用),也可以是你自己注册并设置到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在管理资源分配、计算、请求处理、伸缩以及负载分布时完全不用把应用程序也扯进来。对于那些需要用到操作系统信息的功能,要么由运行时环境外部的服务提供,要么由标准库调用来提供或模拟,要么就直接在沙盒的定义中被限制掉了。
《GAE 运行时环境》留言数:0