Điểm:0

Truyền tệp tmp lớn bị treo trong proxy nginx php-fpm

lá cờ cn

Chúng tôi có một máy chủ đang chạy trang web WordPress với ngăn xếp nginx do máy chủ cài đặt trên Ubuntu 20 LTS.

Các tệp tải lên rất lớn dường như bị kẹt trong quá trình chuyển giao giữa proxy nginx và PHP, và tôi đã hiểu hết những gì tôi biết cách khắc phục sự cố mà không cần chọc vào nó để xem điều gì xảy ra (điều này hiếm khi sử dụng tốt thời gian hoặc cách để tiến về phía trước). Theo như tôi có thể nói, tôi đã tăng thời gian chờ cần thiết và tăng tất cả các giới hạn của đĩa, nhưng rõ ràng là tôi vẫn còn thiếu một số thứ.

Đối với trường hợp sử dụng của chúng tôi, chúng tôi cần cho phép tải lên tối đa 50 GB mà chúng tôi đã làm việc mà không gặp sự cố trong môi trường dàn dựng chạy ngăn xếp LAMP tiêu chuẩn. Chúng tôi không gặp vấn đề gì với các tệp dưới ~2GB, nhưng bất kỳ tệp nào vượt quá mức đó có thể hoặc không thể bị lỗi dựa trên một số tiêu chí mà tôi không thể theo dõi. Trong khi khắc phục sự cố vào thời điểm trước đó, thời gian dừng sao chép tệp dường như tùy ý (với thành công lên tới 10GB), nhưng với cấu hình hiện tại (xem bên dưới), nó luôn dừng khi PHP tmp tệp đạt 2GB.

Khi chúng tôi đang tải lên các tệp rất lớn, chúng tôi có thể xem tệp tạm thời đến sẽ tiêu tốn dung lượng ổ đĩa cho đến khi toàn bộ tệp tồn tại trong /mnt/tmp/[nginx_tmp_path] (vâng, có rất nhiều dung lượng đĩa trống). Sau đó, chúng ta có thể thấy tệp được sao chép vào php tmp đường dẫn, nhưng sau vài giây, tệp php tmp tập tin ngừng phát triển về kích thước và quá trình sao chép bị treo. Cuối cùng, một trong số thời gian chờ 600 giây đã đạt đến và có lỗi được ghi lại (xem bên dưới). Trong ảnh chụp màn hình này, chúng tôi có một bản tải lên 14,8 GB đã hoàn thành (từ góc độ trình duyệt/người dùng cuối) bị treo khi truyền tệp tmp ở mức khoảng 2 GB. Tệp tmp PHP ngừng phát triển

Vào cuối khoảng thời gian 600 giây, đây là nhật ký lỗi của Apache:

(70008)Một phần kết quả hợp lệ nhưng quá trình xử lý chưa hoàn tất: [máy khách <MY_IP>] AH01075: Lỗi khi gửi yêu cầu tới : (đọc nhóm đầu vào), người giới thiệu: https://<THE_URL>/wp-admin/media-new.php

Và nhật ký lỗi nginx đã nói điều này:

2512066#0: *9 hết thời gian ngược dòng (110: Hết thời gian kết nối) trong khi gửi yêu cầu ngược dòng, máy khách: <MY_IP>, máy chủ: <INTERNAL_IP>, yêu cầu: "POST /wp-admin/async-upload.php HTTP/ 2.0", ngược dòng: "http://127.0.0.1:81/wp-admin/async-upload.php", máy chủ lưu trữ: "<THE_URL>", liên kết giới thiệu: "https://<THE_URL>/wp-admin/ media-new.php"

Điều quan trọng cần lưu ý là những thông báo này không xuất hiện trong tệp nhật ký cho đến 10 phút sau khi quá trình tải lên ban đầu hoàn toàn đến máy chủ, tức là 9 phút trở lên sau khi quá trình sao chép tệp dường như bị tạm dừng/treo. Tôi tin rằng có điều gì đó đang khiến bản sao tệp bị kẹt và cuối cùng đã hết thời gian chờ - tôi không tin rằng vấn đề là do chính thời gian chờ. Trong thời gian chuyển tiếp giữa việc dừng sao chép tệp và lỗi hết thời gian chờ xuất hiện trong tệp nhật ký, không có hoạt động gia tăng hoặc bất thường nào trên máy chủ và tất cả các dịch vụ đều hoạt động và phản hồi như mong đợi.

