2013-03-27 60 views
2

Servlet 3.0允许'request'线程(或'main'线程)将长时间运行的处理委托给其他线程,以释放自己接收更多请求。同意。也就是说,我们正在通过利用多线程实现可伸缩性(的请求)。Servlet 3.0:如何将异步处理卸载到不同的JVM?

但是这需要我的'Servlet容器JVM'能够进行这样的处理。 如果我有一个多层体系结构,其中'Servlet容器JVM'只是入口点,而服务请求的逻辑位于其他某个JVM(此后称为“Service JVM”)中的其他位置。

如果我想将传入的'请求'(或至少请求的相关属性)发布到JMS队列并让'请求'被'服务JVM'池中的一个抓取并处理, ?将这个'响应'(比如说JSON)的责任委托给这个服务JVM是不是更好?

我不认为'AsyncContext'可以有意义地传递到Servlet容器JVM的外部。那么,如何真正委托请求处理和响应发送,由分布式服务(JVM)完成呢?

在代码/伪代码方面,我的问题是:

@WebServlet(urlPatterns = "/AsyncServlet", asyncSupported=true) 
public class AsyncServlet extends HttpServlet { 

    protected void doGet(HttpServletRequest request, 
      HttpServletResponse response) 
     throws ServletException, IOException { 

     AsyncContext asyncCtx = request.startAsync(); 
     // Put the asyncCtx in a JMS queue so as to be picked by another 
     // service JVM that can really service this request. 
     // return back to receiving requests and dont worry abt sending a response 
     // The service JVM will take care of sending the appropriate response 
     // as it has the data necessary for the response. 
    } 
} 

一种选择似乎是有工作线程(在Servlet容器JVM)等待从服务的JVM响应。在服务JVM完成实际处理后,它可以将结果(通过消息或其他方式)传递给相应的Worker线程,并让Worker线程发送GET响应。

我想知道是否有(我确定有shd be!)比这更好的选择,因为这看起来很复杂!

+0

您的'AsyncContext'不能等待来自JMS的响应并将其写入响应? – 2013-03-27 21:09:04

+1

你有没有考虑使用EJB的?还有一组后端服务器? – DiogoSantana 2013-03-27 21:14:50

+0

Diogo,或许你对你的建议是正确的。但是,我不熟悉EJB,除了一些半熟的知识,即EJB不好!但是可能你可以指向一个链接,它可以帮助我理解EJB如何解决这个问题? – brainOverflow 2013-03-28 20:38:50

回答

1
  1. 设置上下文异步单豆
  2. 存储上下文发送JMS请求
  3. 过程JMS请求
  4. 发送JMS回复
  5. 从单豆获取答复上下文
  6. 发送回复给客户

您可能想要设置清理计时器,并且可以用异步单向ejb调用替换jms

+0

这听起来和我在问题的最后部分提到的一样。即两跳响应。从真正处理请求的地方到servlet容器线程,再到请求(浏览器)的实际发送者。我正在寻找一个更好的选择。即一跳响应。如果可能的话。 – brainOverflow 2013-03-27 21:29:08

+0

我认为使用不同虚拟机的单跳响应是不可能的,因为第二个虚拟机是OS上的另一个进程,无法将字节(响应)发送到在第一个虚拟机上接收请求的同一个套接字。 – DiogoSantana 2013-03-27 21:32:42

+1

显然你不能序列化套接字连接。考虑WebServices和ws-addressing,如果你想直接从处理jvm发送回复。 – 2013-03-27 21:33:22