2013-02-12 27 views
5

Tôi đang chạy ứng dụng Flask trên Heroku bằng gunicorn với nhân viên của sự kiện. Một tuyến đường cụ thể trên ứng dụng của tôi thường xuyên nhận được dữ liệu POST (x-www-form-urlencoded) với một số trường khá chunky - theo thứ tự tối đa 500KB.Bình trên Heroku: request.form cực kỳ chậm với dữ liệu POST lớn?

Điều này hoạt động tốt khi chạy cục bộ, nhưng trên Heroku, yêu cầu tuyến đường đó mất từ ​​5 đến 30 giây để hoàn thành - và gần như 100% thời gian được sử dụng trong lần truy cập đầu tiên theo yêu cầu.http:

t = time.time() 
action = str(request.form['action']) 
dt = time.time() - t # Often 10 seconds or more! 

Điều này cũng được xác nhận bằng truy vấn yêu cầu chậm của Newrelic. Có một vài phần nghìn giây ở đây hoặc ở đó cho các hoạt động cơ sở dữ liệu, và sau đó một đoạn lớn thời gian trong mã Python, dường như đã chờ đợi một số i/o, vì thời gian CPU được báo cáo thường nhỏ hơn một phần nghìn giây.

Tôi hoàn toàn không thể tái tạo điều này trong môi trường cục bộ bằng cách sử dụng cùng thiết lập gunicorn/eventlet tôi đang sử dụng trong sản xuất. Ngay cả máy chủ WSGI gỡ lỗi tích hợp cũng nhanh như chớp trên các yêu cầu này.

Có ai có bất kỳ ý tưởng nào có thể xảy ra không? Đó có phải là một vấn đề với Flask, hoặc một cái gì đó tôi chỉ cần liên hệ với Heroku hỗ trợ về?

+2

Bạn đã thử đưa ứng dụng lên trên sandbox miễn phí của dotcloud chưa? Tôi đã sử dụng nó cho một ứng dụng Flask nhỏ gần đây, và nó đã chết đơn giản. Có thể thử nghiệm ứng dụng của bạn ở đó hoặc một nơi nào đó tương tự để xem liệu bạn có thể cô lập vấn đề với Heroku hoặc với Flask hoặc ứng dụng của bạn không? –

+1

Tôi thứ hai @AllanAnderson - hãy thử thiết lập tương tự trên một nhà cung cấp khác - nếu nó bị hỏng theo cách tương tự, bạn có thể cung cấp một số dữ liệu mẫu gây ra sự cố không? –

+2

* "và gần như 100% thời gian được chi tiêu trong lần truy cập đầu tiên vào request.form" * Có thể bạn đang gặp phải tác động của việc bỏ dyno không? https://devcenter.heroku.com/articles/dynos#dyno-idling – Dominic

Trả lời

3

Tôi nghĩ rằng tôi đã tìm ra chính xác những gì đang diễn ra. TL; DR nó không thực sự chậm trên máy chủ ở tất cả, tôi đã chỉ bị nhầm lẫn bởi thời gian phản ứng báo cáo của Newrelic!

Tôi đã thử chạy cùng một mã trên hộp cát của dotCloud như một @AllanAnderson đề xuất. Lần đầu tiên tôi tạo một trường hợp thử nghiệm đã giảm: một biểu mẫu HTML đơn giản với một vài trường ẩn được tải sẵn với khoảng 900KB dữ liệu và chức năng chế độ xem không làm gì ngoại trừ đọc từ từ điển request.form và đo thời gian trôi qua cho mỗi truy cập bằng cách sử dụng time.time().

On Heroku, kết quả trông như thế này:

5.87100 seconds: read field "p1": 786432 bytes 
0.00019 seconds: read field "p2": 131072 bytes 
0.00003 seconds: read field "p3": 12288 bytes 
0.00001 seconds: read field "p4": 1024 bytes 

Và trên dotCloud:

0.00096 seconds: read field "p1": 786432 bytes 
0.00019 seconds: read field "p2": 131072 bytes 
0.00003 seconds: read field "p3": 12288 bytes 
0.00001 seconds: read field "p4": 1024 bytes 

Tuy nhiên, cả hai thử nghiệm dường như mất cùng một lượng thời gian trong trình duyệt của tôi ... và bây giờ bạn có thể đoán câu trả lời thực sự cho vấn đề này. :-)

Hóa ra là gunicorn trên Heroku đang thực hiện chức năng xem ngay sau khi nhận được tiêu đề và quyền truy cập đầu tiên vào request.form bị chặn cho đến khi yêu cầu còn lại được nhận. Vì vậy, Newrelic đã nhìn thấy tất cả những thời gian phản hồi cực kỳ chậm đó thực sự chỉ là kết quả của việc tải lên dữ liệu POST qua kết nối mạng crappy. Thiết lập của dotCloud dường như chỉ đợi cho đến khi toàn bộ yêu cầu đã được nhận.

Điều này làm cho số liệu của Newrelic ít hữu ích hơn, nhưng nó không thực sự là vấn đề với trải nghiệm người dùng cuối.

+0

Vui mừng khi biết bạn đã phân loại những gì đã gây hiểu nhầm cho số liệu của bạn. Yay quá trình loại bỏ! –

Các vấn đề liên quan