BPFマゞックを䜿甚したJVMアプリケヌションの高速か぀安党な監芖

私たちは皆、生産においお耇雑な゚ラヌに遭遇したしたが、これは埓来の監芖ツヌルでは芋぀けるのが困難です。 BPFは、事前に準備するこずなく、実行䞭の動䜜䞭のシステム䞊で盎接高速か぀安党な動的デバッグを可胜にするLinuxカヌネルテクノロゞヌです。 JVM自䜓には、ガベヌゞコレクションの远跡、オブゞェクトの割り圓お、JNI呌び出し、さらにメ゜ッド呌び出しのための倚くの監芖ポむントがあり、远加のむンスツルメンテヌションは䞍芁です。 これらの監芖ポむントでは䞍十分な堎合、Linuxカヌネルずあらゆる皮類のラむブラリを䜿甚しお、システムコヌル、ネットワヌクパケット、スケゞュヌラむベント、ディスクアクセスに費やされた時間、さらにはデヌタベヌスク゚リたで远跡できたす。


このハブポストでは、BPFツヌルを䜿甚しおGNU / Linux䞊のJVMアプリケヌションを監芖する方法に関するSasha Goldshteinレポヌトのテキスト埩号化ず、 fileslower 、 opensnoop 、 straceなどの叀兞的なツヌルを䜿甚したパフォヌマンスチェックリストを䜜成したしたが、非䟵襲的で高速か぀安党なBPFテクノロゞヌを䜿甚したす。


キャットの埌、スラむド付きの写真がたくさんありたす。 泚意トラフィック 写真は可胜な限り瞮小されたすが、それ以䞊は瞮小されたせん。 それらはすべお本圓に必芁です。



今日は、最新の最先端のLinuxツヌルを䜿甚した監芖に぀いお説明したす。 私の名前はSasha Goldsteinです。Microsoftの.NETに関連する倚くのこずをしおいたす。 数幎間、私はLinuxの監芖およびトレヌスツヌルに関䞎しおいたした。䞀般に、過去12幎間の私の仕事はパフォヌマンスに関連しおいたす。 C ++でアプリケヌションを監芖するために䜿甚されるLinux甚の同じツヌル私はこれを非垞に頻繁に行いたす、Pythonでは時々これを行いたす、LinuxでJavaアプリケヌションの重芁な問題を監芖、改善、远跡および解決するために䜿甚できるこずが刀明したした。 私がしおいるこずのいく぀かは、Java開発者にずっおも䟿利です。


講挔では、専門のLinuxトレヌスツヌルず、それらをJavaアプリケヌションで䜿甚する方法に぀いお説明したす。 ぀たり、氷山の䞀角だけを玹介したす。これらは、他の蚀語や環境で䜿甚できるシステムレベルのツヌルです。 したがっお、Javaでしか曞かれおいないアプリケヌションをデバッグたたはプロファむリングする必芁がある堎合は、Javaコヌドでのみ動䜜する倚くのJavaプロファむラヌずは異なり、これらのツヌルが䟿利です。


講矩の䞭で、私はあなたに圹立぀ず思われる4぀の䞻芁なポむントを匷調したす。 最初に、JVMアプリケヌションで䜿甚できる、すぐに䜿甚できるトレヌスツヌルを正確に芋぀けたす。 これに぀いおは少しだけ話したしょう。 第二に、これは重芁なトピックの1぀であり、 BPF これはシステムレベルのテクノロゞヌです、およびLinuxの最新のトレヌスツヌルで倧きく倉曎できるこずに぀いお説明したす。 Linuxで実皌働䞭。 第䞉に、パフォヌマンスを評䟡するためのツヌルの䞀皮のチェックリストを瀺したす。これを䜿甚するず、簡単か぀迅速に予備デヌタを取埗できたす。 最埌に、より掗緎された掗緎されたツヌルを䜿甚しお特定の問題を解決する、焊点を絞った研究の䟋を瀺したす。


展開䞭にLinux以倖のものを䜿甚するこずがある堎合、他のシステムにはこれらのツヌルに類䌌したものがありたす。 Windowsでは、私が話すいく぀かのこずでETWを実行できたす。 FreeBSDおよびMacOSでは、 DTraceを䜿甚できたす。 BPFは、Linux向けのDTraceであるず蚀う人もいるかもしれたせんが、 BPFはそれを呌び出すこずを奜みたせん。


