نقوم بتوزيع الملفات من Google Drive باستخدام nginx

قبل التاريخ


لقد حدث أنني بحاجة إلى مكان لتخزين أكثر من 1.5 تيرابايت من البيانات ، وحتى توفير القدرة على تنزيلها من قبل المستخدمين العاديين عبر رابط مباشر. نظرًا لأن هذه المبالغ من الذاكرة تذهب تقليديًا إلى VDS ، والتي لا يتم استثمار تكلفة تأجيرها في ميزانية المشروع من فئة "لا شيء يجب القيام به" ، ومن البيانات المصدر ، كان لدي VPS 400GB SSD ، حيث لا يمكنني وضع 1.5 تيرابايت من الصور دون ضغط دون فقد سوف تنجح.


ثم تذكرت أنه إذا قمت بحذف الملفات غير المرغوب فيها من قرص Google ، مثل البرامج التي تعمل فقط على نظام التشغيل Windows XP ، والأشياء الأخرى التي تنتقل من الوسائط إلى الوسائط نظرًا لأن الإنترنت لم يكن بهذه السرعة والكمال ليست غير محدودة (على سبيل المثال ، من غير المرجح أن يكون لتلك الإصدارات 10-20 من المربع الظاهري أي قيمة أخرى غير الحنين) ، ثم يجب أن يكون كل شيء مناسبًا جدًا. لم يقل قال من القيام به. وهكذا ، في طريقنا من خلال الحد من عدد طلبات api (بالمناسبة ، زاد الدعم التقني دون مشاكل من حصة الطلبات لكل مستخدم في 100 ثانية إلى 10000) ، وسرعان ما تدفقت البيانات إلى مكان نشرها الإضافي.


يبدو أن كل شيء على ما يرام ، ولكن يجب الآن نقله إلى المستخدم النهائي. علاوة على ذلك ، دون أي عمليات إعادة توجيه إلى الموارد الأخرى هناك ، بحيث ينقر الشخص ببساطة فوق الزر "تنزيل" ويصبح المالك المحظوظ للملف الذي يعتز به.


ثم ، من خلال غولي ، انطلقت بكل الطرق الجادة. في البداية كان برنامج نصي على AmPHP ، لكنني لم أكن سعيدًا بالحمل الذي أحدثته (قفزة حادة في البداية حتى 100٪ من استهلاك النواة). بعد ذلك ، تم تشغيل برنامج التفاف curl الخاص بـ ReactPHP ، والذي يتلاءم تمامًا مع تمنياتي للعدد المستهلك من دورات ساعة وحدة المعالجة المركزية ، لكنه لم يمنح السرعة على الإطلاق ما أردت (اتضح أنه يمكنك ببساطة تقليل مدة الفاصل الزمني curl_multi_select ، ولكن بعد ذلك لدينا نفس الشراهة للخيار الأول ). لقد حاولت حتى كتابة خدمة صغيرة في Rust ، وكانت تعمل ببراعة كبيرة (على نحو مدهش ، كانت تعمل حسب علمي) ، لكنني أردت المزيد ، ولم يكن من السهل تخصيصها بطريقة أو بأخرى. بالإضافة إلى ذلك ، فإن كل هذه الحلول كانت مخزنة بشكل غريب في الإجابة ، وأردت تتبع اللحظة التي انتهى فيها تنزيل الملف بأكبر قدر من الدقة.


بشكل عام ، لفترة من الوقت كان منحرف ، لكنه نجح. حتى يوم واحد كان لدي فكرة فكرة وهمية الوهمية: nginx من الناحية النظرية يمكن أن تفعل ما أريد ، وأنها تعمل بخفة ، وحتى تسمح لجميع أنواع الانحرافات مع التكوين. علينا أن نحاول - ماذا لو نجحت؟ وبعد نصف يوم من عمليات البحث المستمرة ، كان الحل يعمل بثبات لعدة أشهر حقق جميع متطلباتي.


تخصيص NGINX


#         . location ~* ^/google_drive/(.+)$ { #       (,     ). internal; #       (  ). limit_rate 1m; #   nginx    google drive    . resolver 8.8.8.8; # C     (    ). set $download_url https://www.googleapis.com/drive/v3/files/$upstream_http_file_id?alt=media; #    Content-Disposition ,        . set $content_disposition 'attachment; filename="$upstream_http_filename"'; #     . proxy_max_temp_file_size 0; # ,  ,     (  ,     $http_upstream    .   ,     -  ,      ). proxy_set_header Authorization 'Bearer $1'; #  ,         . proxy_pass $download_url; #              . add_header Content-Disposition $content_disposition; #        . proxy_hide_header Content-Disposition; proxy_hide_header Alt-Svc; proxy_hide_header Expires; proxy_hide_header Cache-Control; proxy_hide_header Vary; proxy_hide_header X-Goog-Hash; proxy_hide_header X-GUploader-UploadID; } 

يمكن رؤية نسخة قصيرة دون تعليقات تحت المفسد
 location ~* ^/google_drive/(.+)$ { internal; limit_rate 1m; resolver 8.8.8.8; set $download_url https://www.googleapis.com/drive/v3/files/$upstream_http_file_id?alt=media; set $content_disposition 'attachment; filename="$upstream_http_filename"'; proxy_max_temp_file_size 0; proxy_set_header Authorization 'Bearer $1'; proxy_pass $download_url; add_header Content-Disposition $content_disposition; proxy_hide_header Content-Disposition; proxy_hide_header Alt-Svc; proxy_hide_header Expires; proxy_hide_header Cache-Control; proxy_hide_header Vary; proxy_hide_header X-Goog-Hash; proxy_hide_header X-GUploader-UploadID; } 



كتابة السيناريو لإدارة كل هذه السعادة


المثال سيكون في PHP وكتب عمدا مع الحد الأدنى طقم الجسم. أعتقد أن كل شخص لديه خبرة في أي لغة أخرى سيكون قادرًا على دمج هذه المقالة باستخدام مثالي.


 <?php #   Google Drive Api. define('TOKEN', '*****'); # ID     $fileId = 'abcdefghijklmnopqrstuvwxyz1234567890'; # ,         -    ? http_response_code(204); #   c ID  (  nginx      $upstream_http_file_id). header('File-Id: ' . $fileId); #      ( $upstream_http_filename). header('Filename: ' . 'test.zip'); #  .       ,  ,     $1  nginx. header('X-Accel-Redirect: ' . rawurlencode('/google_drive/' . TOKEN)); 

النتائج


بشكل عام ، تجعل هذه الطريقة من السهل إلى حد ما تنظيم توزيع الملفات على المستخدمين من أي مساحة تخزين سحابية. نعم ، حتى من telegram أو VK ، (بشرط ألا يتجاوز حجم الملف الحجم المسموح به لهذا المستودع). كانت لدي فكرة مماثلة لهذه الفكرة ، لكن لسوء الحظ صادفت ملفات تصل سعتها إلى 2 جيجابايت ، ولم أجد بعد طريقة أو وحدة نمطية لتوجيه الإجابات من المنبع ، وكتابة بعض الأغلفة لهذا المشروع هي عملية شاقة بشكل غير معقول.


شكرا لاهتمامكم آمل أن تكون قصتي على الأقل مثيرة للاهتمام أو مفيدة لك.

Source: https://habr.com/ru/post/ar460685/


All Articles