除了 Python 以外,Google App Engine(GAE)又增加了 Java 支持,这对 Java 生态圈相关的工具、框架及语言(像 JRuby 和 Clojure)都产生了很大的影响。然而这么做的结果将对 GAE Java 应用造成很多限制,使其无法轻松扩展和集成这些应用。 Google 官方博客对此说到:
…我们想给开发者一些惊喜,但深知必须要将 Google App Engine 的简单性与 Java 平台的强大功能及灵活性结合起来,同时我们还想利用 App Engine 的基础设施,尽量去扩展这些内容,但又要保持与现有的 Java 标准和工具的兼容性。 我们就是这么做的。现在 App Engine 对标准(这些标准对 Java 工具起到了至关重要的作用)提供了支持(我们也从事着工具的开发——Google Plugin for Eclipse),它使用标准(如 Java Servlet API、JDO、JPA、javax.cache 及 javax.mail)对当前的 App Engine API 进行了包装,同时还提供了足够强大的安全的沙箱,这样你的代码就可以安全地运行在 Google Server 上而又不会丧失灵活性…
CNet 注意到 GAE 运行的是 Java 6。但就像上面提到的,Java 要想融入到 GAE 模型上还不是那么容易的事情,因为限制实在太多。GAE Java 基于 Java 2.4 Servlet API:
- 一旦请求发送到客户端就无法进行进一步的处理了,包括数据流。
- 请求在 30 秒内没有完成就会被终止,此时会抛出异常。如果没有捕获该异常,那么用户就会看到一个 500 错误。
再往上就是几个沙箱限制了:
- 应用无法对文件系统进行写操作,必须要通过 App Engine datastore 才行。
- 应用可能不会打开 socket。
- 应用无法创建自己的线程,也无法使用一些辅助工具,如计时器。
java.lang.System 有如下限制:
- exit()、gc()、runFinalization() 及 runFinalizersOnExit() 什么都不做
- 不允许进行 JNI 访问。
除此以外,还有其他一些限制,如 JRE 类加载的白名单等等。从文档来看,GAE 通过自定义的类装载器对此作了很好的处理,然而应该让其他应用级的类装载器也可以处理上面这些限制,这是一个不足之处。
接下来的问题是上面这些限制能给 GAE 应用带来什么好处呢?首先就是可伸缩性。App Engine 使用多个 Web Server 运行应用并能自动调整所使用的服务器数量。它可以将到来的请求路由到任意的服务器上,而该服务器很可能并不是处理该用户前一个请求的那个服务器。以下内容来自于文档:
…一个应用可以同时处理大约 30 个动态请求,这意味着平均的服务器请求处理时间为 75 毫秒的应用可以处理(1000 ms/second / 75 ms/request)*30=400 requests/second 的请求量而不会出现延时。CPU 处理密集的应用可能会在长时间的请求中出现延时,这是为了让其他应用可以共享同一个服务器。对静态文件的请求不会受到该限制的影响…
Google 还提供了一个 BigTable 版的 JPO 和 JPA 以及 Google Plugin for Eclipse ,以此简化 GAE 的开发。
尽管还处在开发当中,但 Google 已经让为数不少的开发者试用 GAE 的 Java 支持了。Paul Hammant说到:
…还要注意来自于同一客户端的多个并发请求也不一定会被同一个 Servlet 容器处理。即使来自于同一个域名(没有资源转发的情况出现),响应请求的 Servlet 容器实例也很可能是不同的。对于无状态应用来说这没什么问题,但对于那些利用 session 存储属性的应用来说就会出现并发问题了:向同一个资源写两次… …Google 已经实现了一个完善的沙箱。毋庸置疑,这会防止恶意代码的侵袭…而 XStream 是 Java 社区所推崇的一个工具,其最新版为 1.3.1,但它却在 GAE 初始化时抛出异常。
其他一些工程师正在着手 Clojure 、 JRuby 及 Groovy 的支持开发工作,而 ThoughtWorks 的 Ola Bini 则在其博客上详述了GAE 对动态语言的处理。
评论