长时间运行的Web服务架构

发布于 2024-08-13 09:28:34 字数 420 浏览 9 评论 0原文

我们使用 axis2 来构建 Web 服务,并使用 Jboss 服务器来运行所有应用程序的逻辑。我们被要求构建一个与 Bean 对话的 Web 服务,该 Bean 可能需要长达 1 小时才能响应(取决于请求的大小),因此我们无法在这段时间内保持与消费者的连接打开。

我们可以使用异步 Web 服务,但效果还不是很好,因此我们决定可以实现一个 bean,该 bean 将执行 Web 服务背后的逻辑,并让服务异步调用该 bean。 Web 服务将生成一个令牌,该令牌将传递给消费者,消费者可以使用它来查询请求的状态。

我的问题是:

  1. 一旦我从创建该 bean 的服务中的方法返回,如何查询 Jboss 服务器上该 bean 的状态。我需要使用有状态 Bean 吗?
  2. 如果我想从 Web 服务端进行异步调用,我可以使用有状态 Bean 吗?

We use axis2 for building our webservices and a Jboss server to run the logic of all of our applications. We were asked to build a webservice that talks to a bean that could take up to 1 hour to respond (depending on the size of the request) so we would not be able to keep the connection with the consumers opened during that time.

We could use an asynchronous webservice but that hasn't come out all that well so we decided we could implement a bean that will do the logic behind the webservice and have the service invoke that bean asynchronously. The webservice will generate a token that will pass to the consumer and the consumer can use it to query the status of the request.

The questions I have are:

  1. How to I query the status of the bean on the Jboss server once I have returned from the method in the service that created that bean. Do I need to use stateful beans?
  2. Can I use stateful beans if I want to do asynchronous calls from the webservice side?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

耀眼的星火 2024-08-20 09:28:34

您可以采取的另一种方法是使用 JMS 和数据库。

该过程将是:

  1. 在 Web 服务调用中,将消息放入 JMS 队列中
  2. 将记录插入数据库表中,并将该记录的唯一 id 返回给客户端
  3. 在侦听队列的 MDB 中,调用 bean
  4. 当 bean返回,用“完成”状态更新数据库记录
  5. 当客户端调用状态时,读取数据库记录,根据记录返回“未完成”或“完成”。
  6. 当客户端调用并且记录显示“Done”时,返回“Done”并删除记录

此过程对资源使用量较大,但有一些优点

  • 如果您的 bean 方法抛出异常,持久 JMS 队列将重新交付
  • 持久 JMS如果服务器重新启动,队列将重新传送
  • 通过使用数据库表而不是某些静态数据,您可以支持集群或负载平衡环境

Another approach you could take is to make use of JMS and a DB.

The process would be

  1. In web service call, put a message on a JMS Queue
  2. Insert a record into a DB table, and return a unique id for that record to the client
  3. In an MDB that listens to the Queue, call the bean
  4. When the bean returns, update the DB record with a "Done" status
  5. When the client calls for status, read the DB record, return "Not Done" or "Done" depending on the record.
  6. When the client calls and the record indicates "Done", return "Done" and delete the record

This process is a bit heavier on resource usage, but has some advantages

  • A Durable JMS Queue will redeliver if your bean method throws an Exception
  • A Durable JMS Queue will redeliver if your server restarts
  • By using a DB table instead of some static data, you can support a clustered or load balanced environment
悲歌长辞 2024-08-20 09:28:34

我不认为有状态会话 bean 是您问题的答案,它们是为长时间运行的会话会话而设计的,这不是您的场景。

我的建议是使用 Java5 风格 ExecutorService 线程池,使用 Executors工厂类:

  1. 当Web服务服务器初始化时,创建一个ExecutorService实例。
  2. Web 服务调用进来,处理程序创建 可调用。 Callable.call() 方法将以任何形式对业务逻辑 bean 进行实际调用。
  3. 此 Callable 被传递给 ExecutorService.submit(),后者立即返回表示调用最终结果的 Future 对象。 Executor 将开始在单独的线程中调用您的 Callable
  4. 生成一个随机令牌,将 Future 存储在 Map 中,并以令牌作为密钥。
  5. 将令牌返回给 Web 服务客户端(步骤 1 到 4 应该立即发生)
  6. 稍后,Web 服务客户端再次调用请求结果,并传入令牌。
  7. 服务器使用以下命令查找 Future:令牌,并在 Future 上调用 get(),并设置超时值,以便它只等待很短的时间来获取答案。 get() 调用将返回任何 Callable 调用的执行结果。
    • 如果答案可用,请将其返回给客户端,并从“Map”中删除Future
    • 否则,请告诉客户稍后再来。

这是一个非常稳健的方法。如果您愿意,您甚至可以配置 ExecutorService 来限制可以同时执行的调用数量。

I don't think stateful session beans are the answer to your problem, they're designed for long-running conversational sessions, which isn't your scenario.

My recommendation would be to use a Java5-style ExecutorService thread pool, created using the Executors factory class:

  1. When the web service server initializes, create an ExecutorService instance.
  2. Web service call comes in, the handler creates an instance of Callable. The Callable.call() method would make the actual invocation on the business logic bean, in whatever form that takes.
  3. This Callable is passed to ExecutorService.submit(), which immediately returns a Future object representing the eventual result of the call. The Executor will start to invoke your Callable in a separate thread.
  4. Generate a random token, store the Future in a Map with the token as the key.
  5. Return the token to the web service client (steps 1 to 4 should happen immediately)
  6. Later, he web service client makes another call asking for the result, passing in the token
  7. The server looks up the Future using the token, and calls get() on the Future, with a timeout value so that it only waits a short time for the answer. The get() call will return the execution result of whatever the Callable invoked.
    • If the answer is available, return it to the client, and remove the Future from the `Map.
    • Otherwise, tell the client to come back later.

It's a pretty robust approach. You can even configure the ExecutorService to limit the number of calls that can be in execution at the same time, if you so desire.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文