Với cấu hình hiện tại, PHP tmp tệp luôn tăng lên 2097152 KB (theo du -a) khiến tôi tin rằng mình đang đạt đến giới hạn kích thước tệp được tích hợp sẵn mà cho đến nay tôi vẫn chưa phát hiện ra.

Các tùy chọn cấu hình máy chủ nginx có liên quan là: bên trong người phục vụ bối cảnh:

    proxy_connect_timeout 600;
    proxy_read_timeout 600;
    proxy_send_timeout 600;
    proxy_max_temp_file_size 51200m;

    fastcgi_connect_timeout 600;
    fastcgi_read_timeout 600;
    fastcgi_send_timeout 600;
    tắt fastcgi_request_buffering;

    keepalive_timeout 600;
    gửi_thời gian chờ 600;

    client_max_body_size 0;
    client_body_temp_path /mnt/tmp;
    client_body_in_file_only sạch;

Cấu hình Virtualhost của Apache:

    RequestReadTimeout header=0 body=0
    Thời gian chờ 3600
    Hết thời gian ủy quyền 3600

Và cuối cùng, cấu hình PHP:

memory_limit = -1
max_execution_time = 0
max_input_time = -1
post_max_size = 50G
upload_max_filesize = 50G
default_socket_timeout = -1

Tôi không biết điều gì có thể gây ra triệu chứng mà tôi đang gặp phải.Bất kỳ con trỏ được đánh giá cao!

Ghi chú bổ sung: Các triệu chứng khiến tôi cảm thấy rằng nó không liên quan, nhưng trong trường hợp đó là... Trang web chạy qua WP Rocket, nhưng không có dịch vụ proxy bên ngoài như CloudFlare.

CẬP NHẬT: Tôi đã thêm những dòng này vào cấu hình nginx:

    proxy_http_version 1.1;
    proxy_set_header Kết nối "";

Điều này đã thay đổi triệu chứng một chút, nhưng không khắc phục được sự cố. Với thay đổi này, hành vi đã trở lại như những gì tôi đã giải thích trước đó và quá trình truyền tệp dừng lại ở một vị trí không thể đoán trước. Ví dụ đầu tiên bên dưới dừng ở 3823176 KB và ví dụ thứ hai dừng ở 3264364 KB. Lý do cho sự khác biệt trong hành vi đối với tôi không có ý nghĩa gì, nhưng đáng để báo cáo. nhập mô tả hình ảnh ở đây nhập mô tả hình ảnh ở đây

CẬP NHẬT 2: Tôi đã có thể xác định chắc chắn đây là một vấn đề trong quá trình chuyển giao tmp giữa nginx và php, nhưng dường như tôi không thể tìm ra nguyên nhân cụ thể khiến quá trình bị treo.

Chúng ta có thể bỏ qua proxy nginx và chỉ sử dụng PHP tmp bằng cách thêm những dòng này vào cấu hình nginx:

    tắt proxy_buffering;
    tắt proxy_request_buffering;

Với cấu hình này, các tệp đi trực tiếp vào /mnt/tmp/php<RND_STR> và khi quá trình tải lên hoàn tất, ứng dụng của chúng tôi sẽ chọn đúng tệp ra khỏi tmp và hoàn thành nhiệm vụ của mình.

Tuy nhiên, điều này làm chậm quá trình tải lên khoảng 1/3 băng thông khả dụng, vì vậy đây không phải là một giải pháp tốt. Tuy nhiên, nó chứng minh rằng đây không phải là vấn đề ứng dụng.

Vì vậy, đây là những gì đang xảy ra:

  1. Người dùng tải lên một tệp lớn (50GB là mức tối đa trong trường hợp sử dụng của chúng tôi)
  2. Tệp đến trong nginx tmp toàn bộ vị trí
  3. Một nỗ lực được thực hiện để sao chép tệp từ nginx tmp vào PHP tmp - quá trình sao chép sẽ dừng lại trong vòng vài giây ở một nơi nào đó không thể đoán trước, nhưng trong khoảng từ 3 GB đến 10 GB. [3b] Tại thời điểm này, chúng ta có thể thấy cả hai tmp tập tin và PHP tmp tệp chứa một số byte sẽ tăng lên cho đến khi nó bằng kích thước của nginx tmp tập tin, nhưng họ không.Cả hai tệp sẽ nằm hoàn toàn nguyên trạng cho đến khi đạt đến một trong số thời gian chờ 600 giây (xem bên trên), sau đó sẽ xuất hiện lỗi trong tệp nhật ký và cả hai tmp tập tin biến mất. [3c] Nếu tệp dưới 3 GB, nó sẽ hoạt động mọi lúc. Nếu tệp lớn hơn 3 GB, thì đôi khi tệp sẽ hoạt động, còn những tệp khác thì không - tệp càng nhỏ thì khả năng hoạt động càng cao.
  4. Bỏ qua nginx tmp hoạt động hoàn toàn như mong đợi, ngoại trừ việc tải lên chậm.

