تحذير Longrid: لقد تم تحذيرك ، العديد من الرسائل.
لقد تم منذ فترة طويلة تطوير تنسيق توزيع للتطبيقات التي كانت "خالية" من التبعيات على مستوى النظام. إن Ubuntu نشطة للغاية في الترويج لها. كلا الوعد الجنة والتحرر من دورة في الدقيقة / ديب. دعونا نفكر في المشكلة التي يريدون حلها ، والسعر الذي يطلبونه لحل هذه المشكلة.
المكتبات
لا أحد في العالم الحديث يمكنه كتابة طلب دون استخدام كود شخص آخر. هناك عدة أسباب:
- تعد العديد من المكتبات خطيرة للغاية بحيث تعد كتابة وظائفها من البداية مهمة شاقة. أمثلة - دعم يونيكود ، تقديم الخط ، الرياضيات.
- تقدم مكتبات أخرى مجموعة متواضعة إلى حد ما من الوظائف ، لكنها مكتوبة بشكل جيد بحيث يكاد يكون من المستحيل الكتابة على الأقل. المكتبات القياسية للغات البرمجة ، تطبيقات مختلفة من libc ، إلخ.
- غالبًا ما تكون تكلفة العمل مع رمز شخص آخر (والتي يخصص لها هذا القسم) أقل من تكلفة الحفاظ على الشفرة الخاصة بك. من المرجح أن تكون كثافة "الأخطاء لكل سطر من التعليمات البرمجية" قابلة للمقارنة ، ويجب عليك التقاط الأخطاء الخاصة بك بنفسك. من المحتمل أن يتم تصحيح المكتبات الأجنبية (الشائعة) وتصحيحها بواسطة الأيدي الخطأ.
المفتاح هو أنه حتى لو تمكنا من كتابة وظيفة مكتبة واحدة من المبدأ ، فإن العدد الإجمالي للوظائف الضرورية (والتبعيات) يعطي زيادة هائلة تقريبًا في عدد المهام التي تحتاج إلى حل ، مع تأجيل وقت بدء العمل على رمز البرنامج نفسه في مسافة بعيدة المنال.
مثال على تحقيق حجم الدراما: دعنا نقول أن تطبيقك يأخذ سطرين من المدخلات كحجج اختيارية ويعرضهما معًا بعد التطبيع. إذا كنت تكتب تطبيقًا صناعيًا (تطبيق يبدو وكأنه تطبيق "حقيقي") ، فعندئذٍ:
- تحتاج إلى محلل سطر الأوامر
- التي ينبغي أن تقبل يونيكود
- وربما يعطي المستخدم تلميحًا بأنه قد ختم اسم الوسيطة
- ما يتطلب المقارنة الصوتية
- وربما التعبيرات العادية
- بشكل عام ، سيكون عليك دعم ليس فقط Unicode ، ولكن أيضًا لغات أخرى ، والتي تتطلب مكتبة دعم لغة وكل ما يأتي الأشخاص في سياق لغات.
- سلسلة السلسلة مع التطبيع هي استخدام آخر لمكتبة Unicode منفصلة ؛ أنت نفسك لا تنفذ هذا.
- من المحتمل أن يتطلب الإخراج إلى الشاشة (المساعدة في سطر الأوامر ، النتيجة) دعمًا للناقلات - مكتبة تدعم أطرافًا مختلفة (يمكنك القيام به مع وضع النص ، ولكن التطبيقات تستخدم غالبًا إمكانات الألوان).
- تتضمن الاختبارات استخدام إطار اختبار ، وربما مكتبة للمحترفين.
من الواضح أن مثل هذا التعقيد لمهمة "الخطين" هو هندسة مبتكرة ، لكن بمجرد أن تبدأ في فعل شيء أكثر ، تبدأ فكرة "كل شيء بنفسك" في تجاوز حدود ما يمكن ملاحظته وإدراكه.
كم عدد المكتبات التي تعتقد أنها مطلوبة لضمان حل هذا http (s): // ...؟ كثير ستستخدم واحدة ، لكن تبعيات تبعياتك هي تبعياتك.
Copypaste والبيع VS ربط ديناميكي
في حين أن استخدام المكتبات أمر لا مفر منه ، قد يختلف الاستخدام نفسه في التنفيذ. يرجى ملاحظة أن لدينا كلمتين مهمتين: "الاستخدام" و "تنفيذ الاستخدام". ماذا يعني استخدام؟ في أكثر أشكاله وقحا - القدرة على استدعاء رمز المكتبة عند الضرورة. وهنا هي تطبيقات هذا:
- يمكننا نسخ الكود الذي يفعل العمليات التي نحتاجها. في شكل رمز (نسخ ولصق) ، كوحدة نمطية منفصلة بلغة برمجة (ملف كائن للغات المترجمة) ، أو كوحدة نمطية منفصلة (للغات المترجمة). في مكان ما بجواره ، "انسخ الملف المصدر للمكتبة إلى الدليل الخاص بك مع التطبيق." ما هي المشاكل التي يخلقها هذا؟ المشكلة الرئيسية ، هي أننا نفقد (إلى الأبد) الاتصال مع الأصل. حتى إذا قام مؤلف المكتبة الأصلية بتصحيح الخطأ ، فلن نعرف ذلك. علاوة على ذلك ، إذا قمنا بنسخ الكود ، فلن يتمكن الشخص التالي الذي يعمل في البرنامج من معرفة أن هذا الكود "غريب". في الواقع ، قطعنا الطريق في السؤال "الكتابة من الصفر" وأخذنا شخصًا آخر. ومع ذلك ، قمنا بقص قطعة واحدة فقط ، لأنه إذا كانت هناك أخطاء في هذا الرمز (لكنها لن تكون هناك ، فهي موجودة) ، فإن تصحيحها سيتطلب تصحيح واحد للذهاب وفهم جوهر المشكلة حتى النهاية. حتى إذا كانت التجربة تتطلب قراءة عدة مئات الآلاف من سطور الكود المصدري ومئات من RFCs (بالإضافة إلى تعليقات تفيد بأن التطبيقات تختلف عن RFCs) ، فليس لدينا طريقة أخرى. الخطأ الرئيسي في هذا المكان هو أننا فقدنا معلومات تفيد بأن هذا الرمز غريب. يمكن أن يساعد وجود تعليقات في ملف ما ، ولكنه يتطلب مشاركة نشطة وعميقة من شخص ما ، لأنه إذا كتبنا في تعليق "مأخوذ من libfoobar ، إصدار src / lib / foo.c ، الإصدار 364a51577f3782dbf8e5d2482ab941980357c492" ، فسيحتاج الشخص إلى معرفة مكان وجود libfoobar ، ما هو الإصدار وما الذي تغير من الإصدار السابق. "لتبسيط هذه العملية ، نحتاج إلى معلومات تعريف قابلة للقراءة آليًا.
- إذا قمنا بمرافقة "رمز شخص آخر" بمعلومات التعريف واستخدمنا برامج لإدارة هذه الشفرة (بدلاً من نسخ اللصق) ، فإن هذا يسمى البيع ، أي يتم التحكم في تضمين رمز شخص آخر في الشفرة الخاصة بك. من الناحية الفنية ، يمكن أن يحدث البيع في مرحلة النص المصدر ، أو ربط الكائنات بملف قابل للتنفيذ ، أو استيراد الوحدات النمطية (في المترجمين الفوريين) من التطبيق ، أو حتى الارتباط الديناميكي بإصدار "المكتبة" الخاص بك (المزيد حول هذا لاحقًا).
- أخيرًا ، يمكننا إجراء ربط ديناميكي في مرحلة تشغيل التطبيق. بالنسبة للغات المترجمة ، فهذه هي مجموعات عادية ؛ وبالنسبة للغات المترجمة ، هناك وحدة نمطية في عملية الاستيراد على مستوى النظام. إذا كان بإمكان العديد من التطبيقات استيرادها ، فهذه مكتبة مشتركة. إذا كان التطبيق "جلب الوحدة الخاصة به" ، فالمكتبة "خاصة" ، حتى لو كانت واجهتها تتضمن "مكتبة مشتركة". على سبيل المثال ، إذا كان التطبيق يستخدم الإصدار "الخاص" به ، بغض النظر عما إذا كان يختلف عن الإصدار العام أم لا ، فسيكون هذا البيع. وإذا تم استيراد النظام ، فهذه مكتبة مشتركة.
ما هو الفرق بين هذه الأساليب؟ سأطرح الحجج لفترة وجيزة ؛ لقد نوقشت عدة مرات في العديد من المقالات. تظل كل من هذه الحجج صالحة على الرغم من وجود وسائل مضادة مجاورة:
- حفظ الذاكرة (ذاكرة الوصول العشوائي والقرص) لذلك ، مما يقلل من حجم النظام المثبت. كلما زاد عدد التطبيقات التي تستخدم نفس الشيء ، زاد توفير الذاكرة. وفقًا لذلك ، على العكس من ذلك ، فكلما زاد عدد المكتبات "الخاصة بك" التي يقدمها التطبيق ، كلما زاد عدد "الدهون" الموجودة فيه.
- النقاش حول من يراقب نقاط الضعف هو النظام (توفير تحديثات المكتبة) أو مؤلف التطبيق (تحديثه في الوقت المحدد).
- حل تعارض التبعيات (البيع يحل هذه المشكلة حيث تتطلب المكتبات المشتركة الاهتمام والدقة من جميع المشاركين في العملية ، مما يخلق أحيانًا صعوبات لا يمكن التغلب عليها) ، وهي نفس الجحيم الأسطوري.
- إصدارات جديدة من المكتبات - إما أنها تظهر بناءً على طلب مؤلفي التطبيق ، أو بقرار من مؤلفي التوزيع. في إحدى الحالات ، يمكن للمؤلف إحضار الميزة الجديدة التي يحتاجها ، وفي حالة أخرى ، يمكن للتوزيع أن يحقق تحسينًا للتطبيق الحالي من خلال دعم شيء جديد في المكتبة (على سبيل المثال ، بدأت شاشات hidpi تعمل بشكل صحيح في جميع التطبيقات المرتبطة ديناميكيًا بمكتبات qt / gtk) .
كل هذه القضايا تم التعامل معها عدة مرات من قبل. بدلاً من ذلك ، أريد التركيز على الجوانب الاجتماعية لمستجمعات المياه "جميع الألغام" و "جميع الأماكن المشتركة".
العقد الاجتماعي والمحافظون على السلطة
المكتبات المشتركة هي التعاون والقوة والمسؤولية. يملي الأشخاص الذين يحددون المكتبات المشتركة المتوفرة في نظام التشغيل لمصنعي البرامج ما هي المكتبات المشتركة التي يمكنهم استخدامها. يمكن أن يستخدم الكثير من البرامج مكتبات مختلفة ، ويتم ترك الإشارة إلى الإصدار الدقيق المراد استخدامه لتقدير الرابط (بالنسبة للغات المترجمة) أو معالج ملفات التبعية (نقطة ، حزمة ، إلخ). إذا تم تجميع جميع التطبيقات في التوزيع مع نفس المتطلبات ، فستأتي فترة السماح: إذا حدث خطأ في بعض المكتبات ، يقوم مشرف هذه المكتبة بتحديث الإصدار ، ويتم تطبيق الإصلاح تلقائيًا على جميع التطبيقات. حتى إذا تم إصدار التطبيق كل عامين ، فسيتم تطبيق الإصلاح في openssl الشرطية في غضون أسبوع. إذا تم اتخاذ قرار في نظام تشغيل معين بالتخلي عن البروتوكول القديم ، وبعض التعديلات (على سبيل المثال ، واجهة المستخدم) ، فإن هذه التغييرات تنطبق أيضًا على الجميع. انظر وشعر بأسلوب عام يمكن (ربما) تغييره بواسطة المستخدم نهائيًا. أليس هذا نعمة؟
القوة والنضال من أجلها
... تتطلب هذه النعمة أن تعمل جميع التطبيقات مع الإصدار المحدد من المكتبة. ولكن ماذا لو أراد بعض التطبيقات وظيفة جديدة جدًا جدًا من المكتبة ، ولا ترغب جميع التطبيقات الأخرى في استخدامها ، لأن هذا ، على سبيل المثال ، ليس إصدار LTS للمكتبة ، على سبيل المثال أليس مستقرا بما فيه الكفاية؟ لكن مجموعة التوزيع قد ترفض التبديل إلى الإصدارات الجديدة "خارج المبدأ" ، لأننا وعدنا المستخدمين بإصلاح الأخطاء فقط ، والإصدارات الجديدة فقط في الإصدار التالي من نظام التشغيل ، والتي (مثل) ستصدر خلال نصف عام. وهذا يسبب مقاومة من مؤلفي التطبيق. من أنت لتخبرني ما هي الإصدارات التي يجب أن أعمل معها؟ أنا مؤلف ، أراه بهذه الطريقة. أحتاج libfoobar 3.14-pre2 أو أكبر ، وليس لديك libfoobar القديمة مملة 3.10.
... عند هذه النقطة ، يكتب المؤلف ببساطة في متطلبات التطبيق libfoobar>=3.14-pre2
. يأخذ المشرف ويصحح الطلب ، بالإضافة إلى حذف الكود الذي يعتمد على هذه المكتبة. ربما. أو ببساطة يرفض قبول إصدار جديد بمثل هذه التبعية حتى تصبح هذه التبعية (libfoobar 3.16) في الإصدار الجديد من التوزيع.
إذا كان المؤلف يحتاج المستخدمين حقًا إلى استخدام الإصدار الجديد (على سبيل المثال ، لأن المؤلف لا يريد دعم الإصدار القديم) ، فإنه يبحث عن حلول لإرسال التطبيق إلى المستخدم.
يحدث الشيء نفسه عندما يكون هناك عدة توزيعات ، بعضها أحدث وبعضها أقدم. من الصعب الحفاظ على التوزيعات القديمة ، مع اختبار المكتبات المختلفة. لذلك يظهر الخيار "شحن مع مكتباتك" على الفور تقريبًا.
مأساة المجتمع
هذا يخلق الشروط الأساسية لظهور مأساة المجتمع:
- يريد كل مصنع (مؤلف برمجي) الشحن حسب حاجته. يعد التكيف مع قواعد الآخرين (الإصدارات) مضيعة للوقت والجهد ، والأهم من ذلك أن هناك العديد من التوزيعات المختلفة في العالم
- المستخدمين يريدون إصدارات جديدة.
في الوقت نفسه ، كلما زاد عدد التطبيقات التي تأتي مع مكتباتها ، كلما كان استخدام مكتبات النظام أقل. تذكر جريس؟ كلما كانت "عالمية" ، كلما قلت النعمة. إذا تم استخدام مكتبة مشتركة بواسطة 5 تطبيقات مختلفة من بين 995 تطبيقًا آخر ، فستكون فائدة هذه المكتبة 0.5٪. إنه عار ، نعم. علاوة على ذلك ، هذا يؤذي جميع المستخدمين ، حتى أولئك الذين ، من حيث المبدأ ، ليس لديهم حاجة ماسة لميزة جديدة - ولكن إذا كان التطبيق متاحًا فقط في نموذج البيع ، فلن يكون لدى المستخدم خيارات.
لقد تبيّن لنا أن لدينا نطاقًا عالميًا: تستخدم جميع التطبيقات المكتبات المشتركة فقط (الحد الأقصى للنعمة الشائعة ، إزعاج مؤلفي التطبيقات الفردية) أو "كل بمفرده" (توزيع كثيف مع مجموعة من التطبيقات التي قد تحتوي على ثغرات أمنية غير مكتشفة ولكن مستخدمة على نطاق واسع ، تناول مجموعة من الذاكرة ، لكن مؤلف كل تطبيق مناسب).
هذا هو المكان الذي نأتي فيه إلى النزاع rpm / deb VS snap / flatpack
حرية أم عبودية؟
أوبونتو جدا ، بقوة المدافعين عن snap'y. جنوم واثق من أن المستقبل هو في flatpacks. كل واحد منهم هو إطار للتطبيقات الفردية بعمق. جميع أنواع الإلكترونات التي لا تحتوي على غطاء مقصورة المحرك فحسب ، بل وأيضًا نظام تشغيل مقصورة المحرك. libc ، libssl الخاصة ، regexp الخاصة ، ncurses الخاصة ، إلخ. فقط الأفعال الأساسية شائعة ، أي في الواقع ، هذا هو نفس التطبيق الذي يحمل حاوية ، ولكن لسطح المكتب. امنح كل وحدة أساسية خاصة بك ، وستحصل على الأجهزة في شكل جهاز افتراضي. أضف البيانات الوصفية - وستحصل على حاوية Docker.
فردية التطبيقات (مؤلفو التطبيق) مفهومة ، لكن من الذي يقف بعد ذلك من أجل الصالح العام؟ ويقابل تحسن محلي كبير انخفاض طفيف في التوزيع العام مضروب في التطبيقات البحتة. إذا قام الجميع بإجراء تحسينات محلية لأنفسهم ، فستكون قيمة انخفاض القيمة أكبر من فائدة مبلغ التحسين.
يبدو أنه في هذا المكان يجب أن يتصرف مبدعو التوزيعات كأوصياء على المصلحة العامة. ومع ذلك ...
السياسة
تعتمد Ubuntu على دبيان أكثر مما ترغب Canonical (شركة Ubuntu). لا تكمن قيمة Ubuntu في جهود مشرفي Ubuntu ، ولكن في مستودع برمجيات ضخم قادم من دبيان في شكل تعمل فيه جميع التطبيقات جيدًا من خلال جهود الآلاف من مشرفي الحزم الفردية التي تمتلك توزيع دبيان. يضيف Canonical علاوة على ذلك جهوده لتلميع النتيجة - ولهذا فهو محبوب من قبل البعض. أضف القليل من التسويق ودورة حياة ثابتة ، والتي ترضي المؤسسة ، ونحصل على منتج رائع.
... وهذا يعتمد على إرادة الآلاف من المتطوعين في مكان ما هناك.
التي لا تناسب أي شركة تجارية تقريبا. كيفية كسر هذا الإدمان؟ هذا صحيح عن طريق إنشاء حزمة التطبيق الخاصة بك. كلما زاد عدد التطبيقات ، ستؤثر الشركة في عمليات التنقيب في المنبع. يكفي أن نتذكر القصة عندما قام تصويت في دبيان على systemd بدفن مغرور ، التي وضعتها Canonical.
لكن احتفظ بعشرات الآلاف من التطبيقات ، بعضها مساحة خاصة بها (erlang ، و go ، و perl ، و python ، و R ، و julia ، إلخ) ، وبعضها وحوش في مجال الموضوع المقابل (المتصفحات ، emacs ، tex ، منظم ضربات القلب ، إلخ) - هذه هي العمل الثقيل. لا عجب أن هؤلاء الآلاف من المشرفين.
... وهناك فكرة. واسمحوا لمؤلفي التطبيق أنفسهم صيانة التطبيقات. دعونا نعطي الجميع صندوقًا للرمل ، ودعهم يحفرون. يحصل المؤلفون على الحرية ، الكنسي - التطبيقات التي لا تعتمد على دبيان والتي يحتفظ بها شخص على الأقل مجانًا. يحصل المستخدمون على ...
... تطبيقات سمينه ، ثقيلة ، مع تحديثات غير منتظمة والتي يمكن أن تبقي نقاط الضعف دون تصحيح بسهولة لسنوات ... ولكن بعضها جديد لامعة.
إذن ماذا بعد؟
تخيل عالما يحمل فيه الجميع كل شيء معهم ... هل تعرف كيف يبدو؟ نلقي نظرة على chefsdk. انه يشحن مع نفسه داخل postgresql (مع تبعياته) ، rabbitmq (الذي يعتمد على erlang له) ، بالإضافة إلى الشيف سيرفر هو أيضا على erlang ، لذلك لديه أيضا erlang الخاصة به. فجأة ، لدينا عتادان وعشرات نسخ من نفس المكتبات داخل نفس التطبيق ، مختلفة قليلاً في الإصدار. ليس هذا هو الخيار النهائي ، كما في الداخل ، لا تزال هناك مكتبات مشتركة بين المكونات. إذا قطعناها أكثر ، فسنحصل على عشرات النسخ من openssl و libc لتطبيق واحد. حتى في شكله النهائي ، يبدو 600 ميجابايت لكل تطبيق.
... والذي ، بالطبع ، هو مضاعف للتطبيق الإلكترون المتوسط ... وأكبر 12 مرة من خادم mariadb بأكمله (DBMS بأكمله!) ، أو krita أو gimp (تطبيقات رسومات ضخمة).
وإذا كان الجميع سيكون من هذا القبيل؟ لدي 2000 حزمة مثبتة على جهاز الكمبيوتر الخاص بي (لا يتم احتساب -dev و lib) ... 2000 * 300 = 600GB (بالنسبة لمتوسط حجم النتيجة ، أخذت نصف من chefsdk ، لأنه ليس كل شخص فظيعًا جدًا بسبب التبعيات). يشغلون الآن حوالي 7 غيغابايت (بما في ذلك الموارد ، مثل الوثائق ومحررات الملمس وقوالب CAD وما إلى ذلك).
إذا تحول هذا إلى 600 جيجابايت ، فهل هذه مأساة خالصة للمجتمعات؟ في كل لحظة ، نلاحظ التحسين المحلي (وحل إزعاج شخص آخر) ، ولكن معًا ، يقلل مجموع هذه التحسينات المحلية من الأمثلية العامة للنظام. في رأيي ، أكثر من مكسب محلي لكل من المشاركين.
أنا أفهم لماذا يدفع Canonical المفاجئة. أنا أفهم هذا ، ولا أوافق.