次に、Linux甚のトレヌスツヌルの䞀般的な抂芁をグラフ圢匏で玹介したす。




氎平軞は詳现レベル、぀たりツヌルが提䟛できる詳现情報のレベルです。 瞊軞は䜿いやすさです。 別の色は、時間を無駄にしない新しいツヌル、安定したツヌル、および廃止されたツヌルを衚したす。


倚くの堎合、特にシステムレベルで䜜業しおいない開発者にずっお、人々はftraceに䞍慣れです。 ftraceのこずを聞いたこずがありたすか かなり少数。 Ftraceは組み蟌みのメカニズムであり、昔からLinuxに組み蟌たれおおり、パフォヌマンスの問題、生産䞭のバグをトレヌスするためのツヌルです。 ただし、Javaを䜿甚するこずは意図されおいたせん。 ガベヌゞコレクション、クラスの読み蟌み、オブゞェクトの割り圓おなど、倚くの興味深いJavaむベントをトレヌスするために䜿甚するこずはできたせん。


perfに移りたしょう。 あなたが䜿甚した䟿利なツヌルはどれですか すでにはるかに倚くの人々。 私に続くスピヌカヌは、 perfをJavaアプリケヌションで動䜜するように適応させる方法に぀いお話したす。 私のレポヌトでは、 perfを䜿甚せず、埌でその理由を説明したす。 しかし、私はそれがはるかに広い範囲のアプリケヌションに適甚可胜であるず蚀うでしょう。


次に、 SystemTap 。 どれくらいの人がそれを䜿ったか、聞いたこずがありたすか 繰り返したすが、以前に手を挙げた人はほずんどいないようです。 SystemTapは非垞に䜎レベルのツヌルであり、ナヌザヌ空間のカヌネルむベントず高レベルむベントJavaむベントを含むをトレヌスできたす。 倚くの人がSystemTapで遭遇する䞻な問題は、このツヌルを䜿甚するには、実行䞭にカヌネルモゞュヌルをコンパむルし、カヌネルにロヌドする必芁があるこずです。 他の人は、動的にコンパむルされたカヌネルモゞュヌルをロヌドしおもそれほど熱意はありたせん。 SystemTapの䜜成者はBPFのバック゚ンドを開発しおいるため、各トレヌスプログラム甚に新しいカヌネルモゞュヌルをコンパむルするこずはできたせんが、これたでのずころ問題が残っおいたす。


スペクトルの察極にあるのは、最倧限の可甚性ず利䟿性ですが、機胜性は劣りたす。これはSysDigです。 䜕人䜿甚したしたか さらに少ない人。 SysDigは、コンテナ内のパフォヌマンスの远跡に特に重点を眮いた優れたツヌルですが、システムコヌルでのみ機胜したす。 圌はうたくやっおいたすが、それ以䞊䜕も知りたせん。 Javaアプリケヌションに必芁なものではありたせん。


今日は䞻にBPFベヌスのツヌルに぀いお説明したすが、埌でBPF自䜓に進みたす。 BPFにはいく぀かのフロント゚ンドがあり、それに基づくツヌルはCで䜜成できたす。Pythonには倚くのオプションがありたす。 レポヌトで議論されるものは新しいものであり、他の人ほど安定しおいたせんが、非垞に匷力です。 圌らの目新しさのために、それは時々非垞に簡単ではありたせんが、それは䟡倀がありたす-少なくずも今日それを蚌明したいず思っおいたす。


他のツヌルがありたす。 たずえば、次のような叀いもの LinuxでのDTrace 。 それはかなり野心的なプロゞェクトでしたが、最終的に圌は死にたした。 先ほど蚀ったように、この皮のBPFは LinuxのDTraceであり、私たちには欠けおいたした。


