pprof هي أداة التنميط الرئيسية في Go. يتم تضمين ملف التعريف في مكتبة Go القياسية وقد كتب الكثير عن ذلك على مر السنين. لتوصيل pprof إلى تطبيق موجود ، ما عليك سوى إضافة سطر واحد من التعليمات البرمجية:
import _ “net/http/pprof”
في خادم HTTP الافتراضي - net/http.DefaultServeMux
- سيتم تسجيل معالجات إرسال نتائج التنميط على طول المسار /debug/pprof/
.
curl -o cpu-profile.pb.gz http://<server-addr>/debug/pprof/profile
(لمزيد من التفاصيل ، انظر https://godoc.org/net/http/pprof )
ولكن من التجربة ، ليس الأمر دائمًا بهذه البساطة ، وفي الممارسة العملية باستخدام pprof في المعركة ، فهناك مطبات.
بادئ ذي بدء ، لا نريد معالجات ملفات التعريف التمسك بها على الإنترنت. يعد التوصيف رخيصًا ، من حيث النفقات العامة ولكنه غير مجاني ، ويحتوي الملف الشخصي نفسه على معلومات حول الهيكل الداخلي للتطبيق ، والذي لا ينصح غالبًا بفتحه أمام الغرباء. يجب عليك التأكد من أن مسار /debug
لا يمكن الوصول إليه للمستخدمين غير المصرح لهم. يمكن أن يكون الوصول محدودًا من جانب الخادم الوكيل أو يمكن نقل خادم pprof إلى منفذ منفصل ، وسيتم فتح الوصول إليه فقط من خلال المضيف المميز.
ولكن ماذا لو لم يتضمن التطبيق وصول HTTP على الإطلاق - على سبيل المثال ، هل هو معالج قائمة انتظار في وضع عدم الاتصال؟
بناءً على حالة البنية التحتية في الشركة ، قد يثير خادم HTTP "المفاجئ" داخل عملية التطبيق أسئلة من قسم العمليات ؛) يحد الخادم بالإضافة إلى ذلك من إمكانيات القياس الأفقي ، لأن لن يعمل الأمر فقط لتشغيل مثيلات متعددة للتطبيق على نفس المضيف - تتعارض العمليات ، في محاولة لفتح نفس منفذ TCP لخادم pprof.
حل "بسيط" عن طريق عزل كل عملية تطبيق في الحاوية (أو تشغيل خادم pprof على منفذ فريد أو مقبس UNIX). لن تفاجئ أي شخص بعد الآن بخدمة موسعة أفقياً في مئات الحالات ، "منتشرة" عبر العديد من مراكز البيانات. في بنية تحتية ديناميكية للغاية ، يمكن للحاويات مع التطبيق أن تظهر وتختفي بشكل دوري. وما زلنا بحاجة للاتصال بطريقة ما بالملف. وهذا يعني أنه بغض النظر عن طريقة القياس المحددة ، هناك حاجة إلى آليات بحث لمثيل تطبيق معين ومنفذ خادم pprof المقابل.
بناءً على خصائص الشركة ، فإن وجود القدرة على الوصول إلى شيء غير متعلق بنشاط الإنتاج الرئيسي للخدمة قد يثير أسئلة من قسم الأمن ؛) عملت في شركة حيث ، لأسباب موضوعية ، يكون الوصول إلى أي شيء على جانب وكان الإنتاج حصرا في قسم العمليات. كانت الطريقة الوحيدة لتشغيل برنامج التعريف في تطبيق قيد التشغيل هي فتح مهمة في أداة تتبع علة العملية ، مع وصف لأي أمر curl ، وفيه DC ، على الخادم الذي تريد تشغيله ، وما هي النتيجة المتوقعة وماذا تفعل به.
أو تخيل الموقف: صباح العمل. قمت بفتح Slack واكتشفت أنه في المساء ، في إحدى عمليات خدمة الإنتاج "حدث خطأ ما" ، "في مكان ما ، شيء ما" تم إيقافه "،" بدأت الذاكرة تتدفق "،" تم الزحف إلى رسومات وحدة المعالجة المركزية "أو التطبيق بدأ للتو في الذعر. لم تقم فرق التشغيل (أو OOM Killer) بالتنقيب بعمق وإعادة تشغيل التطبيق أو إعادة إصدار أحدث إصدار في اليوم السابق.
بعد الحقيقة ، ليس من السهل فهم مثل هذه المواقف. من الرائع أن تتكرر المشكلة في بيئة اختبار (أو في جزء معزول من الإنتاج يمكنك الوصول إليه). يمكنك جمع البيانات اللازمة مع جميع الأدوات الموجودة ، ومن ثم معرفة أي مكون هي المشكلة.
ولكن إذا لم تكن هناك طريقة واضحة لإعادة إنتاج المشكلة ، فهل تركنا فقط مع سجلات ومقاييس الأمس؟ في مثل هذه المواقف ، من العار دائمًا ألا يمكنك الترجيع عن الوقت إلى اللحظة التي كانت فيها المشكلة مرئية في الإنتاج وجمع كل الملفات الشخصية الضرورية بسرعة ، بحيث يتم التحليل لاحقًا في وضع هادئ.
ولكن إذا كانت pprof رخيصة نسبيًا ، فلماذا لا تجمع بيانات التوصيف تلقائيًا ، في بعض الفترات ، وتخزينها في مكان منفصل عن الإنتاج ، حيث يمكنك منح حق الوصول إلى جميع المهتمين؟
في عام 2010 ، نشرت Google وثيقة Google-Profiling: بنية تحتية مستمرة للتوصيف لمراكز البيانات ، والتي تصف نهجًا للتوصيف المستمر لأنظمة الشركة. وبعد بضع سنوات ، أطلقت الشركة خدمة وضع ملفات تعريف مستمرة - Stackdriver Profiler - متاحة للجميع.
مبدأ التشغيل بسيط: فبدلاً من خادم pprof ، يتم توصيل وكيل stackdriver بالتطبيق ، الذي يقوم ، من خلال واجهة برمجة تطبيقات runtime/pprof
مباشرة ، بجمع أنواع مختلفة من ملفات التعريف من التطبيق وإرسال ملفات التعريف إلى السحابة بشكل دوري. كل ما يحتاجه المطور ، باستخدام لوحة التحكم Stackdriver ، حدد مثيل التطبيق المطلوب في AZ المطلوب ، وبعد ذلك ، يمكنك تحليل التطبيق في أي وقت في الماضي.
يوفر مزودو خدمات SaaS الأخرى وظائف مماثلة. ولكن ، قد تمنع قواعد الأمان لشركتك تصدير البيانات خارج بنيتها الأساسية. والخدمات التي تسمح لك بنشر نظام ملفات تعريف مستمر على الخوادم الخاصة بك ، لم أر.
جميع الصعوبات والأفكار الموضحة أعلاه بعيدة عن أن تكون جديدة ومحددة ليس فقط لـ Go. معهم ، بشكل أو بآخر ، يواجه المطورون جميع الشركات التي عملت فيها تقريبًا.
في مرحلة ما ، شعرت بالفضول لمحاولة بناء نسخة تماثلية من Stackdriver Profiler لخدمة Go Go التعسفية التي يمكن أن تحل المشكلات الموصوفة. كمشروع هواية ، في وقت فراغي ، أعمل على profefe ( https://github.com/profefe/profefe ) - خدمة مفتوحة للتوصيف المستمر. لا يزال المشروع في مرحلة التجارب والمناقشات الدورية ، ولكنه مناسب بالفعل للاختبار.
المهام التي قمت بتعيينها للمشروع:
- سيتم نشر الخدمة على البنية التحتية الداخلية للشركة.
- سيتم استخدام الخدمة كأداة داخلية للشركة. يمكنك الوثوق بموردي ومستهلكي البيانات: في المراحل المبكرة ، يمكنك حذف إذن طلبات الكتابة / القراءة وعدم محاولة حماية نفسك من الاستخدام الضار مقدمًا.
- لا ينبغي أن يكون للخدمة أي توقعات خاصة من البنية التحتية للشركة: كل شيء يمكن أن يعيش في السحابة أو في البلدان النامية ؛ يمكن تشغيل التطبيقات المحددة داخل حاويات ("يتم التحكم في كل شيء بواسطة Kubernetes") أو يمكن تشغيله على المعدن العاري.
- يجب أن تكون الخدمة سهلة التشغيل (يبدو إلى حد ما ، بروميثيوس مثال جيد).
- يجب أن يكون مفهوما أن البنية المحددة قد لا تفي بالشروط التي سيتم فيها استخدام الخدمة. على الأرجح ، ستحتاج إلى القدرة على توسيع / استبدال مكونات النظام لتوسيع نطاق "على الفور".
- وفقًا لـ (4) ، يجب أن نحاول تقليل التبعيات الخارجية المطلوبة. على سبيل المثال ، يجب أن تبحث الخدمة بطريقة ما عن مثيلات للتطبيقات الشخصية ، ولكن على الأقل في المراحل الأولية ، أريد القيام به دون اكتشاف خدمة صريح.
- ستقوم الخدمة بتخزين وتصنيف ملفات تعريف تطبيقات Go. نتوقع أن يشغل ملف pprof واحد 100 كيلو بايت - 2 ميجابايت ( عادةً ما تكون ملفات تعريف الكومة أكبر بكثير من ملفات تعريف وحدة المعالجة المركزية ). من حالة ملف تعريف واحد ، ليس من المنطقي إرسال أكثر من ملفات تعريف N في الدقيقة (يرسل وكيل Stackdriver ، في المتوسط ، ملفي تعريف في الدقيقة الواحدة). يجدر الحساب على الفور أن تطبيقًا واحدًا يمكن أن يحتوي على عدة مئات من الحالات.
- من خلال الخدمة ، يبحث المستخدمون عن أنواع مختلفة من ملفات التعريف (cpu ، الكومة ، المزامنة ، إلخ) للتطبيق أو مثيل معين من التطبيق لفترة زمنية محددة.
- من الخدمة ، سيطلب المستخدم ملف تعريف pprof منفصل من نتائج البحث.
الآن profefe يتكون من عنصرين:
profefe-collector هو جامع الخدمة مع واجهة برمجة تطبيقات RESTful بسيطة.
مهمة المجمع هي الحصول على ملف pprof وبعض البيانات الوصفية وحفظها في التخزين الدائم. تتيح واجهة برمجة التطبيقات للعملاء أيضًا البحث عن ملفات التعريف عن طريق البيانات الوصفية في نافذة زمنية معينة أو قراءة ملف تعريف معين (أو مجموعة من ملفات التعريف من نفس النوع) من المتجر.
الوكيل - مكتبة اختيارية يجب توصيلها بالتطبيق بدلاً من خادم pprof. داخل التطبيق ، في goroutine منفصل ، يبدأ الوكيل بشكل دوري عملية التشكيل الجانبي (باستخدام runtime/pprof
) ، ويرسل ملفات تعريف pprof المستلمة ، جنبًا إلى جنب مع بيانات التعريف إلى المجمع.
بيانات التعريف هي مجموعة قيمة مفتاح تعسفي تصف تطبيقًا أو مثيله الفردي. على سبيل المثال: اسم الخدمة والإصدار ومركز البيانات والمضيف حيث يتم تشغيل التطبيق.

Profefe مكون مخطط التفاعل
ذكرت أعلاه أن الوكيل هو مكون اختياري. إذا لم يكن من الممكن توصيله بتطبيق موجود ، ولكن خادم net/http/pprof
متصل بالفعل في التطبيق ، يمكن إزالة ملفات التعريف باستخدام أي أدوات خارجية وإرسال ملفات pprof إلى المجمع عبر واجهة برمجة تطبيقات HTTP.
على سبيل المثال ، على الأجهزة المضيفة ، يمكنك تكوين مهمة cron تقوم بجمع الملفات الشخصية بشكل دوري من الحالات قيد التشغيل وإرسالها إلى profee للتخزين ؛)

