很早前就想寫(xiě)一篇關(guān)于 eBPF 的文章,但是遲遲沒(méi)有動(dòng)手,這兩天有點(diǎn)時(shí)間,所以就來(lái)寫(xiě)一篇。這文章主要還是簡(jiǎn)單的介紹 eBPF 是用來(lái)干什么的,并通過(guò)幾個(gè)示例來(lái)介紹是怎么玩的。這個(gè)技術(shù)非常非常之強(qiáng),Linux 操作系統(tǒng)的觀測(cè)性實(shí)在是太強(qiáng)大了,并在 BCC 加持下變得一覽無(wú)余。這個(gè)技術(shù)不是一般的運(yùn)維人員或是系統(tǒng)管理員可以駕馭的,這個(gè)還是要有底層系統(tǒng)知識(shí)并有一定開(kāi)發(fā)能力的技術(shù)人員才能駕馭的了的。我在這篇文章的最后給了個(gè)彩蛋。
介紹
eBPF(extened Berkeley Packet Filter)是一種內(nèi)核技術(shù),它允許開(kāi)發(fā)人員在不修改內(nèi)核代碼的情況下運(yùn)行特定的功能。eBPF 的概念源自于 Berkeley Packet Filter(BPF),后者是由貝爾實(shí)驗(yàn)室開(kāi)發(fā)的一種網(wǎng)絡(luò)過(guò)濾器,可以捕獲和過(guò)濾網(wǎng)絡(luò)數(shù)據(jù)包。
出于對(duì)更好的 Linux 跟蹤工具的需求,eBPF 從 dtrace中汲取靈感,dtrace 是一種主要用于 Solaris 和 BSD 操作系統(tǒng)的動(dòng)態(tài)跟蹤工具。與 dtrace 不同,Linux 無(wú)法全面了解正在運(yùn)行的系統(tǒng),因?yàn)樗鼉H限于系統(tǒng)調(diào)用、庫(kù)調(diào)用和函數(shù)的特定框架。
在 Berkeley Packet Filter(BPF)(一種使用內(nèi)核 VM 編寫(xiě)打包過(guò)濾代碼的工具)的基礎(chǔ)上,一小群工程師開(kāi)始擴(kuò)展 BPF 后端以提供與 dtrace 類(lèi)似的功能集。eBPF 誕生了。2014 年隨 Linux 3.18 首次限量發(fā)布,充分利用 eBPF 至少需要 Linux 4.4 以上版本。
eBPF 比起傳統(tǒng)的 BPF 來(lái)說(shuō),傳統(tǒng)的 BPF 只能用于網(wǎng)絡(luò)過(guò)濾,而 eBPF 則可以用于更多的應(yīng)用場(chǎng)景,包括網(wǎng)絡(luò)監(jiān)控、安全過(guò)濾和性能分析等。另外,eBPF 允許常規(guī)用戶(hù)空間應(yīng)用程序?qū)⒁?Linux 內(nèi)核中執(zhí)行的邏輯打包為字節(jié)碼,當(dāng)某些事件(稱(chēng)為掛鉤)發(fā)生時(shí),內(nèi)核會(huì)調(diào)用 eBPF 程序。此類(lèi)掛鉤的示例包括系統(tǒng)調(diào)用、網(wǎng)絡(luò)事件等。用于編寫(xiě)和調(diào)試 eBPF 程序的最流行的工具鏈稱(chēng)為 BPF 編譯器集合(BCC),它基于 LLVM 和 CLang。
eBPF 有一些類(lèi)似的工具。例如,SystemTap 是一種開(kāi)源工具,可以幫助用戶(hù)收集 Linux 內(nèi)核的運(yùn)行時(shí)數(shù)據(jù)。它通過(guò)動(dòng)態(tài)加載內(nèi)核模塊來(lái)實(shí)現(xiàn)這一功能,類(lèi)似于 eBPF。另外,DTrace 是一種動(dòng)態(tài)跟蹤和分析工具,可以用于收集系統(tǒng)的運(yùn)行時(shí)數(shù)據(jù),類(lèi)似于 eBPF 和 SystemTap。[Ⅰ]
以下是一個(gè)簡(jiǎn)單的比較表格,可以幫助您更好地了解 eBPF、SystemTap 和 DTrace 這三種工具的不同之處:[Ⅰ]
工具 | eBPF | SystemTap | DTrace |
---|---|---|---|
定位 | 內(nèi)核技術(shù),可用于多種應(yīng)用場(chǎng)景 | 內(nèi)核模塊 | 動(dòng)態(tài)跟蹤和分析工具 |
工作原理 | 動(dòng)態(tài)加載和執(zhí)行無(wú)損編譯過(guò)的代碼 | 動(dòng)態(tài)加載內(nèi)核模塊 | 動(dòng)態(tài)插接分析器,通過(guò) probe 獲取數(shù)據(jù)并進(jìn)行分析 |
常見(jiàn)用途 | 網(wǎng)絡(luò)監(jiān)控、安全過(guò)濾、性能分析等 | 系統(tǒng)性能分析、故障診斷等 | 系統(tǒng)性能分析、故障診斷等 |
優(yōu)點(diǎn) | 靈活、安全、可用于多種應(yīng)用場(chǎng)景 | 功能強(qiáng)大、可視化界面 | 功能強(qiáng)大、高性能、支持多種編程語(yǔ)言 |
缺點(diǎn) | 學(xué)習(xí)曲線高,安全性依賴(lài)于編譯器的正確性 | 學(xué)習(xí)曲線高,安全性依賴(lài)于內(nèi)核模塊的正確性 | 配置復(fù)雜,對(duì)系統(tǒng)性能影響較大 |
對(duì)比表格[Ⅰ]
從上表可以看出,eBPF、SystemTap 和 DTrace 都是非常強(qiáng)大的工具,可以用于收集和分析系統(tǒng)的運(yùn)行情況。[Ⅰ]
用途
eBPF 是一種非常靈活和強(qiáng)大的內(nèi)核技術(shù),可以用于多種應(yīng)用場(chǎng)景。下面是 eBPF 的一些常見(jiàn)用途:[Ⅰ]
網(wǎng)絡(luò)監(jiān)控:eBPF 可以用于捕獲網(wǎng)絡(luò)數(shù)據(jù)包,并執(zhí)行特定的邏輯來(lái)分析網(wǎng)絡(luò)流量。例如,可以使用 eBPF 程序來(lái)監(jiān)控網(wǎng)絡(luò)流量,并在發(fā)現(xiàn)異常流量時(shí)進(jìn)行警報(bào)。[Ⅰ]
安全過(guò)濾:eBPF 可以用于對(duì)網(wǎng)絡(luò)數(shù)據(jù)包進(jìn)行安全過(guò)濾。例如,可以使用 eBPF 程序來(lái)阻止惡意流量的傳播,或者在發(fā)現(xiàn)惡意流量時(shí)對(duì)其進(jìn)行攔截。[Ⅰ]
性能分析:eBPF 可以用于對(duì)內(nèi)核的性能進(jìn)行分析。例如,可以使用 eBPF 程序來(lái)收集內(nèi)核的性能指標(biāo),并通過(guò)特定的接口將其可視化。這樣,可以更好地了解內(nèi)核的性能瓶頸,并進(jìn)行優(yōu)化。[Ⅰ]
虛擬化:eBPF 可以用于虛擬化技術(shù)。例如,可以使用 eBPF 程序來(lái)收集虛擬機(jī)的性能指標(biāo),并進(jìn)行負(fù)載均衡。這樣,可以更好地利用虛擬化環(huán)境的資源,提高系統(tǒng)的性能和穩(wěn)定性。[Ⅰ]
總之,eBPF 的常見(jiàn)用途非常廣泛,可以用于網(wǎng)絡(luò)監(jiān)控、安全過(guò)濾、性能分析和虛擬化等多種應(yīng)用場(chǎng)景。[Ⅰ]
基于 Spring Boot + MyBatis Plus + Vue & Element 實(shí)現(xiàn)的后臺(tái)管理系統(tǒng) + 用戶(hù)小程序,支持 RBAC 動(dòng)態(tài)權(quán)限、多租戶(hù)、數(shù)據(jù)權(quán)限、工作流、三方登錄、支付、短信、商城等功能
項(xiàng)目地址:https://github.com/YunaiV/ruoyi-vue-pro
視頻教程:https://doc.iocoder.cn/video/
工作原理
eBPF 的工作原理主要分為三個(gè)步驟:加載、編譯和執(zhí)行。
eBPF 需要在內(nèi)核中運(yùn)行。這通常是由用戶(hù)態(tài)的應(yīng)用程序完成的,它會(huì)通過(guò)系統(tǒng)調(diào)用來(lái)加載 eBPF 程序。在加載過(guò)程中,內(nèi)核會(huì)將 eBPF 程序的代碼復(fù)制到內(nèi)核空間。
eBPF 程序需要經(jīng)過(guò)編譯和執(zhí)行。這通常是由Clang/LLVM的編譯器完成,然后形成字節(jié)碼后,將用戶(hù)態(tài)的字節(jié)碼裝載進(jìn)內(nèi)核,并通過(guò)一個(gè)JIT編譯步驟將程序的通用字節(jié)碼轉(zhuǎn)換為機(jī)器特定指令集,以?xún)?yōu)化程序的執(zhí)行速度。
在內(nèi)核中運(yùn)行時(shí),eBPF 程序通常會(huì)掛載到一個(gè)內(nèi)核鉤子(hook)上,以便在特定的事件發(fā)生時(shí)被執(zhí)行。例如,可以將 eBPF 程序掛載到網(wǎng)絡(luò)協(xié)議棧的某個(gè)位置,以便在收到網(wǎng)絡(luò)數(shù)據(jù)包時(shí)被執(zhí)行。
最后,eBPF 程序還需要經(jīng)過(guò)內(nèi)核安全機(jī)制的檢查。這是為了確保 eBPF 程序不會(huì)破壞內(nèi)核的穩(wěn)定性和安全性。在檢查過(guò)程中,內(nèi)核會(huì)對(duì) eBPF 程序的代碼進(jìn)行分析,以確保它不會(huì)進(jìn)行惡意操作,如系統(tǒng)調(diào)用、內(nèi)存訪問(wèn)等。如果 eBPF 程序通過(guò)了內(nèi)核安全機(jī)制的檢查,它就可以在內(nèi)核中正常運(yùn)行了。在運(yùn)行過(guò)程中,eBPF 程序可以訪問(wèn)內(nèi)核的數(shù)據(jù)結(jié)構(gòu),并通過(guò)內(nèi)核接口與其他組件進(jìn)行交互。例如,eBPF 程序可以捕獲網(wǎng)絡(luò)數(shù)據(jù)包,并通過(guò)內(nèi)核接口將它們轉(zhuǎn)發(fā)給用戶(hù)態(tài)的應(yīng)用程序??傊?,eBPF 的工作原理是通過(guò)動(dòng)態(tài)加載、執(zhí)行和檢查無(wú)損編譯過(guò)的代碼來(lái)實(shí)現(xiàn)的。[Ⅰ]
下圖是其架構(gòu)圖。
圖片來(lái)自:https://www.infoq.com/articles/gentle-linux-ebpf-introduction/
基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 實(shí)現(xiàn)的后臺(tái)管理系統(tǒng) + 用戶(hù)小程序,支持 RBAC 動(dòng)態(tài)權(quán)限、多租戶(hù)、數(shù)據(jù)權(quán)限、工作流、三方登錄、支付、短信、商城等功能
項(xiàng)目地址:https://github.com/YunaiV/yudao-cloud
視頻教程:https://doc.iocoder.cn/video/
示例
eBPF 可以用于對(duì)內(nèi)核的性能進(jìn)行分析。下面是一個(gè)基于 eBPF 的性能分析的 step-by-step 示例:
第一步:準(zhǔn)備工作:首先,需要確保內(nèi)核已經(jīng)支持 eBPF 功能。這通常需要在內(nèi)核配置文件中啟用 eBPF 相關(guān)的選項(xiàng),并重新編譯內(nèi)核。檢查是否支持 eBPF,你可以用這兩個(gè)命令查看 ls /sys/fs/bpf 和 lsmod | grep bpf。
第二步:寫(xiě) eBPF 程序:接下來(lái),需要編寫(xiě) eBPF 程序,用于收集內(nèi)核的性能指標(biāo)。eBPF 程序的語(yǔ)言可以選擇 C 或者 Python,它需要通過(guò)特定的接口訪問(wèn)內(nèi)核的數(shù)據(jù)結(jié)構(gòu),并將收集到的數(shù)據(jù)保存到指定的位置。
下面是一個(gè) Python 示例:
#!/usr/bin/python3 from?bcc?import?BPF from?time?import?sleep #?定義?eBPF?程序 bpf_text?=?""" #include?BPF_HASH(stats,?u32); int?count(struct?pt_regs?*ctx)?{ ????u32?key?=?0; ????u64?*val,?zero=0; ????val?=?stats.lookup_or_init(&key,?&zero); ????(*val)++; ????return?0; } """ #?編譯?eBPF?程序 b?=?BPF(text=bpf_text,?cflags=["-Wno-macro-redefined"]) #?加載?eBPF?程序 b.attach_kprobe(event="tcp_sendmsg",?fn_name="count") name?=?{ ??0:?"tcp_sendmsg" } #?輸出統(tǒng)計(jì)結(jié)果 while?True: ????try: ????????#print("Total?packets:?%d"?%?b["stats"][0].value) ????????for?k,?v?in?b["stats"].items(): ???????????print("{}:?{}".format(name[k.value],?v.value)) ????????sleep(1) ????except?KeyboardInterrupt: ????????exit()
這個(gè) eBPF 程序的功能是統(tǒng)計(jì)網(wǎng)絡(luò)中傳輸?shù)臄?shù)據(jù)包數(shù)量。它通過(guò)定義一個(gè) BPF_HASH 數(shù)據(jù)結(jié)構(gòu)來(lái)保存統(tǒng)計(jì)結(jié)果,并通過(guò)捕獲 tcp_sendmsg 事件來(lái)實(shí)現(xiàn)實(shí)時(shí)統(tǒng)計(jì)。最后,它通過(guò)每秒輸出一次統(tǒng)計(jì)結(jié)果來(lái)展示數(shù)據(jù)。這個(gè) eBPF 程序只是一個(gè)簡(jiǎn)單的示例,實(shí)際應(yīng)用中可能需要進(jìn)行更復(fù)雜的統(tǒng)計(jì)和分析。
第三步:運(yùn)行 eBPF 程序:接下來(lái),需要使用eBPF編譯器將 eBPF 程序編譯成內(nèi)核可執(zhí)行的格式(這個(gè)在上面的Python程序里你可以看到——Python引入了一個(gè)bcc的包,然后用這個(gè)包,把那段 C語(yǔ)言的程序編譯成字節(jié)碼加載在內(nèi)核中并把某個(gè)函數(shù)attach到某個(gè)事件上)。這個(gè)過(guò)程可以使用 BPF Compiler Collection(BCC)工具來(lái)完成。BCC 工具可以通過(guò)命令行的方式將 eBPF 程序編譯成內(nèi)核可執(zhí)行的格式,并將其加載到內(nèi)核中。
下面是運(yùn)行上面的 Python3 程序的步驟:
sudo?apt?install?python3-bpfcc
注:在Python3下請(qǐng)不要使用 pip3 install bcc (參看:https://github.com/iovisor/bcc/issues/2278#issuecomment-825356087)
如果你是 Ubuntu 20.10 以上的版本,最好通過(guò)源碼安裝(否則程序會(huì)有編譯問(wèn)題),參看https://github.com/iovisor/bcc/issues/3993#issuecomment-1228217609:
apt?purge?bpfcc-tools?libbpfcc?python3-bpfcc wget?https://github.com/iovisor/bcc/releases/download/v0.25.0/bcc-src-with-submodule.tar.gz tar?xf?bcc-src-with-submodule.tar.gz cd?bcc/ apt?install?-y?python-is-python3 apt?install?-y?bison?build-essential?cmake?flex?git?libedit-dev???libllvm11?llvm-11-dev?libclang-11-dev?zlib1g-dev?libelf-dev?libfl-dev?python3-distutils apt?install?-y?checkinstall mkdir?build cd?build/ cmake?-DCMAKE_INSTALL_PREFIX=/usr?-DPYTHON_CMD=python3?.. make checkinstall
接下來(lái),需要將上面的 Python 程序保存到本地,例如保存到文件 netstat.py。運(yùn)行程序:最后,可以通過(guò)執(zhí)行以下命令來(lái)運(yùn)行 Python 程序:
$?chmod?+x?./netstat.py $?sudo?./netstat.py tcp_sendmsg:?29 tcp_sendmsg:?216 tcp_sendmsg:?277 tcp_sendmsg:?379 tcp_sendmsg:?419 tcp_sendmsg:?468 tcp_sendmsg:?574 tcp_sendmsg:?645 tcp_sendmsg:?29
程序開(kāi)始運(yùn)行后,會(huì)在控制臺(tái)輸出網(wǎng)絡(luò)數(shù)據(jù)包的統(tǒng)計(jì)信息??梢酝ㄟ^(guò)按 Ctrl+C 組合鍵來(lái)結(jié)束程序的運(yùn)行。
下面我們?cè)倏匆粋€(gè)比較復(fù)雜的示例,這個(gè)示例會(huì)計(jì)算TCP??的發(fā)包時(shí)間(示例參考于 Github 上這個(gè) issue[1] 里的程序):
#!/usr/bin/python3 from?bcc?import?BPF import?time #?定義?eBPF?程序 bpf_text?=?""" #include?#include? #include? #include? struct?packet_t?{ ????u64?ts,?size; ????u32?pid; ????u32?saddr,?daddr; ????u16?sport,?dport; }; BPF_HASH(packets,?u64,?struct?packet_t); int?on_send(struct?pt_regs?*ctx,?struct?sock?*sk,?struct?msghdr?*msg,?size_t?size) { ????u64?id?=?bpf_get_current_pid_tgid(); ????u32?pid?=?id; ????//?記錄數(shù)據(jù)包的時(shí)間戳和信息 ????struct?packet_t?pkt?=?{};?//?結(jié)構(gòu)體一定要初始化,可以使用下面的方法 ??????????????????????????????//__builtin_memset(&pkt,?0,?sizeof(pkt));? ????pkt.ts?=?bpf_ktime_get_ns(); ????pkt.size?=?size; ????pkt.pid?=?pid; ????pkt.saddr?=?sk->__sk_common.skc_rcv_saddr; ????pkt.daddr?=?sk->__sk_common.skc_daddr; ????struct?inet_sock?*sockp?=?(struct?inet_sock?*)sk; ????pkt.sport?=?sockp->inet_sport; ????pkt.dport?=?sk->__sk_common.skc_dport; ????packets.update(&id,?&pkt); ????return?0; } int?on_recv(struct?pt_regs?*ctx,?struct?sock?*sk) { ????u64?id?=?bpf_get_current_pid_tgid(); ????u32?pid?=?id; ????//?獲取數(shù)據(jù)包的時(shí)間戳和編號(hào) ????struct?packet_t?*pkt?=?packets.lookup(&id); ????if?(!pkt)?{ ????????return?0; ????} ????//?計(jì)算傳輸時(shí)間 ????u64?delta?=?bpf_ktime_get_ns()?-?pkt->ts; ????//?統(tǒng)計(jì)結(jié)果 ????bpf_trace_printk("tcp_time:?%llu.%llums,?size:?%llu\n",? ???????delta/1000,?delta%1000%100,?pkt->size); ????//?刪除統(tǒng)計(jì)結(jié)果 ????packets.delete(&id); ????return?0; } """ #?編譯?eBPF?程序 b?=?BPF(text=bpf_text,?cflags=["-Wno-macro-redefined"]) #?注冊(cè)?eBPF?程序 b.attach_kprobe(event="tcp_sendmsg",?fn_name="on_send") b.attach_kprobe(event="tcp_v4_do_rcv",?fn_name="on_recv") #?輸出統(tǒng)計(jì)信息 print("Tracing?TCP?latency...?Hit?Ctrl-C?to?end.") while?True: ????try: ????????(task,?pid,?cpu,?flags,?ts,?msg)?=?b.trace_fields() ????????print("%-18.9f?%-16s?%-6d?%s"?%?(ts,?task,?pid,?msg)) ????except?KeyboardInterrupt: ????????exit()
上面這個(gè)程序通過(guò)捕獲每個(gè)數(shù)據(jù)包的時(shí)間戳來(lái)統(tǒng)計(jì)傳輸時(shí)間。在捕獲 tcp_sendmsg 事件時(shí),記錄數(shù)據(jù)包的發(fā)送時(shí)間;在捕獲 tcp_v4_do_rcv 事件時(shí),記錄數(shù)據(jù)包的接收時(shí)間;最后,通過(guò)比較兩個(gè)時(shí)間戳來(lái)計(jì)算傳輸時(shí)間。
從上面的兩個(gè)程序我們可以看到,eBPF 的一個(gè)編程的基本方法,這樣的在 Python 里向內(nèi)核的某些事件掛載一段 “C語(yǔ)言” 的方式就是 eBPF 的編程方式。
實(shí)話(huà)實(shí)說(shuō),這樣的代碼很不好寫(xiě),而且有很多非常詭異的東西,一般人是很難駕馭的(上面的代碼我也很不是很容易都能寫(xiě)通的,把 Google 都用了個(gè)底兒掉,讀了很多晦澀的文檔……)。好在這樣的代碼已經(jīng)有人寫(xiě)了,我們不必再寫(xiě)了,在 Github 上的 bcc 庫(kù)下的 tools 目錄[2]有很多……
BCC(BPF Compiler Collection)是一套開(kāi)源的工具集,可以在 Linux 系統(tǒng)中使用 BPF(Berkeley Packet Filter)程序進(jìn)行系統(tǒng)級(jí)性能分析和監(jiān)測(cè)。BCC 包含了許多實(shí)用工具,如:
bcc-tools:一個(gè)包含許多常用的 BCC 工具的軟件包。
bpftrace:一個(gè)高級(jí)語(yǔ)言,用于編寫(xiě)和執(zhí)行 BPF 程序。
tcptop:一個(gè)實(shí)時(shí)監(jiān)控和分析 TCP 流量的工具。
execsnoop:一個(gè)用于監(jiān)控進(jìn)程執(zhí)行情況的工具。
filetop:一個(gè)實(shí)時(shí)監(jiān)控和分析文件系統(tǒng)流量的工具。
trace:一個(gè)用于跟蹤和分析函數(shù)調(diào)用的工具。
funccount:一個(gè)用于統(tǒng)計(jì)函數(shù)調(diào)用次數(shù)的工具。
opensnoop:一個(gè)用于監(jiān)控文件打開(kāi)操作的工具。
pidstat:一個(gè)用于監(jiān)控進(jìn)程性能的工具。
profile:一個(gè)用于分析系統(tǒng) CPU 使用情況的工具。
下面這張圖你可能見(jiàn)過(guò)多次了,你可以看看他可以干多少事,內(nèi)核里發(fā)生什么事一覽無(wú)余。
延伸閱讀
一些經(jīng)典的文章和書(shū)籍關(guān)于 eBPF 包括:
Brendan Gregg 的《BPF Performance Tools: Linux System and Application Observability[3]》一書(shū)是一個(gè)全面的指南,涵蓋了 eBPF 的基礎(chǔ)知識(shí)和實(shí)踐應(yīng)用。
eBPF 的官網(wǎng):https://ebpf.io/ 由 Cilium 建立
Cilium’s BPF and XDP Reference Guide:http://docs.cilium.io/en/latest/bpf/
BPF Documentation:https://www.kernel.org/doc/html/latest/bpf/index.html
BPF Design Q&A:https://www.kernel.org/doc/html/latest/bpf/bpf_design_QA.html
還有 Github 上的 Awesome eBPF:https://github.com/zoidbergwill/awesome-ebpf
彩蛋
最后來(lái)到彩蛋環(huán)節(jié)。因?yàn)樽罱?ChatGPT 很火,于是,我想通過(guò) ChatGPT 來(lái)幫助我書(shū)寫(xiě)這篇文章,一開(kāi)始我讓 ChatGPT 幫我列提綱,并根據(jù)提綱生成文章內(nèi)容,并查找相關(guān)的資料,非常之順利,包括生成的代碼,我以為我們以很快地完成這篇文章。
但是,到了代碼生成的時(shí)候,我發(fā)現(xiàn),ChatGPT 生成的代碼的思路和方法都是對(duì)的,但是是比較老的,而且是跑不起來(lái)的,出現(xiàn)了好些低級(jí)錯(cuò)誤,如:使用了未聲明的變量,沒(méi)有引用完整的C語(yǔ)言的頭文件,沒(méi)有正確地初始化變量,錯(cuò)誤地獲取數(shù)據(jù),類(lèi)型沒(méi)有匹配……等等,在程序調(diào)試上,挖了很多的坑,C 語(yǔ)言本來(lái)就不好搞,挖的很多運(yùn)行時(shí)的坑很難察覺(jué)。
所以,耗費(fèi)了我大量的時(shí)間來(lái)排除各種各樣的問(wèn)題,其中有環(huán)境上的問(wèn)題,還有代碼上的問(wèn)題,這些問(wèn)題即便是通過(guò) Google 也不容易找到解決方案,我找到的解決方案都放在文章中了,尤其是第二個(gè)示例,讓我調(diào)試了3個(gè)多小時(shí),讀了很多 bcc 上的 issue 和相關(guān)的晦澀的手冊(cè)和文檔,才讓程序跑通。
到了文章收關(guān)的階段,我讓 ChatGPT 給我?guī)讉€(gè)延伸閱讀,也是很好的,但是沒(méi)有給出鏈接,于是我只得人肉 Google 了一下,然后讓我吃驚的是,好多 ChatGPT 給出來(lái)的文章是根本不存在的,完全是它偽造的。我連讓它干了兩次都是這樣,這個(gè)讓我驚掉大牙。
這讓我開(kāi)始懷疑它之前生成的內(nèi)容,于是,我不得我返回仔細(xì) Review 我的文章,尤其是“介紹”、“用途”和“工作原理”這三個(gè)章節(jié),基本都是 ChatGPT 生成的,在 Review 完后,我發(fā)現(xiàn)了 ChatGPT 給我生造了一個(gè)叫 “無(wú)損編譯器”的術(shù)語(yǔ),這個(gè)術(shù)語(yǔ)簡(jiǎn)直了,于是我開(kāi)始重寫(xiě)我的文章。我把一些段落重寫(xiě)了,有一些沒(méi)有,保留下來(lái)的我都標(biāo)記上了 [Ⅰ],大家讀的時(shí)候要小心閱讀。
最后,我的結(jié)論是,ChatGPT 只是一個(gè)不成熟的玩具,只能回答一些沒(méi)有價(jià)值的日常聊天的問(wèn)題,要說(shuō)能取代 Google,我覺(jué)得不可能,因?yàn)?Google 會(huì)基于基本的事實(shí),而 ChatGPT 會(huì)基于內(nèi)容生成的算法,在造假方面稱(chēng)得上是高手,可以列為電信詐騙的范疇了,我以后不會(huì)再使用 ChatGPT 生成文章內(nèi)容或是作我的幫手了。StackOverflow 把其 ban 了真是不能太贊了!
附件一:ChatGPT的造假載圖和樣本
?
ChatGPT 生成的樣本一
Brendan Gregg 的《BPF Performance Tools: Linux System and Application Observability》一書(shū)是一個(gè)全面的指南,涵蓋了 eBPF 的基礎(chǔ)知識(shí)和實(shí)踐應(yīng)用。
Alexei Starovoitov 在 2015 年的 LPC 大會(huì)上發(fā)表的《eBPF and XDP: fast programmable datapath in the Linux kernel》一文,是一個(gè)介紹 eBPF 和 XDP(eXpress Data Path)的綜述。
谷歌的《BPF: The Future of Linux Monitoring and Observability》一文介紹了 eBPF 的基本概念,并探討了它對(duì)于 Linux 監(jiān)控和可觀察性的影響。
微軟的《A Survey of Techniques for Hardware Acceleration of BPF》一文,介紹了 eBPF 在硬件加速方面的研究現(xiàn)狀。
Daniel Borkmann 的《Linux kernel networking: implementation and theory》一書(shū)涵蓋了 eBPF 的實(shí)現(xiàn)和理論。
Martin KaFai Lau 在 2015 年的 SOSP 大會(huì)上發(fā)表的《eBPF: a new execution environment for the Linux kernel》一文,介紹了 eBPF 在 Linux 內(nèi)核中的新執(zhí)行環(huán)境。
來(lái)自?xún)擅雀韫こ處煹摹秂BPF: A New Frontier in Performance Analysis》一文,探討了 eBPF 對(duì)性能分析的影響。
《BPF Performance Tools: Linux System and Application Observability》一書(shū)中的第三章,討論了 eBPF 的編譯器和運(yùn)行時(shí)系統(tǒng)。
來(lái)自三名谷歌工程師的《eBPF: The New Solaris DTrace》一文,比較了 eBPF 和 Solaris DTrace 系統(tǒng)的區(qū)別。
ChatGPT 生成的樣本二
eBPF 程序開(kāi)發(fā)指南:https://cilium.io/doc/ebpf/ebpf-guide/
eBPF 官方文檔:https://www.kernel.org/doc/Documentation/networking/filter.txt
Linux 內(nèi)核 eBPF 介紹:https://www.ibm.com/developerworks/cn/linux/kernel/ebpf/index.html
eBPF 性能優(yōu)化技巧:https://www.infoq.com/cn/news/2018/08/ebpf-performance-tips/
eBPF 實(shí)戰(zhàn)經(jīng)驗(yàn)分享:https://blog.cloudflare.com/ebpf-in-practice/
eBPF 在網(wǎng)絡(luò)安全中的應(yīng)用:https://www.zdnet.com/article/ebpf-how-to-use-it-for-network-security/
eBPF 實(shí)現(xiàn) Linux 系統(tǒng)性能監(jiān)控:https://www.percona.com/blog/2017/08/15/how-to-use-ebpf-to-monitor-linux-system-performance/
eBPF 入門(mén)教程:https://sysdig.com/?blog/ebpf-getting-started/
eBPF 與 BPF 比較:https://lwn.net/Articles/724647/
eBPF 提高課程:https://www.pluralsight.com/courses/ebpf-advanced
附件二:發(fā)明的術(shù)語(yǔ):無(wú)損編譯器
?
相關(guān)鏈接:
https://github.com/iovisor/bcc/issues/2972
https://github.com/iovisor/bcc/tree/master/tools
https://book.douban.com/subject/34467459
作者介紹
陳皓:網(wǎng)名“左耳朵耗子”。前阿里云資深架構(gòu)師、亞馬遜高級(jí)研發(fā)經(jīng)理,擁有 20 多年互聯(lián)網(wǎng)和金融行業(yè)從業(yè)經(jīng)驗(yàn)。現(xiàn)任 MegaEase 創(chuàng)始人,致力于為企業(yè)提供 Cloud Native 和行業(yè)頭部企業(yè)(亞馬遜/ 阿里)標(biāo)準(zhǔn)的高可用、高性能和高并發(fā)架構(gòu)的技術(shù)產(chǎn)品。
編輯:黃飛
評(píng)論