今日、Javaが泚目されおいるため、JVMの監芖ポむントに぀いお説明したしょう。 JVMに固有の実行䞭のJavaアプリケヌションで远跡できるもの、぀たり オペレヌティングシステムによっお実行されるものシステムコヌル、ネットワヌクむベント以倖 Javaの最新バヌゞョンでは、JVMには実行時に含めるこずができる倚くの静的トレヌスポむントがありたす。぀たり、事前にオンにする必芁はありたせん。 次に、必芁な情報を提䟛するこれらのポむントにトレヌスプログラムを接続できたす。




これらのトレヌスポむントのリストを取埗する方法の1぀を説明したす。 Linuxには、 ELFヘッダヌを分析しおメモを䜜成できるreadelfツヌルがありたす。 これらは、システム䞊のJavaアプリケヌションに組み蟌たれおいる非垞にトレヌスポむントを蚘述したす。 高レベルのJavaむベントであるclass_loaded 、 thread_start 、 object_alloc 、これらのポむントを介しおトレヌスできたす。




別のツヌルtplistがありたすが、これは倚少䜿いやすく、自分で䜜成したした。 単玔なリストを䜜成するため、メモを解析する必芁はありたせん。 ここには䜕十ものトレヌスポむントがありたす。ガベヌゞコレクション、モニタヌのピックアップず脱退、JNIむベントスラむドには衚瀺されたせん。




これらのむベントにも匕数がありたす。 時間を節玄するために、この情報がどのように抜出されたかに぀いおは説明したせんが、 tplistには、これらの各芳枬点の匕数を衚瀺できるフラグがありたす。 たずえば、垞識に基づいお、 monitor__waitedむベントには、予想される䜕らかの皮類のモニタヌ情報が含たれおいる可胜性が高いず蚀えたす。ストリヌム識別子がある可胜性がありたす。 ただし、これらの匕数が正確に䜕を意味するかに぀いおは、ここでは盎接蚀及しおいたせん。 ここで、JVMに付属するテキストファむルが圹立぀こずがわかりたす。ここでは、これらのトレヌスポむントに぀いお説明したす。 基本的に、 SystemTapトレヌスファむル。 たずえば、 monitor__waitedむベントにmonitor__waitedいく぀かの匕数monitor__waitedこずがわかりたす。これは、ストリヌム識別子、モニタヌ識別子、予想されるオブゞェクトのクラス名です。 衚瀺甚のトレヌス甚に提瀺できる圢匏オプションも提案されおいたす。


質問は、OpenJDK、Oracle JDK、特定のディストリビュヌションに関するものですか 私の知る限り、すべおのJDKにはこれらのトレヌスポむントがありたすが、仕様がこれを匷制しおいるこずを匷く疑いたす。 たさに圌らが生たれたずき、私は確かに蚀うこずができたせん。 Oracleの蚘事を芚えおいたすが、2008幎に蚘茉されたようです。したがっお、これは新しい珟象ではありたせん。


このレポヌトの埌、確認したしたOracleJDKのLinuxではこれらの監芖ポむントはありたせん 。SolarisおよびおそらくOracle Linuxにありたす。これらのポむントは゜ヌスにありたすが、デフォルトではコンパむルされたせん。しかし、すべおのOpenJDKに存圚したす


最初に、それらの䜿甚方法を瀺したいず思いたす。次に、 BPFずそれらの䜿甚方法に぀いお説明したす。 ここに、軜薄な䟋がありたす。Javaアプリケヌションは、重芁ず思われるメッセヌゞをコン゜ヌルに出力したすが、どこから来たのかはわかりたせん。 さらに、本番環境でこれらのメッセヌゞを送信するコヌドを知りたいです。 おそらくデバッガの助けを借りお、この問題はブレヌクポむントを介しお解決できたすが、それは行いたせん。 PreserveFramePointerフラグが必芁になりたす 。これは、スタックを走査するために倚くのJavaプロファむラヌでも䜿甚されたす。 このフラグはすでにJDK 8u60に存圚しおいたしたが、 perfを䜿甚する次のレポヌトで説明したす。 旗は、スタックを歩くために必芁です。 このフラグには、フレヌムレゞスタCPUレゞスタの1぀が他のレゞスタず同様に通垞の蚈算に䜿甚されおいないこずの確認が含たれたす。 スタック䞊を歩くこずを含め、䞀連の呌び出しを凊理するためにのみ䜿甚する必芁がありたす。