مهمة Cron تجمع وترسل ملفات تعريف التطبيق إلى profee جامع
يمكنك قراءة المزيد عن واجهة برمجة تطبيقات profefe في الوثائق الموجودة على جيثب .
خطط
حتى الآن ، فإن الطريقة الوحيدة للتفاعل مع جامع profefe هي HTTP API. تتمثل إحدى مهام المستقبل في تجميع خدمة UI منفصلة يمكن من خلالها عرض البيانات المخزنة بصريًا: نتائج البحث ، نظرة عامة عامة على أداء المجموعة ، إلخ.
ليس جمع البيانات الشخصية وتخزينها أمرًا سيئًا ، ولكن "بدون التطبيق ، تكون البيانات عديمة الفائدة". لدى الفريق الذي أعمل فيه مجموعة من الأدوات التجريبية لجمع الإحصاءات الأساسية للعديد من الملفات الشخصية المقدمة من الخدمة. يساعد هذا كثيرًا في تحليل عواقب تحديث التبعيات الرئيسية للتطبيق أو نتائج إعادة هيكلة كبيرة ( لسوء الحظ ، لا يفي الأداء في الإنتاج دائمًا بالتوقعات بناءً على إطلاق معايير معزولة والتنميط في بيئة اختبار ). أرغب في إضافة وظائف مماثلة لمقارنة وتحليل الملفات الشخصية المخزنة في واجهة برمجة تطبيقات profefe.
على الرغم من أن التركيز الرئيسي لـ profefe هو التشكيل الجانبي المستمر لخدمات Go ، إلا أن تنسيق ملف pprof ليس مرتبطًا على الإطلاق بـ Go. بالنسبة إلى Java و JavaScript و Python وما إلى ذلك ، هناك مكتبات تتيح لك الحصول على بيانات ملفات التعريف بهذا التنسيق. ربما تصبح profefe خدمة مفيدة للتطبيقات المكتوبة بلغات أخرى.
من بين أشياء أخرى ، يحتوي المستودع على عدد من الأسئلة المفتوحة الموضحة في تعقب المشروع على GitHub .
استنتاج
في السنوات القليلة الماضية ، تم ترسيخ فكرة شائعة بين المطورين: لتحقيق " قابلية الملاحظة " للخدمة ، هناك حاجة إلى ثلاثة مكونات: المقاييس والسجلات والتتبع (" الركائز الثلاث للرصد "). يبدو لي أن الرؤية هي القدرة على الإجابة بشكل فعال على الأسئلة حول صحة النظام ومكوناته. تتيح المقاييس والتتبع فهم النظام ككل. تغطي السجلات الأجزاء الموصوفة عمداً من النظام. التنميط هو إشارة أخرى لتحقيق الرؤية ، مما يتيح لك فهم النظام على المستوى الجزئي. يساعد التوصيف المستمر على مدار فترة من الزمن أيضًا في فهم كيفية تأثير المكونات الفردية والبيئة والتأثير على إمكانية تشغيل النظام بأكمله وإنتاجيته.