Một cái gì đó chắc chắn đang bị treo lên trong quá trình tmp chuyển giao tệp giữa nginx và PHP khi các tệp quá lớn và tôi rất muốn tìm hiểu xem nó là gì.

Michael Hampton avatar
lá cờ cz
Bạn nên đặt câu hỏi tại sao ứng dụng PHP lại mất hơn 600 giây để xử lý tệp.
Chris Ostmo avatar
lá cờ cn
Tôi đã tăng tất cả thời gian chờ vì tôi cho rằng quá trình chuyển giao tệp 50 GB sẽ mất hơn 60 giây mặc định. Không phải quá trình xử lý PHP sẽ hết thời gian chờ - việc chuyển giao tệp tạm thời sẽ hết thời gian chờ proxy. Phải thừa nhận rằng tôi đã mở rộng quá nhiều trong quá trình tìm kiếm giải pháp.
Chris Ostmo avatar
lá cờ cn
... Tuy nhiên, PHP không mất 600 giây để xử lý tệp - một cái gì đó dừng lại vài giây khi sao chép tệp và 600 giây chỉ đơn giản là khi nó dừng chờ và đưa ra lỗi. Ứng dụng PHP của chúng tôi không có cơ hội bắt đầu làm việc trên tệp cho đến khi nó được chuyển ra khỏi `tmp`, đây không phải là trạng thái mà chúng tôi đang đạt tới. (xin lỗi, đã cố chỉnh sửa nhận xét ban đầu của tôi, nhưng đã quá muộn)
Michael Hampton avatar
lá cờ cz
Hừm. Chà, tất cả những gì tôi thực sự có thể nói từ các lỗi được đăng là nginx dường như đã chuyển nó thành công sang Apache và Apache đã không chuyển nó sang PHP. Đối với tôi, điều này khiến người ta nghi ngờ chính mã PHP xử lý quá trình tải lên. Bạn nên nhờ nhà phát triển ứng dụng tham gia. Nhưng một số thứ khác trông hơi kỳ lạ. Bạn đã gắn các hệ thống tệp riêng biệt cho các tệp tạm thời? Chúng là loại hệ thống tập tin nào?
Chris Ostmo avatar
lá cờ cn
Tôi là nhà phát triển và lỗi này xảy ra từ hộp thoại tải lên phương tiện truyền thông WordPress vanilla, vì vậy không có bất kỳ mã nào đang phát ở đây mà không được nhiều người sử dụng. Tệp không bao giờ hoàn tất quá trình chuyển giao từ tmp của nginx sang tmp của PHP, vì vậy tôi không tin rằng ứng dụng có thể can thiệp. Có, thư mục `tmp` được gắn trên phân vùng ext4 của chính nó. Ngoài ra, hành vi thay đổi khi tôi thay đổi cấu hình máy chủ không phù hợp với lỗi ứng dụng.

Đăng câu trả lời

Hầu hết mọi người không hiểu rằng việc đặt nhiều câu hỏi sẽ mở ra cơ hội học hỏi và cải thiện mối quan hệ giữa các cá nhân. Ví dụ, trong các nghiên cứu của Alison, mặc dù mọi người có thể nhớ chính xác có bao nhiêu câu hỏi đã được đặt ra trong các cuộc trò chuyện của họ, nhưng họ không trực giác nhận ra mối liên hệ giữa câu hỏi và sự yêu thích. Qua bốn nghiên cứu, trong đó những người tham gia tự tham gia vào các cuộc trò chuyện hoặc đọc bản ghi lại các cuộc trò chuyện của người khác, mọi người có xu hướng không nhận ra rằng việc đặt câu hỏi sẽ ảnh hưởng—hoặc đã ảnh hưởng—mức độ thân thiện giữa những người đối thoại.