REST พร้อม JAX-RS - การจัดการการดำเนินการที่ใช้เวลานาน

ฉันมีบริการ REST ที่ใช้กับ JAX-RS การดำเนินการบางอย่างใช้เวลานานจึงจะเสร็จสมบูรณ์ อาจใช้เวลาประมาณ 15-30 นาที ในกรณีเหล่านี้ ความชอบของฉันคือส่งเธรดพื้นหลังเพื่อประมวลผลการดำเนินการที่ใช้เวลานาน จากนั้นตอบสนองทันทีด้วยสถานะ HTTP 202 ACCEPTED การตอบกลับจะมีส่วนหัวของสถานที่พร้อม URL ที่ลูกค้าสามารถใช้เพื่อสำรวจความคืบหน้า

วิธีการนี้จำเป็นต้องมีการสร้างเธรดเพื่อรองรับการดำเนินการที่รันเป็นเวลานาน ซึ่งสามารถส่งคืน 202 ACCEPTED ได้ทันที ฉันรู้ด้วยว่าโดยทั่วไปแล้วการสร้างเธรดของคุณเองในคอนเทนเนอร์ Java EE ถือเป็นแนวทางปฏิบัติที่ไม่ดี!

คำถามของฉันมีดังนี้:

  1. ผู้คนเห็นพ้องกันว่านี่เป็นแนวทางที่ถูกต้องหรือไม่?
  2. สมมติว่าถูกต้อง ผู้คนสามารถแนะนำโซลูชัน 'แนวปฏิบัติที่ดี' ที่ช่วยให้ฉันสามารถส่งการดำเนินการที่ใช้เวลานานในเบื้องหลังและกลับมาได้ทันทีได้หรือไม่

นอกจากนี้ เพื่อหลีกเลี่ยงการจัดการเธรดของตัวเอง ฉันจึงดู API ของเซิร์ฟเวอร์อะซิงโครนัส JAX-RS น่าเสียดายที่แม้ว่าสิ่งนี้จะปรับปรุงปริมาณงานของเซิร์ฟเวอร์ แต่ก็ไม่อนุญาตให้ฉันตอบกลับทันทีโดยยอมรับแล้ว

เจอร์ซีย์ระบุดังต่อไปนี้:

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.

ความช่วยเหลือใด ๆ ที่ชื่นชม ขอบคุณ!


person cmd    schedule 13.09.2013    source แหล่งที่มา


คำตอบ (3)


ฉันคิดว่า เอกสาร 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();
person Wojtek Owczarczyk    schedule 05.03.2014
comment
การส่งคืน 202 จะไม่เข้าถึงลูกค้า ฉันพยายามแล้วจริงๆ! - person Vishnu G S; 02.11.2016
comment
ไม่ทำงาน, ไม่เป็นผล. ไม่ควรเป็นคำตอบที่ยอมรับ คำตอบของ Sotirios Delimanolis นั้นถูกต้อง - person ccleve; 19.05.2017
comment
ตกลง - นี่ไม่ได้ตอบคำถาม ผู้ขอต้องการรหัสสำหรับส่งคืน 202 จากวิธีการของเขา - person cs94njw; 11.04.2018

ฉันรู้ด้วยว่าโดยทั่วไปแล้วการสร้างเธรดของคุณเองในคอนเทนเนอร์ Java EE ถือเป็นแนวทางปฏิบัติที่ไม่ดี!

แม้ว่าข้อความข้างต้นจะเป็นจริงในกรณีส่วนใหญ่ แต่ในกรณีนี้ คุณไม่มีทางเลือก อย่างน้อยอย่าสร้างอินสแตนซ์ Thread ของคุณเอง ให้ ExecutorService ทำเพื่อคุณ หากมีสิ่งใด ให้ทำให้ ExecutorService มีพูลที่ใหญ่พอและแชร์กับส่วนประกอบทั้งหมดของคุณ

person Sotirios Delimanolis    schedule 13.09.2013
comment
ขอบคุณ. ฉันยอมรับว่าควรใช้บางสิ่งที่มีความสุขเช่น ExecutorService เพื่อจัดการเธรด ฉันยังมีความรู้สึกไม่สบายใจที่ต้องส่งพวกเขาไป นอกจากนี้ ฉันกำลังใช้ EJB และสถานะข้อมูลจำเพาะของ EJB: • Enterprise bean ต้องไม่พยายามจัดการเธรด Enterprise bean จะต้องไม่พยายามเริ่ม หยุด ระงับ หรือดำเนินการเธรดต่อ หรือเปลี่ยนลำดับความสำคัญหรือชื่อของเธรด Enterprise bean ต้องไม่พยายามจัดการกลุ่มเธรด runnable ของฉันสามารถเป็น stateful session bean ได้หรือไม่ อาจจะใช่? คลาสที่ใช้ ExecutorService เพื่อส่งเธรดสามารถเป็น Stateless Singleton ได้หรือไม่ เลขที่? - person cmd; 13.09.2013
comment
@cmd ด้วย EJB อาจดู สิ่งนี้ - person Sotirios Delimanolis; 13.09.2013
comment
ขอบใจนะ ใกล้จะได้ไปได้แล้ว - person cmd; 14.09.2013
comment
@SotiriosDelimanolis โปรดดูสิ่งนี้และช่วยเหลือ ขอบคุณที่สละเวลา. stackoverflow.com/ คำถาม/19706788/ - person Kumar; 06.11.2013

ฉันจะสร้างวิธีการที่ส่งคืนการตอบกลับทันทีพร้อมรหัสกระบวนการและเวลาที่จะดำเนินการให้เสร็จสิ้น การคำนวณเริ่มต้นในเบื้องหลังและจะถูกแคชไว้ระยะหนึ่งหลังจากเสร็จสิ้น จากนั้นลูกค้าจะพยายามดึงข้อมูลด้วยรหัสเฉพาะและได้รับการตอบสนองที่เกี่ยวข้อง

person Justinas Jakavonis    schedule 06.05.2016