什么是异步JAX-RS的目的 [英] What is the purpose of asynchronous JAX-RS

查看:221
本文介绍了什么是异步JAX-RS的目的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在读REST风格的Java与JAX-RS 2.0一书。我与异步JAX-RS完全糊涂了,于是我问一个所有的问题。书中写道:异步服务器是这样的:

  @Path(/用户)
公共类CustomerResource {    @得到
    @Path((编号))
    @Produces(MediaType.APPLICATION_XML)
    公共无效getCustomer(@Suspended最终AsyncResponse asyncResponse,
                            @Context最后请求的要求,
                            @PathParam(值=ID)最终诠释的id){        新的Thread(){
            @覆盖
            公共无效的run(){
                asyncResponse.resume(Response.ok(新用户(ID))建立());
            }
        }。开始();
    }
}

Netbeans的创建异步服务器是这样的:

  @Path(/用户)
公共类CustomerResource {
    私人最终ExecutorService的ExecutorService的= java.util.concurrent.Executors.newCachedThreadPool();    @得到
    @Path((编号))
    @Produces(MediaType.APPLICATION_XML)
    公共无效getCustomer(@Suspended最终AsyncResponse asyncResponse,
                            @Context最后请求的要求,
                            @PathParam(值=ID)最终诠释的id){        executorService.submit(新的Runnable(){
            @覆盖
            公共无效的run(){
                doGetCustomer(ID);
                asyncResponse.resume(javax.ws.rs.core.Response.ok()建立());
            }
        });
    }    私人无效doGetCustomer(@PathParam(值=ID)最终诠释的id){
    }
}

那些不创建后台线程使用一些锁定方法来存储响应对象以便进一步处理。这个例子是用于发送股票报价给客户:

  @Path(qoute / RHT)
公共类RHTQuoteResource {    保护列表与LT; AsyncResponse>响应;    @得到
    @Produces(text / plain的)
    公共无效的getQuote(@Suspended AsyncResponse响应){
        同步(响应){
            responses.add(响应);
        }
    }
}

响应对象将一些后台作业共享,它会发送报价给所有客户端时,它已准备就绪。

我的问题:


  1. 在例1和2的W​​eb服务器线程(即处理请求的)死亡
    我们创建另一个后台线程。背后的整个思路
    异步服务器是减少空闲线程。这些实施例
    不降低空闲线程。一个线程死了,另一个出生。

  2. 我想过创造容器内非托管线程是一个坏主意。
    我们应该只使用管理线程并发使用公用事业
    的Java EE 7。

  3. 的想法背后异步服务器再一个是规模。例3不结垢,对吧?


解决方案

摘要:你过想这



  

在例1和2的W​​eb服务器线程(即处理请求的)死亡,我们创建另一个后台线程。背后异步服务器的整体思路是减少空闲线程。这些实施例不减少空闲线程。一个线程死了,另一个出生。


也不是特别大,说实话。在生产服务,你不会持有这样的私人领域的执行者,而是将它作为一个单独配置对象(例如,它自己的Spring bean)。在另一方面,这样一个复杂的例子是相当困难为你没有更多的背景下理解;这包括豆类系统应用/管理的资源,必须建立以从地上爬起来的方式。这也是不是很重要的小规模工作要非常小心这一点,而这是一个的很多的Web应用程序。

的握持手感是从服务器上重新启动恢复实际上是不是担心太多摆在首位。如果服务器重新启动,你可能会失去所有的连接,无论如何,如果这些 AsyncResponse 的对象不是序列化中某种方式(没有保证,他们是或者不是),不能将它们存储在数据库中,以便恢复。最好不要担心,因为没有太多可以做的太过分了! (客户端也将一段时间后超时,如果他们没有得到任何答复回来;你不能无限期持有他们)


  

我想创建容器内非托管线程是一个坏主意。我们应该只使用使用并发性工具管理线程的Java EE 7。


这是一个例子!从外部供应执行人但是你想为你的想象的生产系统。


  

思想背后异步服务器再一个是规模。例3不结垢,对吧?


这只是一个列表,这是不是一个非常缓慢的操作可言,尤其是与所有的网络和反序列化的成本/序列回事相比上进行排队的对象。什么它不显示是拿东西关闭该列表,执行处理,并产生结果返回应用程序的其他部分;它们可以执行不力而导致的问题,或者他们可能做仔细和系统的正常工作。

