10

我对单例在 Google App Engine(或任何分布式服务器环境)中的工作方式很感兴趣。鉴于您的应用程序可以同时在多个进程中(在多台机器上)运行,并且请求可以完全路由,那么当应用程序执行以下操作时实际上会发生什么:'CacheManager.getInstance()'?

我只是以(GAE)CacheManager 为例,但我的意思是,某处有一个单例的全局应用程序实例,那么它在哪里?是否调用了 RPC?实际上,全局应用程序状态(如会话)实际上是如何处理的?

问候, 谢恩

4

3 回答 3

13

App Engine Java 中的单例是针对每个运行时的,而不是针对每个 Web 应用的。他们的目的只是提供对底层服务的单点访问(在 Memcache 和 Users API 的情况下,通过 RPC 访问),但这纯粹是库的设计模式 - 没有每个应用程序的单例这些方法访问的任何地方。

于 2009-07-26T15:19:35.140 回答
3

缓存通常与某种分布式复制缓存链接在一起。例如,GAE 使用自定义版本的memcached来处理跨集群维护对象的共享缓存,同时将存储状态保持在一致状态。一般来说,这个问题有很多解决方案,在性能和缓存一致性方面需要做出很多不同的权衡(例如,所有缓存是否必须 100% 匹配,是否必须将缓存写入磁盘以保护防止损失等)。

以下是一些具有分布式缓存功能的示例产品(大多数都有详细描述各种方法的权衡的文档:

如您所见,已经有很多项目解决了这个问题。一种可能的解决方案是在一台机器上简单地共享一个缓存,但是,大多数项目都可以进行某种复制和分布式故障转移。

于 2009-07-26T02:56:53.740 回答
0

我不确定 GAE 的具体细节,但通常在这种大小的 Web 应用程序中,您将有多个进程在多台机器上运行(然后在它们之间进行负载平衡)。在每个进程中,如果您使用的是多线程 Web 服务器,则可以处理多个请求。因此,这将允许您在同一 Web 服务器内的请求之间共享对象(例如,您将在 Web 应用程序进程启动时实例化一个单例)。

如果Web服务器不是多线程的,而是多进程的,那么据我所知,如果不与单独的缓存进程对话,就无法在请求之间共享对象。

GAE 文档似乎支持他们所谓的“应用程序缓存”,它本质上允许你做同样的事情,但我从文档中不清楚他们是通过使用多线程 Web 服务器还是一些与 Web 服务器一起运行的其他缓存进程。

我很想知道是否CacheManager.getInstance() 总是解析为同一个对象,或者它是否只是同一个 Web 服务器处理的请求的同一个对象。实际上,这并不重要,因为它只是用于与单独的 memcached 进程通信。

于 2009-07-26T08:05:11.423 回答