GAE:实例和队列之间的分工

时间:2012-09-07 12:18:12

标签: java google-app-engine ejb esb n-tier-architecture

我通常喜欢使用2或3层“组件”部署我的JBoss服务器应用程序:

  • 一个my-ws.war文件,包含我所有服务器的Web服务,包括“Web层”并部署到JBoss的Web容器;和
  • 一个my-esb.war文件,由我的服务器的“ESB”(服务总线)组成,基本上是用Apache Camel构建的ESB,用于处理异步请求
  • 1 + EJB由我所有服务器的业务逻辑组成,包括“业务层”并部署到JBoss的app容器;所有EJB都负责为同步请求提供服务

因此,Web服务(my-ws.war)是后端的“网关”,并且根据请求的性质,Web服务知道将它们路由到适当的EJB(在某种情况下)需要及时响应的同步请求),或者将它们路由到队列,在那里它们被我的基于Camel的ESB拾取和处理(在异步请求的情况下)。这一直对我有用,我非常喜欢这种架构。

我现在正在设计我的第一个GAE后端,并且正在努力弄清楚如何将这个相同的架构映射到GAE平台上。

显然,我必须将所有内容部署为单个WAR文件(不再需要EAR或EJB)。但我在这里“没有”得到的是:

  1. 如果Web服务确定请求是异步的并且应该在ESB上进行,我可以将请求排入任务队列,但不确定如何指示我的Camel路由的第一个端点获取任务并开始处理它(我以前在Camel和ActiveMQ之间工作)
  2. 假设我的ESB应该部署到后端实例,因此它不受时间或线程限制的限制,
  3. 如果Web服务确定请求是同步的并且必须快速响应,我需要EJB的GAE版本。我只是创建处理程序POJOS并将请求路由到它们?我的Web服务将尽可能多线程(我相信10个线程是前端实例的最大值)所以我假设这样的处理程序POJO需要线程安全,?或者,有没有更好的方法来模拟GAE上的EJB /模块化业务逻辑?
  4. 此外,如果有人在尝试将我的常规架构映射到GAE时看到任何固有错误的内容,请大声说出来告诉我/为什么/为什么!提前谢谢!

2 个答案:

答案 0 :(得分:0)

您描述的架构很简单。是否可以为您的应用程序保证隐含的复杂性。

我不熟悉Camel的细节,因此您需要尝试在此处映射概念。但是,这应该没什么大不了的。在这个级别,ESB是ESB是ESB。

对于#1,有两种选择。 GAE有pushpull个队列。 Push队列由您设置并由GAE管理,只能在GAE环境中使用。 Pull队列由您设置和管理,但可以同时驱动GAE和外部应用程序。

到您的应用程序的push队列只不过是一个普通的Web请求,详细信息是GAE是发出实际请求的客户端。您将其要访问的URL及其有效负载,GAE捕获,路由和限制对URL的请求发布到队列。为了向Camel注入请求,如果您可以从Servlet或任意Java类中抽取Camel管道,那么您可以在此处执行此操作。我知道Camel有很多连接器和监听器等,但在这种情况下,你只需要一个简单的,基于代码的注入点。我毫不怀疑Camel可以做到这一点,我只是不能说出细节。

pull队列完全不同。在这里,您将需要一个自由运行的线程,将任务从队列中拉出(使用GAE租用机制)并处理它们。您可能能够利用一些Camel基础结构来创建符合pull队列的线程端点,并让Camel管理整个工具包。但最终,你必须调整线程,管理你想要运行的数量,监控它们,关闭它们等等。因此,与{{1相比,实际上要做的工作还要多一些。队列。如果GAE中的所有内容都是合理的要求,则从内部基础架构的角度来看,push队列更容易。如果您需要一些外部集成,可以通过HTTP请求从外部源提取Push队列。

因此,虽然Camel可能没有开箱即用的功能来管理GAE pull队列,但我认为让现有组件适应这一点非常简单,那么你可以让Camel管理整个事情。如果你已经在这个级别上对Camel感到满意,那么这对你来说可能更容易合作。

对于#2,GAE后端的两个主要好处是稳定性和长寿。普通的实例存在于通用Web应用程序中,适用于负载平衡。 GAE动态地根据流量和响应模式创建和销毁这些实例。但是,在任何特定时间实际运行您的应用程序的零实例是非常可能的,GAE会在看到第一个请求时将其旋转。因此,任何内部(即没有持久存在于DB)管理状态都无法保证具有任何实际生命周期。

后端是您控制下的实例。它们非常像其他云提供商的实例。你启动它,你调整它的大小,你将流量路由到它们,你关闭它们。为此,您可以更好地断言正常运行时间和系统容量。

如果您的请求在CPU时间或资源方面要求不高,则可能不需要后端实例,尤其是pull队列。基本上想象从Web浏览器获取请求,并将信息传递给GAE任务系统。所有GAE要做的就是像任何其他请求一样立即回电。对于您的应用来说,它看起来就像普通的网络流量一样,它并不知道"来自GAE。

因此,如果您同时将1000个请求全部放入队列,GAE将根据需要启动尽可能多的应用实例,以满足桶速率和消息速率。当这1000个请求完成后,GAE将关闭任何安静的实例。就像你突然有1000名访问者一样突然离开你的应用程序。

对于push队列,您几乎需要一个运行时间很长的实例,因为它们实际上是唯一能够处理等待流量的队列中长时间运行的线程的类型。但这意味着你一直在运行,流量还是没有。

对于#3,这大部分是直截了当的。

在最基本的形式中,EJB(我假设你主要是指无状态会话Bean)基本上是一个POJO,其中包含一个包含在事务上下文中的已定义生命周期。您可以非常轻松地复制SSB,因为您可以编写自己的" mini"容器:

pull

在10,000英尺处,这是它的要点。幸运的是,你实际上不必自己写这个。 Spring和Guice都可以为您处理大部分内容,特别是注入资源和其他bean。如果您不大量(或根本不)使用EJB生命周期,拦截器或事务机制,那么也会简化事情。

最后,假设您的SSB中没有静态值,您不必担心线程安全,因为您只需为每个请求创建一个新实例。与Servlets相比,极大地简化了问题。

您还可以查看一个像Stripes或Struts 2这样的体面Action Framework,它提供了很多围绕Web请求的生命周期模式等。可以简化事情。

因此,处理大3.所有这一切,我不是"战斗穿" GAE老手,我的GAE应用程序非常小,并没有使用任何这些技术。它全部都是“学习”'"。

答案 1 :(得分:0)

好吧,我会尽量简洁,易于理解,并按照问题的顺序给出答案。

  1. 任务队列只是URL,Gae将在执行任务时调用 从队列中出来。因此,您必须配置此URL以调用其中一个 您喜欢的后端或前端。 但很重要!你可以 call your backend directly没有使用任务队列
    • push队列中,你推动任务,Gae尽快执行。
    • pull队列中,您必须配置要执行任务的时间。
  2. 正如我之前所说,如果你打电话给后端或前端取决于 要执行的任务,60秒是实际限制 前端电话,这对很多任务都很重要。
  3. 由于Gae不支持EJB,如果您熟悉的话 基于组件的框架(如EJB),你必须寻找另一个框架 一,这里有一些选择,但还有更多:
  4. 无论你做什么同步请求,你都必须在请求中执行所有任务 上下文或将失去与客户的联系。