15

I have a REST service implemented with JAX-RS. Some of the operations take a long time to complete, potentially 15-30 minutes. For these cases, my inclination is to dispatch a background thread to process the long running operation and then respond immediately with HTTP status 202 ACCEPTED. The response would contain a location header with a url that clients can use to poll for progress.

This approach requires the creation of threads to handle long running operations, such that 202 ACCEPTED can be returned immediately. I also know that that creating your own threads in a Java EE container is generally bad practice!

My questions are as follows:

  1. Do folks agree that this is a correct approach?
  2. Assuming it is correct, Can folks recommend a 'good practice' solution that enables me to dispatch a long running operation in the background and return immediately?

Also, to avoid managing my own threads, I looked into the JAX-RS asynchronous server api. Unfortunately, although this improves server throughput, it will not allow me to respond immediately with ACCEPTED.

Jersey states the following:

Note that the use of server-side asynchronous processing model will not improve the 
request processing time perceived by the client. It will however increase the
throughput of the server, by releasing the initial request processing thread back to
the I/O container while the request may still be waiting in a queue for processing or    
the processing may still be running on another dedicated thread. The released I/O  
container thread can be used to accept and process new incoming request connections.

Any help is appreciated. Thanks!

4

3 に答える 3

5

また、Java EE コンテナー内に独自のスレッドを作成することは、一般的に悪い習慣であることも知っています。

上記はほとんどの場合に当てはまりますが、この場合は選択の余地がありません。少なくとも自分でThreadインスタンスを作成しないでください。あなたのためにExecutorServiceやらせてください。どちらかといえば、これExecutorServiceに十分な大きさのプールを持たせ、すべてのコンポーネントと共有します。

于 2013-09-13T13:46:03.393 に答える
2

Jersey Async のドキュメントはこのトピックをかなりうまく使い果たしていると思います。ここに簡単なスニペットがあります:

@Path("/async/longRunning")
public class MyResource {

   @GET
   public void longRunningOp(@Suspended final AsyncResponse ar) {
       executor.submit(
            new Runnable() {
                public void run() {
                    executeLongRunningOp();
                    ar.resume("Hello async world!");
                } });
  }
}

ドキュメントからの次の引用に関しては:

サーバー側の非同期処理モデルを使用しても、クライアントが認識するリクエスト処理時間は改善されないことに注意してください。(...)

あなたはそれを少し誤解していると思います。ドキュメントの作成者がここで表現しようとしたことは、非同期処理はそれだけではスピードアップしないということです。ただし、たとえば次のようにすると、すぐに応答を返すことができます。

return Response.status(Status.ACCEPTED).build();
于 2014-03-05T15:03:03.637 に答える
0

プロセスIDと完了時刻を含む応答をすぐに返すメソッドを作成します。計算はバックグラウンドで開始され、完了後しばらくキャッシュされます。次に、クライアントは特定の ID で情報を取得しようとし、関連する応答を取得します。

于 2016-05-06T07:29:23.357 に答える