如果您可以在code做的更好,的通过各种手段做到这一点的。 (要知道,你不能工作项目存储在数据库中,或者至少你不能确切知道你能做到这一点,即使它正好是实际上是可能的,虽然我怀疑它;有可能的信息关于那里的TCP网络连接,这是不容易保存和完全恢复。)

I'm reading "RESTful Java with JAX-RS 2.0" book. I'm completely confused with asynchronous JAX-RS, so I ask all questions in one. The book writes asynchronous server like this:

@Path("/customers")
public class CustomerResource {

    @GET
    @Path("{id}")
    @Produces(MediaType.APPLICATION_XML)
    public void getCustomer(@Suspended final AsyncResponse asyncResponse,
                            @Context final Request request,
                            @PathParam(value = "id") final int id) {

        new Thread() {
            @Override
            public void run() {
                asyncResponse.resume(Response.ok(new Customer(id)).build());
            }
        }.start();
    }
}

Netbeans creates asynchronous server like this:

@Path("/customers")
public class CustomerResource {
    private final ExecutorService executorService = java.util.concurrent.Executors.newCachedThreadPool();

    @GET
    @Path("{id}")
    @Produces(MediaType.APPLICATION_XML)
    public void getCustomer(@Suspended final AsyncResponse asyncResponse, 
                            @Context final Request request,
                            @PathParam(value = "id") final int id) {

        executorService.submit(new Runnable() {
            @Override
            public void run() {
                doGetCustomer(id);
                asyncResponse.resume(javax.ws.rs.core.Response.ok().build());
            }
        });
    }

    private void doGetCustomer(@PathParam(value = "id") final int id) {
    }
}

Those that do not create background threads use some locking methods to store response objects for further processing. This example is for sending stock quotes to clients:

@Path("qoute/RHT")
public class RHTQuoteResource {

    protected List<AsyncResponse> responses;

    @GET
    @Produces("text/plain")
    public void getQuote(@Suspended AsyncResponse response) {
        synchronized (responses) {
            responses.add(response);
        }
    }
}

responses object will be shared with some background jobs and it will send quote to all clients when it is ready.

My questions:

  1. In example 1 and 2 web server thread(the one that handle request) dies and we create another background thread. The whole idea behind asynchronous server is to reduce idle threads. These examples are not reducing idle threads. One threads dies and another one born.
  2. I thought creating unmanaged threads inside container is a bad idea. We should only use managed threads using concurrency utilities in Java EE 7.
  3. Again one of ideas behind async servers is to scale. Example 3 does not scale, does it?

解决方案

Executive Summary: You're over-thinking this.


In example 1 and 2 web server thread(the one that handle request) dies and we create another background thread. The whole idea behind asynchronous server is to reduce idle threads. These examples are not reducing idle threads. One threads dies and another one born.

Neither is particularly great, to be honest. In a production service, you wouldn't hold the executor in a private field like that but instead would have it as a separately configured object (e.g., its own Spring bean). On the other hand, such a sophisticated example would be rather harder for you to understand without a lot more context; applications that consist of systems of beans/managed resources have to be built to be that way from the ground up. It's also not very important for small-scale work to be very careful about this, and that's a lot of web applications.

The gripping hand is that the recovery from server restart is actually not something to worry about too much in the first place. If the server restarts you'll probably lose all the connections anyway, and if those AsyncResponse objects aren't Serializable in some way (no guarantee that they are or aren't), you can't store them in a database to enable recovery. Best to not worry about it too much as there's not much you can do! (Clients are also going to time out after a while if they don't get any response back; you can't hold them indefinitely.)

I thought creating unmanaged threads inside container is a bad idea. We should only use managed threads using concurrency utilities in Java EE 7.

It's an example! Supply the executor from outside however you want for your fancy production system.

Again one of ideas behind async servers is to scale. Example 3 does not scale, does it?

It's just enqueueing an object on a list, which isn't a very slow operation at all, especially when compared with the cost of all the networking and deserializing/serializing going on. What it doesn't show is the other parts of the application which take things off that list, perform the processing, and yield the result back; they could be poorly implemented and cause problems, or they could be done carefully and the system work well.

If you can do it better in your code, by all means do so. (Just be aware that you can't store the work items in the database, or at least you can't know for sure that you can do that, even if it happens to be actually possible. I doubt it though; there's likely information about the TCP network connection in there, and that's never easy to store and restore fully.)

这篇关于什么是异步JAX-RS的目的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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