使用异步Servlet和派遣()和完整的()方法的行为,而处理请求 [英] Using Asynchronous Servlets and the behaviour of dispatch() and complete() methods while processing request

查看:139
本文介绍了使用异步Servlet和派遣()和完整的()方法的行为,而处理请求的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的异步servlet来处理请求,

据文件:( 完整()讯( )

<$p$p><$c$c>╔══════════════════╦═══════════════════════════════════════════════════════════╗
║无效完成()║完成异步操作并关闭║
║║与此异步上下文关联的响应。 ║
║║你写入响应对象后调用此方法║
║异步上下文中║。 ║
╠══════════════════╬═══════════════════════════════════════════════════════════╣
║无效讯()║调度请求和响应对象║
║║这AsyncContext到servlet容器中。 ║
╚══════════════════╩═══════════════════════════════════════════════════════════╝

我不明白异步。调度()异步.complete(),以及它们如何工作
我对此有一些疑虑:


  1. 什么之间async.dispatch()完全相同的差异 async.complete()

  2. 当我打电话给调度()(里面的run())的响应到达客户端,这意味着我们可以异步推回应?

  3. 如果我称之为 asyncContext.dispatch()第一和 asyncContext.complete()接下来是什么行为线程?

  4. 如果我打电话后,任何方法 asyncContext.complete(),会发生什么是方法调用,如下图所示code(在相同的运行())?
    [当我测试这个它的正常工作,并显示出相同的线程ID]

  5. 如果我打电话里面异步方法的run()我应该需要完成 asyncContext.complete()内<一href=\"http://docs.guava-libraries.google$c$c.com/git/javadoc/com/google/common/util/concurrent/Futures.html#addCallback%28com.google.common.util.concurrent.ListenableFuture,%20com.google.common.util.concurrent.FutureCallback%29\"相对=nofollow>回调()? (的onSuccess()或者onFailure处())

  6. 无论任何帮助(例如源/书籍/联机帮助)提供有关本? (异步Servlet和期货组合)

     最后FutureCallback&LT;无效&GT; calculateTime =新CustomFuture&LT;&GT;(计算);
     //启动异步上下文。
     最终AsyncContext asyncContext = request.startAsync();  asyncContext.start(新的Runnable(){
            @覆盖
            公共无效的run(){            MYOBJECT对象= NULL;
                尝试{
                    对象= myFactory.create();
                    //调度异步上下文
                    asyncContext.dispatch(对象创建成功);
                }赶上(最终IOException异常E1){
                    logger.error(记录错误);
                }
                asyncContext.complete(); //完整的背景下异步            //调用异步方法
                最后ListenableFuture&LT;无效&GT;未来= myService.doSomething();            Futures.addCallback(未来,calculateTime);
                //调用asyncContext.complete()在这里是否行得通呢?
            }
        });

    先谢谢了。



解决方案

从马的嘴(甲骨文的Javadoc)

完成()

完成对启动上用于initialze这个AsyncContext的要求,关闭被用于初始化这个AsyncContext的响应异步操作。

这是与创建此AsyncContext将在他们的onComplete方法被调用的ServletRequest注册类型AsyncListener的任何侦听器。

讯(字符串路径)

调度此AsyncContext给定路径的请求和响应的对象。

...

在请求控制和响应委托给调度目标,当目标调度执行完毕的响应将被关闭,除非的ServletRequest#startAsync()或ServletRequest中#startAsync(的ServletRequest,ServletResponse的)被调用。

Q / A


  1. 什么的区别调度完整

    调用完整告诉容器以的onComplete 听众和停止异步模式下,调度基本上告诉容器调用完整,然后将请求转发(内部)到指定的路径。路径可以是一个JSP,同步servlet或甚至另一个异步的servlet,这将引发新一轮的异步处理的。


  2. 当我打电话调度运行响应到达客户端,这是否意味着我们可以把响应异步这样?

    相反调度关闭asynchrnonous模式,将请求转发到另一个servlet或JSP。为了将数据推送到你写响应客户端 AsyncContext


  3. 如果我叫调度第一和完整接下来是什么线程的行为?

    不定,这是说的一个很好的方式,它取决于容器是如何实现的。也许它会抛出一个错误,也许的onComplete 处理程序将被两次开除,也许来电完整会做什么,也许会有你的线程,并呼吁处理程序和操纵 AsyncContext 实施等内部结构的容器之间的竞争条件。


  4. 如果我打电话后,任何方法完整会发生这种方法叫什么

    取决于你正在调用什么方法。该规范规定调度将抛出 IllegalStateException异常后,如果称为完全,别的是不确定的,因此具体执行。


  5. 如果我打电话运行里面的异步方法我应该叫完整里面的回调()<? / H3>

    是你要调用完整一旦你完成完成异步处理。在运行方法用于计划任务由一个容器管理的线程池来执行,它可以被多次调用异步请求的生命周期中。


  6. 是否有

    使用异步Servlet和期货组合的例子吗?

    我不知道任何,但也有使用参见部分挂钩异步的servlet的一些很好的例子。原则上我看不出使用期货多大价值。请参见:是异步的servlet非常适合我在做什么


是异步的servlet非常适合我在做什么?

异步Servlet的目标是减少对服务于某些类型的推客户端的所需线程数:HTTP直到一个(通常是外部的)事件发生时,请求被保持打开,然后服务器将数据推走在信道。在一个标准的servlet环境中的每个客户都会有一个专门的线程分配,并等待从而节省宝贵的系统资源。在异步模式中,客户端连接可以直到一个事件进来,这使得它能够用它做什么放在暂停和拆卸从执行线程。想想一个在线聊天应用程序为例。所有连接的客户端将被闲置,直到有人将消息放到了房间。这是一种浪费,保持一个专用的线程为每个连接的用户。

如果您的应用程序需要同时调用多个服务,并要使用期货和执行人并行的操作,然后异步的servlet可能不是一个很好的配合:你将一无所获和标准的servlet会容易得多实现。如果对服务呼叫可以在异步(非阻塞)的方式进行,不依赖于螺纹执行人另一方面,则又是另一回事。

正确的问题要问的是:我想有比活动连接线程较少


另请参阅:

I am using Asynchronous Servlets to process requests,

According to Docs:(complete(),dispatch())

╔══════════════════╦═══════════════════════════════════════════════════════════╗
║ void complete()  ║ Completes the asynchronous operation and closes the       ║
║                  ║ response associated with this asynchronous context.       ║
║                  ║ You call this method after writing to the response object ║
║                  ║ inside the asynchronous context.                          ║ 
╠══════════════════╬═══════════════════════════════════════════════════════════╣
║ void dispatch()  ║ Dispatches the request and response objects               ║
║                  ║ of this AsyncContext to the servlet container.            ║
╚══════════════════╩═══════════════════════════════════════════════════════════╝

I failed to understand async.dispatch(), async.complete(), and how they work.
I have few doubts on this:

  1. What exactly the difference between async.dispatch() and async.complete()?
  2. When I called dispatch()(inside run()) the response reaches the client, that mean we can push the response asynchronously?
  3. if I call asyncContext.dispatch() first and asyncContext.complete() next what is the behaviour of the thread?
  4. If I call any method after asyncContext.complete(), what will happen to that method call, as shown below code(in the same run())?
    [when I tested this it's working fine and showing same thread id]
  5. If I am calling Asynchronous methods inside run() should I need to complete asyncContext.complete() inside callback()? (onSuccess() or onFailure())
  6. Whether any help(example source/books/online help) available regarding this? (Async Servlets and Futures Combination)

    final FutureCallback<Void> calculateTime= new CustomFuture<>(calculate);
     // start Async context.
     final AsyncContext asyncContext = request.startAsync();
    
      asyncContext.start(new Runnable() {
            @Override
            public void run() {
    
                MyObject object= null;
                try {   
                    object= myFactory.create();
                    //dispatch async context
                    asyncContext.dispatch("Object Successfully Created"); 
                } catch (final IOException e1) {
                    logger.error("logging error");      
                }
                asyncContext.complete(); //complete async context
    
                // call asynchronous method
                final ListenableFuture<Void> future = myService.doSomething();
    
                Futures.addCallback(future, calculateTime);
                // calling asyncContext.complete() here will work?
            }
        });
    

    Thanks in Advance.

解决方案

From the horse's mouth (Oracle Javadoc)

complete()

Completes the asynchronous operation that was started on the request that was used to initialze this AsyncContext, closing the response that was used to initialize this AsyncContext.

Any listeners of type AsyncListener that were registered with the ServletRequest for which this AsyncContext was created will be invoked at their onComplete method.

dispatch(String path)

Dispatches the request and response objects of this AsyncContext to the given path.

...

Control over the request and response is delegated to the dispatch target, and the response will be closed when the dispatch target has completed execution, unless ServletRequest#startAsync() or ServletRequest#startAsync(ServletRequest, ServletResponse) are called.

Q/A

  1. what's the difference between dispatch and complete?

    Calling complete tells container to fire onComplete listeners and stop the asynchronous mode, dispatch basically tells container to call complete and then forward the request (internally) to the specified path. The path can be a JSP, a synchronous servlet or even another asynchronous servlet that will trigger a new round of async processing.

  2. When I called dispatch inside run the response reached the client, does that mean we can push the response asynchronously like this?

    On the contrary dispatch closes the asynchrnonous mode and forwards the request to another servlet or JSP. To push data to the client you have to write to Response object associated with the AsyncContext.

  3. if I call dispatch first and complete next what is the behaviour of the thread ?

    Undefined, which is a nice way of saying it depends on how the container is implemented. Maybe it will throw an error, maybe onComplete handlers will be fired twice, maybe call to complete will do nothing, maybe there will be a race condition between your thread and the container in calling handlers and manipulating internal structures of AsyncContext implementation etc.

  4. If I call any method after complete what will happen to that method call

    Depends on what method you are calling. The specification states that dispatch will throw IllegalStateException if called after complete, anything else is undefined and thus implementation specific.

  5. If I am calling asynchronous methods inside run should I call complete inside callback()?

    Yes you have to call complete to finish asynchronous processing once you are done. The run method is used to schedule a task to be executed by a container managed thread pool and it can be called multiple times during the lifetime of an asynchronous request.

  6. Are there any examples of using Async Servlets and Futures Combination?

    I am not aware of any, but there are a few good examples of using async servlets linked in "See also" section. In principle I don't see much value in using futures. See: "Is async servlet a good fit for what I am doing?"

Is async servlet a good fit for what I am doing ?

The objective of an async servlet is to reduce the number of threads required to serve certain types of "push clients": HTTP request is left open until an (usually external) event occurs and then the server will push data down the channel. In a standard servlet environment each client will have a dedicated thread allocated and waiting thus consuming valuable system resources. In asynchronous mode the client connection can be put "on hold" and detached from an execution thread until an event comes in which makes it possible to do something with it. Think about an online chat application as an example. All connected clients will be idle until someone posts a message to the room. It is wasteful to keep a dedicated thread for every connected user.

If your application needs to call multiple services at the same time and you wish to use futures and executors to parallelize that operation then an asynchronous servlet is probably not a good fit: You will gain nothing and a standard servlet will be much easier to implement. On the other hand if service calls can be made in an asynchronous (non-blocking) way, without relying on threaded executors, then it's another story.

The "right" question to ask is: Do I want to have fewer threads than active connections?


See also:

这篇关于使用异步Servlet和派遣()和完整的()方法的行为,而处理请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