このフラグを䜿甚する掚定コストは、玄3です。 プロセッサの負荷が非垞に高くなく、1秒あたり数癟䞇のメ゜ッドが呌び出されない堎合おそらく0、これは控えめな芋積もりです。 画面に、トレヌスしようずしおいるプログラムの出力が衚瀺されたす。




譊告は十分に深刻に芋えるため、譊告の出所を理解する必芁がありたす。 私が曞いたトレヌスツヌルを䜿甚しおみたしょう。 圌はシステムレベルのむベントをトレヌスし、途䞭でこれらのむベントからJava呌び出しのスタックを受け取りたす。 同時に、Javaアプリケヌションを再起動し、実際にトレヌスを再コンパむルする必芁はありたせん。これは、実皌働環境に起動できる非垞に軜量なツヌルです。 スラむドに沿っおリンクがあり、レポヌトの終わりたでに、これらすべおのツヌルの入手先がわかりたす。




トレヌスは BPFに基づいおいたす。 スラむドには、圌ぞの蚎えがありたす。 たず、泚意特暩ナヌザヌずしおコヌドを実行する必芁がありたす。 埌で説明するように、 BPFでは、これずperfが他の倚くのツヌルず同様に必芁です。 次に、 トレヌスが正確に添付されおいるものを刀別する必芁がありたす。 画面ぞの出力のトレヌスが必芁ですが、この特定のケヌスではシステムレベルで䜜業しおいるので、特に暙準出力を提䟛する特定のシステムコヌルを探したす。 さらに、最初の匕数が1぀でなければならないずいう条件を远加したす。 あなたの意芋では、必芁なシステムコヌルの最初の議論は䜕ですか


そうです、ファむル蚘述子、およびナニットは、出力をstdoutトレヌスするための条件です。 次に、印刷されるメッセヌゞが衚瀺されたす。これはprintfのスタむルです。 䞀方、 arg2は、印刷のプロセスに盎接あるバッファヌですテキストが含たれおいる堎合は、ほずんどの堎合。 その埌に、ナヌザヌ空間の呌び出しスタックを瀺す-Uフラグが続きたす。 最埌に、Javaプロセスのみに関心があるため、Javaプロセスのみを残すフィルタヌを配眮したす。 構文を理解しおいただければ、これがすべお明らかになるこずを願っおいたす。


traceの出力を芋おみたしょう。 圌はほずんど私たちが望んでいたものです。 最初の数行は、プロセスずフロヌの識別子を識別する芋出しです。 次に、私たちに興味のあるメッセヌゞが来たす-「デヌタの受信゚ラヌ、クリア」。 コヌルスタックはほずんど必芁なもので、最初はすべお問題ありたせんが、たずえばjava_io_FileOutputStream前に䜕が起こるかなど、最も興味深い郚分は瀺しおいたせん。 たた、Javaスタックを通過しお、コヌド内のシンボル、関数名、およびメ゜ッドずの通信を構築しようずする倚くのツヌルを䜿甚する堎合、この問題が発生したす。




ここでは、 perfや他の倚くのツヌルず同様に、JITでコンパむルされたコヌドのメモリ内のアドレスずメ゜ッドの実際の名前ずの間の察応を出力する小さな゚ヌゞェントが必芁になりたす。 必芁に応じお、゜ヌス情報にアクセスできるため、゜ヌス情報も印刷できたす。 この堎合、GitHubにあるかなり䞀般的で非垞に単玔な゚ヌゞェントperf-map-agentを䜿甚したす。 出力は/ tmpフォルダヌに送信されたす。これらは、コヌドアドレス、特定のメ゜ッドの衚瀺、およびこのメ゜ッドのサむズを含む非垞に単玔な圢匏のファむルになりたす。 これらのマッピングは、Java呌び出しスタックを解決するために必芁です。 プロファむラヌが最初にJavaスタックフレヌムの操䜜方法を知らない堎合、そのような操䜜は䞍芁です。




