REST dengan JAX-RS - Menangani operasi yang berjalan lama

Saya memiliki layanan REST yang diimplementasikan dengan JAX-RS. Beberapa operasi membutuhkan waktu lama untuk diselesaikan, mungkin 15-30 menit. Untuk kasus ini, kecenderungan saya adalah mengirimkan thread latar belakang untuk memproses operasi yang berjalan lama dan kemudian segera merespons dengan status HTTP 202 DITERIMA. Responsnya akan berisi header lokasi dengan url yang dapat digunakan klien untuk melakukan polling kemajuan.

Pendekatan ini memerlukan pembuatan thread untuk menangani operasi yang berjalan lama, sehingga 202 ACCEPTED dapat segera dikembalikan. Saya juga tahu bahwa membuat utas Anda sendiri dalam wadah Java EE umumnya merupakan praktik yang buruk!

Pertanyaan saya adalah sebagai berikut:

  1. Apakah orang-orang setuju bahwa ini adalah pendekatan yang benar?
  2. Dengan asumsi itu benar, Dapatkah orang merekomendasikan solusi 'praktik yang baik' yang memungkinkan saya untuk menjalankan operasi yang berjalan lama di latar belakang dan segera kembali?

Selain itu, untuk menghindari pengelolaan thread saya sendiri, saya melihat api server asinkron JAX-RS. Sayangnya, meskipun hal ini meningkatkan throughput server, hal ini tidak memungkinkan saya untuk langsung merespons dengan ACCEPTED.

Jersey menyatakan sebagai berikut:

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.

Bantuan apa pun dihargai. Terima kasih!


person cmd    schedule 13.09.2013    source sumber


Jawaban (3)


Menurut saya dokumen Jersey Async cukup menguras topik Sehat. Berikut cuplikan singkatnya:

@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!");
                } });
  }
}

Mengenai kutipan berikut dari dokumen:

Perhatikan bahwa penggunaan model pemrosesan asinkron sisi server tidak akan meningkatkan waktu pemrosesan permintaan yang dirasakan oleh klien.(...)

Saya kira Anda sedikit salah memahaminya. Apa yang coba diungkapkan oleh penulis dokumen di sini adalah bahwa pemrosesan asinkron tidak akan mempercepat segalanya dengan sendirinya. Namun responsnya dapat segera dikembalikan menggunakan contoh berikut:

return Response.status(Status.ACCEPTED).build();
person Wojtek Owczarczyk    schedule 05.03.2014
comment
Mengembalikan 202 tidak akan menjangkau klien. Saya benar-benar mencobanya! - person Vishnu G S; 02.11.2016
comment
Tidak bekerja. Seharusnya bukan jawaban yang diterima. Jawaban Sotirios Delimanolis benar. - person ccleve; 19.05.2017
comment
Setuju - ini tidak menjawab pertanyaan. Pemohon menginginkan kode untuk mengembalikan 202 dari metodenya. - person cs94njw; 11.04.2018

Saya juga tahu bahwa membuat thread Anda sendiri di container Java EE umumnya merupakan praktik yang buruk!

Meskipun hal di atas benar dalam banyak kasus, dalam hal ini Anda tidak punya pilihan. Setidaknya jangan membuat Thread instance Anda sendiri. Biarkan ExecutorService melakukannya untuk Anda. Jika ada, buat ExecutorService ini memiliki kumpulan yang cukup besar dan bagikan dengan semua komponen Anda.

person Sotirios Delimanolis    schedule 13.09.2013
comment
Terima kasih. Saya setuju sesuatu yang diberkati seperti ExecutorService harus digunakan untuk mengelola utas. Saya masih merasa mual untuk mengirim mereka. Selain itu, saya menggunakan EJB dan spesifikasi EJB menyatakan: • Enterprise bean tidak boleh mencoba mengelola thread. Kacang perusahaan tidak boleh mencoba memulai, menghentikan, menangguhkan, atau melanjutkan thread, atau mengubah prioritas atau nama thread. Kacang perusahaan tidak boleh mencoba mengelola grup thread. Bisakah runnable saya menjadi kacang sesi Stateful? Mungkin ya? Bisakah kelas yang menggunakan ExecutorService untuk mengirimkan thread menjadi Stateless Singleton? TIDAK? - person cmd; 13.09.2013
comment
@cmd Dengan EJB, mungkin lihat ini - person Sotirios Delimanolis; 13.09.2013
comment
Terima kasih, ini cukup dekat dengan tujuanku. - person cmd; 14.09.2013
comment
@SotiriosDelimanolis Silakan lihat ini dan bantuan. Terima kasih atas waktunya. stackoverflow.com/ pertanyaan/19706788/ - person Kumar; 06.11.2013

Saya akan membuat metode yang segera mengembalikan respons dengan id proses dan waktu penyelesaiannya. Penghitungan dimulai di latar belakang dan disimpan dalam cache selama beberapa waktu setelah selesai. Kemudian klien mencoba mengambil informasi dengan id tertentu dan mendapat respons terkait.

person Justinas Jakavonis    schedule 06.05.2016