เรากำลังเรียกใช้เซิร์ฟเวอร์ django/gunicorn บน heroku ผู้ใช้ส่วนใหญ่ของเราอยู่ในประเทศที่เครือข่ายมือถือไม่ค่อยดีนัก ดังนั้นบ่อยครั้งที่พวกเขามีการเชื่อมต่อที่ไม่สม่ำเสมอ
คำขอส่วนใหญ่ของเราเป็น "การโพสต์ดิบ" จากอุปกรณ์มือถือ และดูเหมือนว่าแม้ว่าคำขอ POST จะไม่ได้ส่งอย่างสมบูรณ์ คำขอก็ถูกส่งออกไปเพื่อให้คนงานของ gunicorn จัดการแล้ว เมื่อผู้ปฏิบัติงานพยายามประมวลผลคำขอและอ่านข้อมูล พนักงานก็จะค้างเพื่อรอข้อมูลที่เหลือ แม้ว่าพฤติกรรมนี้เหมาะสมสำหรับการอ่านไฟล์/ข้อมูลรูปภาพในโหมด "สตรีมมิ่ง" แต่ก็ไม่สมเหตุสมผลในกรณีของเรา เนื่องจากโพสต์ทั้งหมดของเรามีขนาดค่อนข้างเล็กและเว็บเซิร์ฟเวอร์โดยรวมสามารถอ่านได้ง่าย จากนั้นจึงส่งต่อไปยัง gunicorn ของเราเท่านั้น คนงาน
การแฮนด์ออฟก่อนกำหนดนี้ทำให้เกิดปัญหาเมื่อเรามีคำขอดังกล่าวจำนวนมากพร้อมกัน เนื่องจากผู้ปฏิบัติงานทั้งหมดอาจถูกบล็อก ขณะนี้เราแก้ไขปัญหาด้วยการเพิ่มจำนวนคนงาน/ไดโน แต่มีค่าใช้จ่ายค่อนข้างสูง ฉันไม่พบวิธีใดที่จะบังคับให้เว็บเซิร์ฟเวอร์หรือ gunicorn รอและส่งต่อคำขอไปยังผู้ปฏิบัติงานเมื่อมีการส่งโดยสมบูรณ์เท่านั้น
มีวิธีที่จะทำให้เว็บเซิร์ฟเวอร์ / gunicorn ของ heroku โอนคำขอไปยังคนงาน gunicorn เท่านั้นเมื่อมีการส่งจากฝั่งไคลเอ็นต์อย่างสมบูรณ์ (เซิร์ฟเวอร์ได้รับอย่างเต็มที่)
โค้ดตัวอย่างบางส่วน (เราได้เพิ่มการติดตาม 'ตามคำสั่ง' newrelic เพื่อให้แน่ใจว่านี่คือบรรทัดที่แน่นอนที่ทำให้เกิดปัญหา):
def syncGameState(request):
transaction = agent.current_transaction()
with agent.FunctionTrace(transaction, "syncGameState_raw_post_data", 'Python/EndPoint'):
data = request.raw_post_data
with agent.FunctionTrace(transaction, "syncGameState_gameStateSyncRequest", 'Python/EndPoint'):
sync_request = sync_pb2.gameStateSyncRequest()
with agent.FunctionTrace(transaction, "syncGameState_ParseFromString", 'Python/EndPoint'):
sync_request.ParseFromString(data)
นี่คือการวัด New Relic สำหรับตัวอย่างคำขอที่ช้านี้ (เป็น POST ที่มีข้อมูล 7K) การอ่าน POST ใช้เวลา 99% ของวิธีการ....
web: gunicorn hellodjango.wsgi -t 3 -b 0.0.0.0:$PORT
- person dani herrera   schedule 30.08.2012