゚ヌゞェントを䜿甚した新しい結果であるスラむドでは、スタックは受け入れられるように芋えたす。生成したばかりの.mapファむルから抜出された関数の名前はすべお蚱可されたす。 スラむドでは、アプリケヌションのコヌドの䞀郚DataFetcher :: fetchDataが匷調衚瀺されおおり、コン゜ヌルぞの出力が実行されお邪魔されたした。 ゜ヌスが芋぀かりたしたが、珟圚は状況に応じお、このコヌドで䜕をするかを決定したす。 これは、必芁な機胜の䟋であるように思えたす。単玔で、リ゜ヌスを倧量に消費しない、すぐに䜿甚できるツヌルを䜿甚しお、既に実行䞭のシステムからデヌタを抜出したす。 これは、Javaレベル、システムレベル、カヌネルレベルで発生する可胜性がありたす-問題ではありたせん。


問題の芁旚に入る前に、別の同様の䟋を考えおみたしょう。 倚くのガベヌゞコレクションを匕き起こすJavaアプリケヌション。 ガベヌゞコレクタヌのログから、 System.gc()盎接呌び出すこずがわかっおいるので、正確にどこを理解する必芁がありたす。 アプリケヌションは巚倧で、倚くのラむブラリがあり、どのようなコヌドがこれらの呌び出しを行うかは䞍明です。 ここでは倚くのリ゜ヌスを必芁ずするフラグが必芁になるため、この䟋から始めたせんでした。 これは、 ExtendedDTraceProbesず呌ばれる䞀皮のスヌパヌデバッグモヌドであり、任意のJavaメ゜ッドの入力および出力にトレヌスプログラムを添付できたす。 明らかに、これには私が説明した他の方法よりも倚くのリ゜ヌスが必芁になるため、このフラグは特定の問題を解決する必芁がある堎合にのみ䜿甚しおください。




ガベヌゞコレクタヌログの前に、 System.gc()盎接呌び出しがありたす。 ここでもトレヌスを䜿甚したすが、アタッチメントの目的がわずかに異なるため、わずかに異なる方法で䜿甚したす。




method__entryず呌ばれるJVM内のポむントになりたす。これを䜿甚しお、任意のJavaメ゜ッドをトレヌスできたす。 興味のある特定のメ゜ッドを瀺すために、 arg4 これはメ゜ッドの名前ですがgcず等しいこずを必芁ずする条件に眮き換えたす。 おそらく、クラス名のチェックも远加する必芁がありSystem 。これはSystemでなければなりたせん。 次に、メッセヌゞを出力し、その埌に呌び出しスタックを出力したす。 最埌に、これらはすべおJavaプロセスでのみ行う必芁がありたす。 次に、このアプリケヌションの各System.gc()呌び出しの呌び出しずスタックトレヌスがある出力がありたす。 これは、前回ず同じコヌドであるDataFetcher::fetchData 、 RequestProcessor::processRequestなどの芁求に応じおRequestProcessor::processRequestれたす。


これは正盎なフルスタックであり、JavaフレヌムずJVMからのネむティブフレヌムの䞡方を持ち、Linuxのルヌトスレッドたで、パス党䜓に沿っお私たちを導きたす。 絶察にすべおがここで芋るこずができたす。 そのため、このようなデヌタを取埗するために克服する必芁があるものの䟋を次に瀺したす。


この䜜業の背埌にある動機付けのさらにいく぀かの䟋...䟋から、すでに述べた問題に移りたしょう。perfの䜕が問題なのでしょうか このツヌルは、Linuxの実皌働環境でのJavaアプリケヌションの監芖たたはトレヌスに関するすべおの講挔で蚀及されおいたす。 前述したように、私の次の蚘事は、 perfを䜿甚しおJavaアプリケヌションのCPUサむクルをフェッチする新しい独自の方法に関するレポヌトです。




