แก้ไข:คำตอบของฉันครอบคลุมเฉพาะคำถามที่ไม่ได้แก้ไขดั้งเดิมซึ่งเป็นสิ่งที่ประเภทนี้เป็นเรื่องปกติใน load balancer / reverse proxies ฉันไม่แน่ใจว่า nginx / product X รองรับสิ่งนี้หรือไม่ 99.9% ของประสบการณ์การพร็อกซีย้อนกลับของฉันอยู่กับ HAproxy
แก้ไข. HTTP Keep-Alive ที่ฝั่งไคลเอ็นต์ แต่ไม่ใช่ฝั่งเซิร์ฟเวอร์
ทำไม?
หากคุณแยกรายละเอียดเล็กน้อยคุณจะเห็นได้อย่างรวดเร็วว่าเหตุใดจึงเป็นประโยชน์ สำหรับตัวอย่างนี้สมมติว่าเรากำลังโหลดหน้าเว็บ www.example.com และหน้านั้นมี 3 ภาพ img [1-3] .jpg
เบราว์เซอร์โหลดหน้าโดยไม่มี Keep-Alive
- ลูกค้าสร้างการเชื่อมต่อ TCP ไปที่ www.example.com บนพอร์ต 80
- ลูกค้าร้องขอ HTTP GET สำหรับ "/"
- เซิร์ฟเวอร์ส่งเนื้อหา HTML ของ URI "/" (ซึ่งมีแท็ก HTML อ้างอิง 3 ภาพ)
- เซิร์ฟเวอร์ปิดการเชื่อมต่อ TCP
- ลูกค้าสร้างการเชื่อมต่อ TCP ไปที่ www.example.com บนพอร์ต 80
- ลูกค้าร้องขอ HTTP GET สำหรับ "/img1.jpg"
- เซิร์ฟเวอร์ส่งภาพ
- เซิร์ฟเวอร์ปิดการเชื่อมต่อ TCP
- ลูกค้าสร้างการเชื่อมต่อ TCP ไปที่ www.example.com บนพอร์ต 80
- ลูกค้าร้องขอ HTTP GET สำหรับ "/img2.jpg"
- เซิร์ฟเวอร์ส่งภาพ
- เซิร์ฟเวอร์ปิดการเชื่อมต่อ TCP
- ลูกค้าสร้างการเชื่อมต่อ TCP ไปที่ www.example.com บนพอร์ต 80
- ลูกค้าร้องขอ HTTP GET สำหรับ "/img3.jpg"
- เซิร์ฟเวอร์ส่งภาพ
- เซิร์ฟเวอร์ปิดการเชื่อมต่อ TCP
ขอให้สังเกตว่ามีการสร้างเซสชัน TCP แยกกัน 4 เซสชันแล้วปิด
เบราว์เซอร์กำลังโหลดหน้าเว็บพร้อม Keep-Alive
HTTP Keep-Alive อนุญาตให้มีการเชื่อมต่อ TCP เดียวเพื่อให้บริการคำขอ HTTP หลายรายการซึ่งกันและกัน
- ลูกค้าสร้างการเชื่อมต่อ TCP ไปที่ www.example.com บนพอร์ต 80
- ไคลเอนต์ทำการร้องขอ HTTP GET สำหรับ "/" และขอให้เซิร์ฟเวอร์ตั้งค่าเซสชัน HTTP Keep-Alive
- เซิร์ฟเวอร์ส่งเนื้อหา HTML ของ URI "/" (ซึ่งมีแท็ก HTML อ้างอิง 3 ภาพ)
- เซิร์ฟเวอร์ไม่ปิดการเชื่อมต่อ TCP
- ไคลเอนต์ทำและคำขอ HTTP GET สำหรับ "/img1.jpg"
- เซิร์ฟเวอร์ส่งภาพ
- ไคลเอนต์ทำและคำขอ HTTP GET สำหรับ "/img2.jpg"
- เซิร์ฟเวอร์ส่งภาพ
- ไคลเอนต์ทำและคำขอ HTTP GET สำหรับ "/img3.jpg"
- เซิร์ฟเวอร์ส่งภาพ
- เซิร์ฟเวอร์ปิดการเชื่อมต่อ TCP หากไม่ได้รับการร้องขอ HTTP อีกภายในระยะเวลาหมดเวลา HTTP Keep-Alive
โปรดสังเกตว่าด้วย Keep-Alive จะมีการสร้างการเชื่อมต่อ TCP เพียง 1 รายการเท่านั้น
ทำไม Keep-Alive ถึงดีกว่า?
ในการตอบคำถามนี้คุณต้องเข้าใจว่าต้องทำอย่างไรเพื่อสร้างการเชื่อมต่อ TCP ระหว่างไคลเอนต์และเซิร์ฟเวอร์ สิ่งนี้เรียกว่าการจับมือ TCP 3-way
- ไคลเอนต์ส่งแพ็คเก็ต SYN (chronise)
- เซิร์ฟเวอร์ส่ง AC-chronise SYN (chronise) กลับไปตอนนี้ SYN-ACK
- ไคลเอนต์ส่งแพคเก็ต ACK (nowledgement)
- ขณะนี้การเชื่อมต่อ TCP ถูกพิจารณาว่าใช้งานได้โดยทั้งไคลเอนต์และเซิร์ฟเวอร์
เครือข่ายมีความล่าช้าดังนั้นแต่ละขั้นตอนในการจับมือ 3 ทางใช้เวลาพอสมควร ให้บอกว่ามีไคลเอ็นต์และเซิร์ฟเวอร์ 30 มิลลิวินาทีการส่งแพ็คเก็ต IP ที่จำเป็นในการสร้างการเชื่อมต่อ TCP หมายความว่าต้องใช้เวลา 3 x 30ms = 90ms เพื่อสร้างการเชื่อมต่อ TCP
สิ่งนี้อาจไม่ฟังดูมากนัก แต่ถ้าเราพิจารณาว่าในตัวอย่างดั้งเดิมของเราเราต้องสร้างการเชื่อมต่อ TCP แยกต่างหาก 4 อันสิ่งนี้จะกลายเป็น 360ms เกิดอะไรขึ้นถ้าเวลาแฝงระหว่างไคลเอ็นต์และเซิร์ฟเวอร์คือ 100ms แทนที่จะเป็น 30ms จากนั้นคนรู้จักทั้ง 4 คนของเราใช้เวลาในการสร้าง 1200 มิลลิวินาที
ยิ่งแย่ไปกว่านั้นหน้าเว็บทั่วไปอาจต้องการรูปภาพมากกว่า 3 รูปเพื่อโหลดอาจมีไฟล์ CSS, JavaScript, รูปภาพหรือไฟล์อื่น ๆ ที่ลูกค้าต้องร้องขอ หากหน้าโหลดไฟล์อื่น ๆ 30 ไฟล์และเวลาแฝงของไคลเอ็นต์เซิร์ฟเวอร์คือ 100 มิลลิวินาทีเราใช้เวลานานแค่ไหนในการสร้างการเชื่อมต่อ TCP?
- หากต้องการสร้าง 1 การเชื่อมต่อ TCP ใช้เวลา 3 x เวลาแฝงนั่นคือ 3 x 100ms = 300ms
- เราต้องทำเช่นนี้ 31 ครั้งสำหรับหน้าหนึ่งครั้งและอีก 30 ครั้งสำหรับไฟล์อื่น ๆ ที่อ้างอิงโดยหน้าเว็บ 31 x 300ms = 9.3 วินาที
ใช้เวลา 9.3 วินาทีในการสร้างการเชื่อมต่อ TCP เพื่อโหลดหน้าเว็บที่อ้างอิงไฟล์อื่น ๆ 30 ไฟล์ และนั่นไม่ได้นับเวลาที่ใช้ในการส่งคำขอ HTTP และรับการตอบกลับ
ด้วย HTTP Keep-Alive เราต้องการเพียงสร้างการเชื่อมต่อ 1 TCP ซึ่งใช้เวลา 300ms
ถ้า HTTP Keep-Alive นั้นยอดเยี่ยมทำไมไม่ลองใช้มันที่ฝั่งเซิร์ฟเวอร์ด้วย?
HTTP reverse proxies (เช่น HAproxy) มักจะถูกนำไปใช้งานใกล้กับเซิร์ฟเวอร์ส่วนหลังที่พวกเขากำลังใช้งานอยู่ ในกรณีส่วนใหญ่เวลาแฝงระหว่างพร็อกซีย้อนกลับและเซิร์ฟเวอร์แบ็กเอนด์จะต่ำกว่า 1 มิลลิวินาทีดังนั้นการสร้างการเชื่อมต่อ TCP จะเร็วกว่ามากระหว่างไคลเอ็นต์
นั่นเป็นเพียงครึ่งหนึ่งของเหตุผล เซิร์ฟเวอร์ HTTP จัดสรรจำนวนหน่วยความจำที่แน่นอนสำหรับการเชื่อมต่อลูกค้าแต่ละครั้ง ด้วย Keep-Alive จะทำให้การเชื่อมต่อยังคงอยู่และโดยการขยายจะรักษาจำนวนหน่วยความจำที่ใช้งานบนเซิร์ฟเวอร์จนกว่าจะถึงเวลาหมด Keep-Alive ซึ่งอาจสูงถึง 15 วินาทีขึ้นอยู่กับการกำหนดค่าเซิร์ฟเวอร์ .
ดังนั้นหากเราพิจารณาถึงผลกระทบของการใช้ Keep-Alive ที่ฝั่งเซิร์ฟเวอร์ของ HTTP reverse proxy เรากำลังเพิ่มความต้องการหน่วยความจำ แต่เนื่องจากเวลาแฝงระหว่างพร็อกซีและเซิร์ฟเวอร์ต่ำดังนั้นเราจึงไม่ได้รับประโยชน์ที่แท้จริงจาก ลดเวลาในการจับมือ 3-way ของ TCP ดังนั้นโดยทั่วไปแล้วดีกว่าการปิดใช้งาน Keep-Alive ระหว่างพร็อกซีและเว็บเซิร์ฟเวอร์ในสถานการณ์นี้
คำเตือน: ใช่คำอธิบายนี้ไม่ได้คำนึงถึงความจริงที่ว่าเบราว์เซอร์มักจะสร้างการเชื่อมต่อ HTTP หลายไปยังเซิร์ฟเวอร์ในแบบคู่ขนาน อย่างไรก็ตามมีข้อ จำกัด เกี่ยวกับจำนวนการเชื่อมต่อแบบขนานที่เบราว์เซอร์จะทำกับโฮสต์เดียวกันและโดยทั่วไปแล้วสิ่งนี้ยังมีขนาดเล็กพอที่จะทำให้เป็นที่ต้องการได้