0

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

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

所以 Web 服务my-ws.war(及时),或者它将它们路由到一个队列,在那里它们被我的基于 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/模块化业务逻辑?

此外,如果有人认为尝试将我的正常架构映射到 GAE 有任何内在错误,请大声说出来,让我知道是什么/为什么!提前致谢!

4

2 回答 2

0

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

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

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

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

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

因此,虽然 Camel 可能没有开箱即用的能力来管理 GAEpull队列,但我敢打赌,调整现有组件来处理这个问题非常简单,然后你可以让 Camel 管理整个事情。如果您已经在这个级别上对 Camel 感到满意,那么这对您来说可能更容易使用。

对于#2,GAE 后端的两个主要好处是稳定性和寿命。普通实例作为通用 Web 应用程序存在,适用于负载平衡。GAE 根据流量和响应模式动态创建和销毁这些实例。但是很有可能在任何特定时间实际运行的应用程序实例为零,GAE 在看到第一个请求时会启动它们。因此,任何内部(即未保存在数据库中)托管状态都不能保证具有任何实际寿命。

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

如果您的请求在 CPU 时间或资源方面不是特别苛刻,您可能不需要后端实例,尤其是push队列。基本上想象从 Web 浏览器获取请求,并将信息传递给 GAE 任务系统。GAE 要做的就是像任何其他请求一样立即回拨。对你的应用来说,它看起来就像正常的网络流量,它不“知道”它来自 GAE。

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

对于pull队列,您几乎需要一个长时间运行的实例,因为它们确实是唯一一种可以处理位于队列中等待流量的长时间运行的线程。但这意味着您一直在运行,无论是否有流量。

对于#3,这主要是直截了当的。

在最基本的形式中,EJB(我假设您主要指的是无状态会话 Bean)基本上是一个 POJO,其定义的生命周期包装在事务上下文中。您可以相当容易地复制 SSB,因为您可以编写自己的“迷你”容器:

YourTrnCtx ctx = startNewTransaction();
registerContextToThread(ctx);
YourBean b = new YourBean();
injectResources(b);
b.start();
b.service();
b.end();
commitTransaction(ctx);

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

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

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

这样就可以处理大 3。总而言之,我不是“身经百战”的 GAE 老手,我的 GAE 应用程序很小,并且没有使用任何这些技术。这都是“书本学习”。

于 2012-09-26T04:36:23.363 回答
0

好吧,我会尽量简明扼要,易于理解,并将答案按您问题的相同顺序排列。

  1. 任务队列只是URL当任务从队列中取出时 Gae 会调用的。因此,您必须将其配置URL为根据需要调用您的后端或前端之一。但是很重要!您可以 直接调用后端而不使用任务队列。
    • 推送队列中,您推送任务,Gae 会尽快执行它。
    • 队列中,您必须配置要执行任务的时间。
  2. 正如我之前所说,如果您调用后端或前端取决于您要执行的任务,60 秒是前端调用的实际限制,对于许多任务来说很多。
  3. 由于 Gae 不支持 EJB,如果您熟悉基于组件的框架(如 EJB),则必须寻找另一种,这里有一些选项,但还有更多:

无论您为同步请求做什么,您都必须在请求上下文中完成所有任务,否则将失去与客户端的连接。

于 2012-09-27T10:31:06.273 回答