perfを䜿甚するず、単玔に動䜜したす。最初に蚘録し、次に蚘録を凊理しお、たずえばフレヌムグラフを取埗したす。 おそらく、このperfの䜿甚を認識しおいる人もいたす。 私がお話しする問題は、 BPFず私があなたに䌝えたいず思う考えに関連しおいたす。 その䜜業のために、 perfは埌続の分析のためにファむルを介しおナヌザヌ空間に倧量のデヌタを転送したす。 特定のクラりド䞊に仮想マシンを䜜成し、このマシンに接続しお、玄1 Gbit / sの速床でファむルをダりンロヌドしたした。 自宅ではそのような接続はありたせん。そのため、クラりド䞊の仮想マシンに぀いお話しおいるず蚀ったのです。 その結果、玄9䞇のnetif_receive_skbむベントが発生したした。 システムで受信したデヌタ、トレヌス遅延、パケットサむズをトレヌスするために、 perfでこれを蚘録できたす。 ただし、同時に、1秒あたり9䞇むベントが出力されたす。コヌルスタックを蚘録する堎合、これはファむルに曞き蟌たれる1秒あたり20メガバむトのデヌタです。 明らかに、これは通垞、実皌働環境では行われたせん。たた、ハヌドディスク領域が䞍足するだけなので、このような䜜業を1分以䞊行うこずは明らかに望たしくありたせん。 同時に、これらの20メガバむト/秒のうち、平均パケットサむズ、パケットの受信からJavaアプリケヌションぞの配信たでの平均遅延など、わずか5バむトに関心があるかもしれたせん。 1秒あたり20メガバむトは必芁ありたせんが、これがたさにperfの仕組みです。むベントがファむルに送信され、このファむルを分析するナヌザヌスペヌスプログラムが起動したす。 これがたさに私たちが解決しようずしおいる問題です。 私たちは、凊理を盎接デヌタ収集、トレヌスプログラムに近づけ、自分でファむルを必芁ずしない堎合はファむルを䜜成しないようにしおいたす。




そしお、ここで「Berkley Packet Filter」の略であるBPFを玹介したす。 このツヌルは、90幎代の初めから存圚しおいたした。 レポヌトを歎史の教蚓に倉えたくはありたせん。ここでの基盀が非垞に成熟しおいるこずを瀺すだけです。 BPFは、パケットをフィルタリングし、システムに入るパケットをトレヌスし、それらを通過させるかどうかを決定するために䜜成されたした。 tcpdump 、 Wiresharkたたは同様の远跡ツヌルは、どのIPアドレスから、どの特定のプロトコルでパケットを受信するかを指定するずきに䜿甚したす。 どちらの堎合も、 tcpdumpずWiresharkは、独自の呜什セットを䜿甚しお小さなBPFプログラムを䜜成し、カヌネルに枡したす。次に、着信パケットごずにこのプログラムを実行しお、このパケットを削陀するかトレヌスするかを決定したす。 私たちの目の前のスラむドには、別のアセンブラヌであるこの䞀連の指瀺がありたす。 90幎代、この䞀連の指瀺は非垞に簡単でした。 しかし、過去3〜4幎にわたっお、ネットワヌクの目的だけでなく、パケットのフィルタリングだけでなくBPFを䜿甚できるようにするために、倚くの努力が払われおきたした。 今日、トレヌスはその機胜の䞀郚であり、私の䞻な焊点はそれです。 䞊蚘で瀺したトレヌスツヌルはBPFを䜿甚したす。 ただし、 BPFには他の機胜がありたす。 さらに、Javaず同様に、 BPFにはJITコンパむラヌが远加されたした。 䞊蚘の䞀連の呜什は、カヌネルによっお解釈されなくなり、代わりに、それらをマシンコヌド、プロセッサ呜什にコンパむルしおから実行したす。


以前、 SystemTapには問題があり、動的にコンパむルされたカヌネルモゞュヌルをロヌドするずいうこずを蚀いたした。 これは、 BPFずは異なりたす。 埌者の堎合、呜什のセットはarbitrary意的ではなく、セキュリティの問題を回避するために特別に遞択されたした。 䞍良なBPFプログラムは、カヌネルをドロップたたはサスペンドできたせん。 BPFプログラムはメモリを割り圓おないため、カヌネルでメモリリヌクを匕き起こすこずはできたせん。 これらのプログラムのすべおの機胜は、生産に害を及がさないように厳しく制限されおいたす。


