长期运行的Web服务架构

时间:2009-12-02 20:42:27

标签: java web-services jboss axis2 long-running-processes

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

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

我的问题是:

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

2 个答案:

答案 0 :(得分:3)

您可以采用的另一种方法是使用JMS和DB。

过程将是

  1. 在Web服务调用中,在JMS队列上放置消息
  2. 将记录插入数据库表,并将该记录的唯一ID返回给客户端
  3. 在侦听队列的MDB中,调用bean
  4. 当bean返回时,以“完成”状态更新数据库记录
  5. 当客户端呼叫状态时,请阅读数据库记录,根据记录返回“未完成”或“完成”。
  6. 当客户致电并且记录显示“完成”时,返回“完成”并删除记录
  7. 这个过程在资源使用上有点重,但有一些优点

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

答案 1 :(得分:1)

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

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

  1. 当Web服务器初始化时,创建一个ExecutorService实例。
  2. 进入Web服务调用,处理程序创建Callable的实例。 Callable.call()方法将以任何形式对业务逻辑bean进行实际调用。
  3. Callable传递给ExecutorService.submit(),它会立即返回表示调用最终结果的Future对象。 Executor将开始在单独的帖子中调用您的Callable
  4. 生成随机令牌,将Future存储在Map中,并将令牌作为密钥。
  5. 将令牌返回给Web服务客户端(步骤1到4应立即发生)
  6. 后来,他的Web服务客户端再次打电话询问结果,传递令牌
  7. 服务器使用令牌查找Future,并使用超时值调用get()上的Future,以便它只等待很短的时间才能得到答案。 get()调用将返回调用Callable的执行结果。
    • 如果答案可用,请将其返回给客户端,然后从“地图”中删除Future
    • 否则,请告诉客户稍后再回来。
  8. 这是一种非常强大的方法。如果您愿意,您甚至可以配置ExecutorService以限制可以同时执行的呼叫数。