คำขอไปยัง URL เดียวกันถูกบล็อกในพูลเธรด http nio

ฉันเพิ่งสร้าง RestController ในแอปพลิเคชัน springboot(1.5.4.RELEASE) และทดสอบว่ามันทำงานอย่างไรเมื่อมีคำขอหลายรายการเข้ามา สิ่งที่ฉันสับสนคือ:

  • URL เดียวกัน : คำขอที่ 2 ถูกบล็อกจนกว่าคำขอที่ 1 จะดำเนินการ
  • URL ที่แตกต่างกัน: ไม่บล็อก มีการดำเนินการคำขอ 2 รายการเกือบพร้อมกัน

คำถามของฉันคือใครบล็อกคำขอที่ 2 และเพราะเหตุใด

รหัสทดสอบ:

@GetMapping(value = "/sleep")
public String sleep(HttpServletRequest request, @RequestParam boolean status) 
{
    String requestId = request.toString();
    logger.info("request  [{}] in  and status = {}.", requestId, status);
    String result;
    if (status)
    {
        Thread.currentThread().sleep(10 * 1000);
        result = "slept";
    }
    else
    {
        result = "stay up";
    }
    logger.info("response [{}] out and result = [{}].", requestId, result);
    return result;
}

ผลการทดสอบ:

  1. URL อื่น:อย่าบล็อก เกือบจะเริ่มดำเนินการพร้อมกัน

http://localhost:20002/sleep?status=false และ http://localhost:20002/sleep?status=true

2018-08-14 15:04:14.139  [http-nio-20002-exec-5]: connection [RequestFacade@46515328] in  and status = true.
2018-08-14 15:04:16.452  [http-nio-20002-exec-6]: connection [RequestFacade@1140f857] in  and status = false.
2018-08-14 15:04:16.452  [http-nio-20002-exec-6]: connection [RequestFacade@1140f857] out and result = [stay up].
2018-08-14 15:04:24.139  [http-nio-20002-exec-5]: connection [RequestFacade@46515328] out and result = [slept].
  1. URL เดียวกัน: บล็อก คำขอที่ 2 จะไม่ดำเนินการจนกว่าคำขอที่ 1 จะเสร็จสิ้น

http://localhost:20002/sleep?status=true และ http://localhost:20002/sleep?status=true

2018-08-14 15:10:29.943  [http-nio-20002-exec-9]: connection [RequestFacade@46515328] in  and status = true.
2018-08-14 15:10:39.944  [http-nio-20002-exec-9]: connection [RequestFacade@46515328] out and result = [slept].
2018-08-14 15:10:39.960  [http-nio-20002-exec-1]: connection [RequestFacade@1140f857] in  and status = true.
2018-08-14 15:10:49.960  [http-nio-20002-exec-1]: connection [RequestFacade@1140f857] out and result = [slept].

ฉันดีบักโค้ดของ tomcat-embed-core และพบว่าเมื่อมีการร้องขอที่มี url ที่แตกต่างกันเข้ามา เธรด Poller สามารถตรวจจับได้ทันทีและประมวลผล ในขณะที่คำขอที่มี URL เดียวกันเข้ามา Poller จะไม่สามารถรับได้จนกว่าการเชื่อมต่อครั้งที่ 1 จะถูกส่งกลับ


person George Wang    schedule 14.08.2018    source แหล่งที่มา
comment
จะเกิดอะไรขึ้นหากคุณใช้ Jetty หรือ Spring Boot เวอร์ชันใหม่กว่า (1.5.14 แทนที่จะเป็น 1.5.4)   -  person M. Deinum    schedule 14.08.2018
comment
ทดสอบกับ Jetty และ SpringBoot 1.5.14.RELEASE พบว่าไม่มีความแตกต่างกัน   -  person George Wang    schedule 23.08.2018
comment
พยายามที่จะทำซ้ำ แต่ทำงานได้ตามที่คาดหวังจากฝั่งของฉัน เรียกใช้คำขอ 8 รายการพร้อมกันสำหรับ URL เดียวกันและคำขอเหล่านั้นมาถึงพร้อมกัน คุณทดสอบสิ่งนี้อย่างไร? จากเบราว์เซอร์ การทดสอบ หรือบางอย่างเช่น cUrl หรือ Httpie บนบรรทัดคำสั่ง ฉันสงสัยว่าเบราว์เซอร์ที่อาจป้องกันการเรียก URL เดียวกัน (และรอให้คำขอแรกเสร็จสิ้นก่อนที่จะโทรอีกครั้ง)   -  person M. Deinum    schedule 23.08.2018
comment
ใช่ ขอบคุณ การใช้ cliet ที่แตกต่างกันและคำขอมาถึงพร้อมกัน Chrome เองที่ขัดขวางคำขอไปยังทรัพยากรเดียวกัน   -  person George Wang    schedule 24.08.2018


คำตอบ (1)


ขอบคุณ @M.Deinum การบล็อกไม่เกี่ยวข้องกับ NIO Chrome เองที่บล็อกคำขอที่ 2 และด้วยเหตุผลนี้ ฉันจึงพบความคิดเห็นด้านล่าง:

this behavior is due to Chrome locking the cache and waiting to see the result of one 
request before requesting the same resource again. 

https://stackoverflow.com/a/27514611/10222882

และพิสูจน์แล้วโดย Chrome Network -> Timing คำขอที่ 2 อยู่ในสถานะ [จนตรอก] จนกว่าจะมีการตอบกลับครั้งที่ 1

connection_stalled

person George Wang    schedule 24.08.2018