䞻なトピックであるトレヌスに移る前に、いく぀かのシナリオに぀いお簡単に説明したす。 ネットワヌク䌚議で聞くこずができる今日のBPFの最も重芁な甚途の1぀は、 XDPeXpress Data Pathです。 DDoS保護サヌビスを䜜成しおいるず仮定したす Cloudflareは䟋です。 パッケヌゞを凊理したり転送したりするこずなく、できるだけ早くパッケヌゞを削陀する必芁がありたす。 この堎合、パケットがカヌネル、TCPスタック、たたはアプリケヌションに到達する前に、 BPFプログラムが実行され、パケットを削陀するか、他の誰かに転送するか、アプリケヌションの最䞊郚に送信するかが決定されたす。 これは、 BPFを䜿甚しおシステムの動的ルヌルを蚭定する1぀の䟋です。


同じ皮類の別の䟋はseccompです。 珟圚のLinuxでは、 BPFプログラムをむンストヌルしお、特定のアプリケヌションのシステムコヌルをフィルタリングできたす。 アプリケヌションは特定のファむルぞのアクセスを拒吊するこずができたすが、他のファむルぞの呌び出しは蚱可されたす。 ハヌドドラむブからの読み取りを蚱可しながら、ハヌドドラむブぞの曞き蟌みを防ぐこずができたす。 システムずの察話のこのフィルタヌのおかげで、 BPFは䞀皮のサンドボックスを䜜成したす。


䞻に、システム䞊のむベントガベヌゞコレクションなどをトレヌスするためのBPFの䜿甚ず、トレヌスのデモですでに説明したメ゜ッド呌び出しのトレヌスに぀いお説明したす。 システムにはさたざたな接続ポむントがありたす。アプリケヌションレベルでは、これらはガベヌゞコレクション、オブゞェクト割り圓お、Javaアプリケヌションでのクラスロヌドです。 さらに、パケットの受信、システムコヌルのwriteおよびreadなど、倚くのカヌネルレベルの接続ポむントがありたす。 ナヌザヌスペヌスには、カヌネルにBPFプログラムをむンストヌルし、それを関心のあるむベントにアタッチする制埡プログラムがありたす。 これらのむベントが発生するず、カヌネル内のプログラムが実行されたすが、次の2぀のいずれかを実行できたす。 情報をナヌザヌ空間に送信でき、同時に、本質的にトレヌスの手段ずしお機胜したす。 これが私のプログラムの仕組みであり、ナヌザヌ空間のスクリプトを介しお出力を印刷したす。 たたは、プログラムは、集蚈を実行するメモリ内デヌタ構造を曎新できたす。 埌続の分析のためにデヌタをナヌザヌスペヌスに転送する代わりに、カヌネルで盎接集蚈を実行し、平均、高倀、安倀、ヒストグラムなどを取埗できたす。 数癟䞇のむベントの送信に関䞎するこずなく、トレヌサヌが機胜する堎所。 これはたさにBPFの重芁な違いであり、 BPFを非垞に䟡倀のあるものにし、 perfよりも優䜍に立おたす。


プログラムがカヌネルで実行されるず、ナヌザヌスペヌススクリプトはバッファヌたたはデヌタ構造からデヌタを読み取り、必芁な凊理を行いたす。画面にメッセヌゞを衚瀺し、グラフ、ヒストグラムなどを䜜成したす。 perfずは異なり、ファむルは必芁でない限りどこにも䜜成されたせん。
このツヌルが䞀般に受け入れられないのはなぜですか たず第䞀に、それは完党に新しいからです。 パフォヌマンスをトレヌスおよび監芖する BPF゜フトりェアを䜿甚するには、ほんの数幎前の最小バヌゞョン4.1 Linuxカヌネルが必芁です。 Ubuntu 14たたはCentOS 5はサポヌトしおいたせん。 最も有甚なこずのためには、さらに新しいカヌネルが必芁です。 FedoraずUbuntuの䟋を芋おみたしょう。 Ubuntu 16 LTSでは 、 Ubuntu 16.10でBPFの倚くの機胜を䜿甚できたす-ほずんどすべお。 BPFによっお远加された最新の機胜には、ほんの数か月前にリリヌスされた4.9カヌネルバヌゞョンが必芁です。 したがっお、今日は盎接動䜜しないものもあれば、かなり新しいカヌネルを搭茉した特定のシステムでのみ動䜜するものもありたす。 しかし、Linuxトレヌスの未来はBPFにありたす。 これは、Java、Python、およびC ++-Linuxで実行されるすべおの蚀語に適甚されたす。 その理由は、カヌネルでトレヌスプログラムを実行し、埌続の分析のためにすべおのデヌタをナヌザヌ空間に転送する代わりに、察応衚やヒストグラムの曎新などの耇雑なアクションを実行するためです。


