يوفر Uber JVM Profiler وكيل Java لجمع المقاييس المختلفة وتتبعات المكدس لعمليات Hadoop/Spark JVM بطريقة موزعة، على سبيل المثال، مقاييس وحدة المعالجة المركزية/الذاكرة/الإدخال والإخراج.
يوفر Uber JVM Profiler أيضًا إمكانات تحليل بيانات متقدمة لتتبع أساليب ووسائط Java التعسفية على رمز المستخدم دون الحاجة إلى تغيير رمز المستخدم. يمكن استخدام هذه الميزة لتتبع زمن انتقال استدعاء عقدة اسم HDFS لكل تطبيق Spark وتحديد عنق الزجاجة لعقدة الاسم. يمكنه أيضًا تتبع مسارات ملفات HDFS التي يقرأها أو يكتبها كل تطبيق Spark ويحدد الملفات الساخنة لمزيد من التحسين.
تم إنشاء ملف التعريف هذا في البداية لملف تعريف تطبيقات Spark التي تحتوي عادةً على عشرات أو مئات من العمليات/الآلات لتطبيق واحد، بحيث يمكن للأشخاص ربط مقاييس هذه العمليات/الآلات المختلفة بسهولة. وهو أيضًا وكيل Java عام ويمكن استخدامه لأي عملية JVM أيضًا.
mvn clean package
يقوم هذا الأمر بإنشاء ملف jvm-profiler.jar مع أدوات المراسلة الافتراضية مثل ConsoleOutputReporter وFileOutputReporter وKafkaOutputReporter المجمعة فيه. إذا كنت تريد تجميع المراسلين المخصصين مثل RedisOutputReporter أو InfluxDBOutputReporter في ملف jar، فقم بتوفير معرف ملف تعريف maven لهذا المراسل في أمر الإنشاء. على سبيل المثال، لإنشاء ملف jar باستخدام RedisOutputReporter، يمكنك تنفيذ أمر mvn -P redis clean package
. يرجى التحقق من ملف pom.xml لمعرفة المراسلين المخصصين المتاحين ومعرفات ملفاتهم الشخصية.
يمكنك تحميل ملف jvm-profiler jar إلى HDFS حتى يتمكن منفذو تطبيق Spark من الوصول إليه. ثم أضف التكوين كما يلي عند تشغيل تطبيق Spark:
--conf spark.jars=hdfs://hdfs_url/lib/jvm-profiler-1.0.0.jar
--conf spark.executor.extraJavaOptions=-javaagent:jvm-profiler-1.0.0.jar
سيبدأ الأمر التالي تطبيق المثال مع وكيل ملف التعريف المرفق، والذي سيبلغ عن المقاييس إلى مخرجات وحدة التحكم:
java -javaagent:target/jvm-profiler-1.0.0.jar=reporter=com.uber.profiling.reporters.ConsoleOutputReporter,tag=mytag,metricInterval=5000,durationProfiling=com.uber.profiling.examples.HelloWorldApplication.publicSleepMethod,argumentProfiling=com.uber.profiling.examples.HelloWorldApplication.publicSleepMethod.1,sampleInterval=100 -cp target/jvm-profiler-1.0.0.jar com.uber.profiling.examples.HelloWorldApplication
استخدم الأمر التالي لتشغيل ملف تعريف jvm مع تطبيق jar القابل للتنفيذ.
java -javaagent:/opt/jvm-profiler/target/jvm-profiler-1.0.0.jar=reporter=com.uber.profiling.reporters.ConsoleOutputReporter,metricInterval=5000,durationProfiling=foo.bar.FooAppication.barMethod,sampleInterval=5000 -jar foo-application.jar
قم بتعيين ملف تعريف jvm في CATALINA_OPTS قبل بدء تشغيل خادم Tomcat. تحقق من ملف logs/catalina.out لمعرفة المقاييس.
export CATALINA_OPTS="$CATALINA_OPTS -javaagent:/opt/jvm-profiler/target/jvm-profiler-1.0.0.jar=reporter=com.uber.profiling.reporters.ConsoleOutputReporter,metricInterval=5000,durationProfiling=foo.bar.FooController.barMethod,sampleInterval=5000"
استخدم الأمر التالي لاستخدام ملف تعريف jvm مع Spring Boot 2.x. بالنسبة لـ Spring Boot 1.x، استخدم -Drun.arguments
بدلاً من -Dspring-boot.run.jvmArguments
في الأمر التالي.
mvn spring-boot:run -Dspring-boot.run.jvmArguments="-javaagent:/opt/jvm-profiler/target/jvm-profiler-1.0.0.jar=reporter=com.uber.profiling.reporters.ConsoleOutputReporter,metricInterval=5000,durationProfiling=foo.bar.FooController.barMethod,sampleInterval=5000"
يدعم Uber JVM Profiler إرسال المقاييس إلى Kafka. على سبيل المثال،
java -javaagent:target/jvm-profiler-1.0.0.jar=reporter=com.uber.profiling.reporters.KafkaOutputReporter,metricInterval=5000,brokerList=localhost:9092,topicPrefix=profiler_ -cp target/jvm-profiler-1.0.0.jar com.uber.profiling.examples.HelloWorldApplication
سيتم إرسال المقاييس إلى ملف تعريف موضوع كافكا_CpuAndMemory. انظر أسفل هذا المستند للحصول على مثال للمقاييس.
راجع منشور مدونة ملف تعريف JVM.
يدعم Uber JVM Profiler الميزات التالية:
تصحيح أخطاء استخدام الذاكرة لجميع منفذي تطبيق Spark، بما في ذلك ذاكرة Java الكومة والذاكرة غير الكومة والذاكرة الأصلية (VmRSS وVmHWM) وتجمع الذاكرة وتجمع المخزن المؤقت (المخزن المؤقت الموجه/المعين).
تصحيح استخدام وحدة المعالجة المركزية (CPU)، ووقت تجميع البيانات المهملة لجميع منفذي الشرارة.
تصحيح أساليب فئة جافا التعسفية (عدد مرات تشغيلها، وكم المدة التي تقضيها). نحن نسميها تحديد المدة.
تصحيح أخطاء استدعاء أسلوب فئة جافا التعسفي وتتبع قيمة الوسيطة. نحن نسميها ملف تعريف الوسيطة.
قم بإجراء Stacktrack Profiling وقم بإنشاء مخطط لهب لتصور الوقت الذي تستغرقه وحدة المعالجة المركزية في تطبيق الشرارة.
تصحيح مقاييس الإدخال والإخراج (وحدات البايت للقراءة/الكتابة على القرص للتطبيق، وانتظار وحدة المعالجة المركزية للجهاز).
تصحيح مقاييس سلسلة JVM مثل عدد إجمالي الخيوط وخيوط الذروة والخيوط المباشرة/النشيطة والخيوط الجديدة.
يدعم وكيل Java المعلمات التالية، والتي يمكن استخدامها في سطر أوامر Java مثل "-javaagent:agent_jar_file.jar=param1=value1,param2=value2":
Reporter: اسم الفئة للمراسل، على سبيل المثال com.uber.profiling.reporters.ConsoleOutputReporter، أو com.uber.profiling.reporters.KafkaOutputReporter، والتي تم تنفيذها بالفعل في التعليمات البرمجية. يمكنك تنفيذ المراسل الخاص بك وتعيين الاسم هنا.
configProvider: اسم الفئة لموفر التكوين، على سبيل المثال com.uber.profiling.YamlConfigProvider، والتي تم تنفيذها بالفعل في التعليمات البرمجية. يمكنك تنفيذ موفر التكوين الخاص بك وتعيين الاسم هنا.
configFile: مسار ملف التكوين الذي سيتم استخدامه بواسطة YamlConfigProvider (إذا تم تعيين configProvider على com.uber.profiling.YamlConfigProvider). يمكن أن يكون هذا مسار ملف محلي أو عنوان URL HTTP.
العلامة: سلسلة نصية عادية سيتم الإبلاغ عنها مع المقاييس.
metricInterval: مدى تكرار جمع المقاييس والإبلاغ عنها بالمللي ثانية.
DurationProfiling: تكوين لملف تعريف فئة وطريقة معينة، على سبيل المثال com.uber.profiling.examples.HelloWorldApplication.publicSleepMethod. كما أنه يدعم حرف البدل (*) لاسم الطريقة، على سبيل المثال com.uber.profiling.examples.HelloWorldApplication.*.
arrayProfiling: تكوين لملف تعريف وسيطة أسلوب معين، على سبيل المثال com.uber.profiling.examples.HelloWorldApplication.publicSleepMethod.1 (".1" يعني الحصول على قيمة للوسيطة الأولى وإرسالها في المراسل).
SampleInterval: التردد (بالميلي ثانية) لإجراء أخذ عينات تتبع المكدس، إذا لم يتم تعيين هذه القيمة أو كانت صفرًا، فلن يقوم مُنشئ ملفات التعريف بأخذ عينات تتبع المكدس.
ioProfiling: تحديد ما إذا كان سيتم تحديد مقاييس الإدخال/الإخراج، قد يكون صحيحًا أو خطأ.
BrokerList: قائمة الوسطاء في حالة استخدام com.uber.profiling.reporters.KafkaOutputReporter.
themePrefix: بادئة الموضوع في حالة استخدام com.uber.profiling.reporters.KafkaOutputReporter. سيرسل KafkaOutputReporter مقاييس إلى موضوعات متعددة بهذه القيمة كبادئة لأسماء المواضيع.
OutputDir: دليل الإخراج في حالة استخدام com.uber.profiling.reporters.FileOutputReporter. سيقوم FileOutputReporter بكتابة المقاييس في هذا الدليل.
يمكن توفير المعلمات كوسائط في أمر Java، أو في ملف تكوين YAML إذا كنت تستخدم configProvider=com.uber.profiling.YamlConfigProvider. فيما يلي مثال على ملف التكوين YAML:
reporter: com.uber.profiling.reporters.ConsoleOutputReporter
metricInterval: 5000
فيما يلي مثال لمقاييس وحدة المعالجة المركزية والذاكرة عند استخدام ConsoleOutputReporter أو KafkaOutputReporter:
{
"nonHeapMemoryTotalUsed" : 11890584.0 ,
"bufferPools" : [
{
"totalCapacity" : 0 ,
"name" : " direct " ,
"count" : 0 ,
"memoryUsed" : 0
},
{
"totalCapacity" : 0 ,
"name" : " mapped " ,
"count" : 0 ,
"memoryUsed" : 0
}
],
"heapMemoryTotalUsed" : 24330736.0 ,
"epochMillis" : 1515627003374 ,
"nonHeapMemoryCommitted" : 13565952.0 ,
"heapMemoryCommitted" : 257425408.0 ,
"memoryPools" : [
{
"peakUsageMax" : 251658240 ,
"usageMax" : 251658240 ,
"peakUsageUsed" : 1194496 ,
"name" : " Code Cache " ,
"peakUsageCommitted" : 2555904 ,
"usageUsed" : 1173504 ,
"type" : " Non-heap memory " ,
"usageCommitted" : 2555904
},
{
"peakUsageMax" : -1 ,
"usageMax" : -1 ,
"peakUsageUsed" : 9622920 ,
"name" : " Metaspace " ,
"peakUsageCommitted" : 9830400 ,
"usageUsed" : 9622920 ,
"type" : " Non-heap memory " ,
"usageCommitted" : 9830400
},
{
"peakUsageMax" : 1073741824 ,
"usageMax" : 1073741824 ,
"peakUsageUsed" : 1094160 ,
"name" : " Compressed Class Space " ,
"peakUsageCommitted" : 1179648 ,
"usageUsed" : 1094160 ,
"type" : " Non-heap memory " ,
"usageCommitted" : 1179648
},
{
"peakUsageMax" : 1409286144 ,
"usageMax" : 1409286144 ,
"peakUsageUsed" : 24330736 ,
"name" : " PS Eden Space " ,
"peakUsageCommitted" : 67108864 ,
"usageUsed" : 24330736 ,
"type" : " Heap memory " ,
"usageCommitted" : 67108864
},
{
"peakUsageMax" : 11010048 ,
"usageMax" : 11010048 ,
"peakUsageUsed" : 0 ,
"name" : " PS Survivor Space " ,
"peakUsageCommitted" : 11010048 ,
"usageUsed" : 0 ,
"type" : " Heap memory " ,
"usageCommitted" : 11010048
},
{
"peakUsageMax" : 2863661056 ,
"usageMax" : 2863661056 ,
"peakUsageUsed" : 0 ,
"name" : " PS Old Gen " ,
"peakUsageCommitted" : 179306496 ,
"usageUsed" : 0 ,
"type" : " Heap memory " ,
"usageCommitted" : 179306496
}
],
"processCpuLoad" : 0.0008024004394748531 ,
"systemCpuLoad" : 0.23138430784607697 ,
"processCpuTime" : 496918000 ,
"appId" : null ,
"name" : " 24103@machine01 " ,
"host" : " machine01 " ,
"processUuid" : " 3c2ec835-749d-45ea-a7ec-e4b9fe17c23a " ,
"tag" : " mytag " ,
"gc" : [
{
"collectionTime" : 0 ,
"name" : " PS Scavenge " ,
"collectionCount" : 0
},
{
"collectionTime" : 0 ,
"name" : " PS MarkSweep " ,
"collectionCount" : 0
}
]
}
يمكن العثور على قائمة بجميع المقاييس والمعلومات المقابلة لها هنا.
يمكننا أن نأخذ مخرجات Stacktrack Profiling لإنشاء مخطط لهب لتصور وقت وحدة المعالجة المركزية. باستخدام برنامج Python النصي stackcollapse.py
، سيؤدي الأمر التالي إلى طي ملف إخراج Stacktrack Profiling json إلى تنسيق ملف الإدخال لإنشاء مخطط اللهب. يمكن العثور على البرنامج النصي flamegraph.pl
على FlameGraph.
python stackcollapse.py -i Stacktrace.json > Stacktrace.folded
flamegraph.pl Stacktrace.folded > Stacktrace.svg
لاحظ أنه مطلوب لتمكين أخذ عينات التتبع المكدس، من أجل إنشاء مخطط اللهب. لتمكينه، يرجى تعيين معلمة sampleInterval
. إذا لم يتم تعيينه أو صفر، فلن يقوم منشئ ملفات التعريف بأخذ عينات تتبع المكدس.