叀いメ゜ッドず新しいメ゜ッドを比范したす。 原則ずしお、 perfを䜿甚するず、デヌタがファむルに送信され、このファむルが凊理および分析されたす。 BPF , . . , , .


. , , BPF , . BCC . , .. , , , , - Linux. . .




BCC . — , . - , . , , , , Java, MySQL, Postgres , . , , , , BPF .




, . , , , , , , . , , IO. , TCP TCP. DNS. , . , , — . , Java.


, . , . . , , BPF.




top , 100%. , , . BCC — uthreads . , Java-, . , . , . profile , ( perf ). profile Java, , PU, . , . Java, Java-, — . , perf — , java-, — .




, . , . , . , . , . , , . , , . dd, dnf, Java stress . , , Java. Java , — Prime::isPrime , , . ? , , . isPrime , , , , isPrime . , . , , . — , , , CPU, . , , BPF , , .




. , , : , , ( if(isPrime(i)) ) . , ? ? , Java- , ? BCC, argdist. , . , : monitor__contended__enter() , JVM. Argdist 5 , . , — 3 , 9 . - , 3 9 5 , . , , . , . , , JVM.


CPU, , Java- , , , . Java-, , MySQL. , . , , . , , 50 , .




, dbstat BCC . MySQL PostgreSQL. , , . MySQL ASCII- ( , ). 3000 0 1 , 8 1 2 , . . MySQL. dbstat , , , 5 . , 2 , .




, MySQL. top , 2% , . , BCC dbslower. MySQL , — 500. dbslower , , call getproduct(97) . , ?




, trace , . MySQL query__exec__start , . trace , call getproduct(97)`` sleep(2)`. , , — sleep(2). , , .




, . Java-, . . Java , , mysqlsniff . . BPF Java , , , socket.send() . MySQL. , , . , , . , call getproduct(97) . , hibernate, beans ., JDBC, . — , Product::load , User::loadProducts , Databaseey::main .. , , . , Wireshark , , . , BPF , MySQL , , . , , — .
, . MySQL , Java. Java , BCC , .
, , . , , , .




, , . Java-, . .NET, , , . top, , , BCC ustat . Java, . 800, , , , , , . profile, , . ResponseBuilder::addLine , , .




, BCC Java, Ruby — uobjnew. , ExtendedDTraceProbes . , , , , . 5 , Java. , . uobjnew , , , . , , — stackcount . object__alloc JVM, , . , , . , : _new_array_Java , ResponseBuilder::AddLine . , — JVM, SharedRuntime::dtrace_object_alloc — .
, , . , , , . -, , , .




. , , — « ». , , , , ? opensnoop, . -x . , /etc , — 2, Linux « », . , , . trace. open, «-2». Java. . , , , . , Java.


, . HTTP- . , . , , , , 1.4-2 . 6 — , - . — facebook.com, — i-dont-exist-at-all.com, . . . , , 5 .


, , DNS , . . BCC DNS. DNS . , DNS , . . , ? trace , «-2», « », .




dig — , , , , BCC. DNS i-dont-exist-at-all.com dig : , , , 15 , . . . « » 0, . dig . DNS.




. , DNS-, , 800 - . - . , DNS 0 . , , Java DNS . , , BPF , DNS.
, , : , JVM-; BPF Linux; ; . ご枅聎ありがずうございたした。







広告の分。 おそらくご存知のように、䌚議を行っおいたす。 次はJBreak 2018ずJPoint 2018です。 そこに来お、さたざたなファッショナブルな技術の開発者ずラむブでチャットできたす。たずえば、Azul Systemsの副CTOであるSimon Ritterがいたす。 c " " . ( olegchir ) . 芁するに、私たちはあなたを埅っおいたす。


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


All Articles