Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
隨著公司業(yè)務(wù)的不斷擴(kuò)張,用戶流量在不斷提升,研發(fā)體系的規(guī)模和復(fù)雜性也隨之增加。線上服務(wù)的穩(wěn)定性也越來(lái)越重要,服務(wù)性能問(wèn)題,以及容量問(wèn)題也越發(fā)明顯。
因此有必要搭建一個(gè)有效壓測(cè)系統(tǒng),提供安全、高效、真實(shí)的線上全鏈路壓測(cè)服務(wù),為線上服務(wù)保駕護(hù)航。
關(guān)于全鏈路壓測(cè)的建設(shè),業(yè)界已經(jīng)有了非常多文章,但是涉及到具體的技術(shù)實(shí)現(xiàn)方面,卻很少介紹。本文想從全鏈路壓測(cè)系統(tǒng),從設(shè)計(jì)到落地整個(gè)實(shí)踐過(guò)程,來(lái)詳細(xì)介紹下全鏈路壓測(cè)系統(tǒng)是具體是如何設(shè)計(jì),以及如何落地的。希望能從技術(shù)落地實(shí)踐的角度,給同行業(yè)的同學(xué)一些參考和啟發(fā)。
全鏈路壓測(cè)在業(yè)內(nèi)已經(jīng)有了廣泛的實(shí)踐,如阿里的 Amazon、PTS[1][2],美團(tuán)的 Quake[3][4],京東的的 ForceBOT[5],高德的 TestPG[6]等等,都為我們提供豐富的實(shí)踐經(jīng)驗(yàn),和大量?jī)?yōu)秀的技術(shù)方案。我們廣泛吸收了各大互聯(lián)網(wǎng)公司的全鏈路壓測(cè)建設(shè)經(jīng)驗(yàn),并基于字節(jié)跳動(dòng)業(yè)務(wù)需求,設(shè)計(jì)開發(fā)了一個(gè)全鏈路壓測(cè)系統(tǒng) Rhino。
Rhino 平臺(tái)作為公司級(jí)的全鏈路壓測(cè)平臺(tái),它的目標(biāo)是對(duì)全公司所有業(yè)務(wù),提供單服務(wù)、全鏈路,安全可靠、真實(shí)、高效的壓測(cè),來(lái)幫助業(yè)務(wù)高效便捷的完成性能測(cè)試任務(wù),更精確評(píng)估線上服務(wù)性能&容量方面風(fēng)險(xiǎn)。
因此在 Rhino 平臺(tái)設(shè)計(jì)之初,我們就定下以下目標(biāo):
Rhino 是一個(gè)分布式全鏈路壓測(cè)系統(tǒng),可以通過(guò)水平擴(kuò)展,來(lái)實(shí)現(xiàn)模擬海量用戶真實(shí)的業(yè)務(wù)操作場(chǎng)景,對(duì)線上各種業(yè)務(wù)進(jìn)行全方位的性能測(cè)試。它主要分為控制中心(Rhino Master)模塊,壓測(cè)鏈路服務(wù)模塊,監(jiān)控系統(tǒng)模塊,壓測(cè)引擎模塊,如圖。(每一個(gè)模塊都是由多個(gè)微服務(wù)來(lái)完成的。如下圖每個(gè)實(shí)線圖都代表一個(gè)微服務(wù)或多個(gè)微服務(wù))。
壓測(cè)過(guò)程中數(shù)據(jù)構(gòu)造是最重要,也是最為復(fù)雜的環(huán)節(jié)。壓測(cè)數(shù)據(jù)的建模,直接影響了壓測(cè)結(jié)果的準(zhǔn)確性。
為了高效的構(gòu)造特定的 Fake 壓測(cè)數(shù)據(jù),Rhino 壓測(cè)平臺(tái)提供大量數(shù)據(jù)構(gòu)造方式:
在壓測(cè)過(guò)程中,有些壓測(cè)請(qǐng)求需要進(jìn)行登錄,并保持會(huì)話;此外在很多壓測(cè)請(qǐng)求中涉及到用戶賬號(hào)信息 UserID,DeviceID 等數(shù)據(jù)。用戶賬號(hào)的構(gòu)造問(wèn)題,一直是壓測(cè)過(guò)程中非常棘手的問(wèn)題。Rhino 平臺(tái)打通的用戶中心,設(shè)置了壓測(cè)專屬的賬號(hào)服務(wù),完美地解決了壓測(cè)過(guò)程中的登錄態(tài),以及測(cè)試賬號(hào)等問(wèn)題。具體流程和使用界面,如下圖。
壓測(cè)隔離中需要解決的壓測(cè)流量隔離,以及壓測(cè)數(shù)據(jù)的隔離。
壓測(cè)流量隔離,主要是通過(guò)構(gòu)建壓測(cè)環(huán)境來(lái)解決,如線下壓測(cè)環(huán)境,或泳道化/Set 化建設(shè),將壓測(cè)流量與線上流程完全隔離。優(yōu)點(diǎn)是壓測(cè)流量與線上流量完全隔離,不會(huì)影響到線上用戶。缺點(diǎn):機(jī)器資源及維護(hù)成本高,且壓測(cè)結(jié)果需要經(jīng)過(guò)一定的換算,才能得線上容量,結(jié)果準(zhǔn)確性存在一定的問(wèn)題。目前公司內(nèi)壓測(cè)都是在線上集群上完成的,線上泳道化正在建設(shè)中。
壓測(cè)數(shù)據(jù)隔離,主要是通過(guò)對(duì)壓測(cè)流量進(jìn)行染色,讓線上服務(wù)能識(shí)別哪些是壓測(cè)流量,哪些是正常流量,然后對(duì)壓測(cè)流量進(jìn)行特殊處理,以達(dá)到數(shù)據(jù)隔離的目的。目前 Rhino 平臺(tái)整體壓測(cè)隔離框架如圖。
壓測(cè)標(biāo)記就是最常見的壓測(cè)流量染色的方式。
目前公司內(nèi)各個(gè)基礎(chǔ)組件、存儲(chǔ)組件,以及 RPC 框架都已經(jīng)支持了壓測(cè)標(biāo)記的透?jìng)鳌F湓硎菍簻y(cè)標(biāo)記的 KV 值存入 Context 中,然后在所有下游請(qǐng)求中都帶上該 Context,下游服務(wù)可以根據(jù) Context 中壓測(cè)標(biāo)記完成對(duì)壓測(cè)流量的處理。在實(shí)際業(yè)務(wù)中,代碼改造也非常簡(jiǎn)單,只需要透?jìng)?Context 即可。
Golang 服務(wù): 將壓測(cè)標(biāo)記寫入 Context 中。
Python 服務(wù):利用 threading.local()存儲(chǔ)線程 Context。
Java 服務(wù):利用 ThreadLocal 存儲(chǔ)線程 Context。
為了解決線上壓測(cè)安全問(wèn)題,我們還引入了壓測(cè)開關(guān)組件。
線上壓測(cè)中,最復(fù)雜的問(wèn)題就是壓測(cè)鏈路中涉及到寫操作,如何避免污染線上數(shù)據(jù),并且能保證壓測(cè)請(qǐng)求保持和線上相同的請(qǐng)求路徑。業(yè)界有很多解決方案,常見的有影子表,影子庫(kù),以及數(shù)據(jù)偏移,如圖[7]。
Rhino 平臺(tái)針對(duì)不同存儲(chǔ),有不同的解決方案:
在壓測(cè)之前,需要對(duì)服務(wù)進(jìn)行壓測(cè)驗(yàn)證。對(duì)于不滿足壓測(cè)要求(即壓測(cè)數(shù)據(jù)隔離)的服務(wù),需要進(jìn)行壓測(cè)改造。
a. 盡量減少代碼改動(dòng),并給出完整的指導(dǎo)手冊(cè)及代碼示例,減少 RD 的工作量,降低代碼錯(cuò)誤的可能性
b. 提供簡(jiǎn)單便捷的線上線下 HTTP&RPC 的壓測(cè)請(qǐng)求 Debug 工具,方便代碼改動(dòng)的驗(yàn)證
c. 對(duì)于新項(xiàng)目,在項(xiàng)目開始初期,就將壓測(cè)改造加入項(xiàng)目開發(fā)規(guī)范中,減少后期的代碼改動(dòng)
請(qǐng)求調(diào)用鏈,對(duì)于線上壓測(cè)是非常重要的:
Rhino 平臺(tái)通過(guò)公司的流式日志系統(tǒng)來(lái)完成調(diào)用鏈檢索的。一個(gè)服務(wù)在被請(qǐng)求或者請(qǐng)求下游時(shí),都會(huì)透?jìng)饕粋€(gè) LogID。RPC 框架會(huì)打印調(diào)用鏈日志(包括 RPC 日志-調(diào)用者日志,Access 日志-被調(diào)用者日志),所有日志中都會(huì)包含這個(gè) LogID。通過(guò) LogID 將一個(gè)請(qǐng)求所經(jīng)過(guò)的所有服務(wù)日志串起來(lái),就完成調(diào)用鏈檢索。
Rhino 平臺(tái)在公司流式日志系統(tǒng)提供的鏈路梳理功能基礎(chǔ)上,進(jìn)行了進(jìn)一步優(yōu)化,以滿足壓測(cè)需要:
雖然 Rhino 平臺(tái)對(duì)于壓測(cè)有很多的安全保障措施,但是對(duì)于大型壓測(cè),保證信息的通暢流通也是非常重要的。因此在壓測(cè)周知方面,Rhino 平臺(tái)也提供了很多解決方案:
在壓測(cè)之前,需要開啟整體鏈路的壓測(cè)開關(guān)的,否則壓測(cè)流量就會(huì)被服務(wù)拒絕,導(dǎo)致壓測(cè)失敗。
對(duì)于調(diào)用鏈中不能壓測(cè)的服務(wù)(敏感服務(wù)),或者第三方服務(wù),為了壓測(cè)請(qǐng)求的完整性,就需要對(duì)這些服務(wù)進(jìn)行 Mock。業(yè)界通用的 Mock 方案有:
由于字節(jié)整個(gè)公司都采用微服務(wù)架構(gòu),導(dǎo)致一次壓測(cè)涉及鏈路都比較長(zhǎng),快速無(wú)業(yè)務(wù)入侵的 Mock
方式成為了首選。Rhino 平臺(tái)是通過(guò)公司 Service Mesh 和 ByteMock 系統(tǒng)來(lái)實(shí)現(xiàn)了高效的,對(duì)業(yè)務(wù)透明的服務(wù) Mock。
壓測(cè)執(zhí)行前,Rhino 平臺(tái)需要向 Service Mesh 注冊(cè)染色轉(zhuǎn)發(fā)規(guī)則,并向 Mock 服務(wù)注冊(cè) Mock 規(guī)則。然后在壓測(cè)流量中注入 Mock 染色標(biāo)記,才能完成服務(wù) Mock:
Rhino 平臺(tái)中,壓測(cè) Agent 就是一個(gè)最小調(diào)度單元。一次壓測(cè)任務(wù),通常會(huì)拆分成多個(gè)子 Job,然后下發(fā)到多個(gè) Agent 上來(lái)完成。
2020 年春節(jié)搶紅包壓測(cè)中,Rhino 臨時(shí)擴(kuò)容在 4000+個(gè)實(shí)例,支撐了單次 3kw+QPS 的壓測(cè),但日常 Rhino 平臺(tái)只部署了 100+個(gè)實(shí)例,就能滿足日常壓測(cè)需求。
Rhino 平臺(tái)默認(rèn)將全鏈路壓測(cè)分為公網(wǎng)壓測(cè)和內(nèi)網(wǎng)壓測(cè)。公網(wǎng)壓測(cè)主要 IDC 網(wǎng)絡(luò)帶寬,延時(shí),IDC 網(wǎng)關(guān)新建連接、轉(zhuǎn)發(fā)等能力;內(nèi)網(wǎng)壓測(cè),主要是壓測(cè)目標(biāo)服務(wù),目標(biāo)集群的 性能,容量等。
Rhino 平臺(tái)在各個(gè) IDC 都有部署 Agent 集群。各個(gè) IDC 內(nèi)服務(wù)的壓測(cè),默認(rèn)會(huì)就近選擇壓測(cè) Agent,來(lái)減少網(wǎng)絡(luò)延時(shí)對(duì)壓測(cè)結(jié)果的干擾,使得壓測(cè)結(jié)果更精準(zhǔn),壓測(cè)問(wèn)題定位更簡(jiǎn)單。
除了多機(jī)房部署之外,Rhino 平臺(tái)還在邊緣計(jì)算節(jié)點(diǎn)上也部署了壓測(cè) Agent,來(lái)模擬各種不同地域不同運(yùn)營(yíng)商的流量請(qǐng)求,確保流量來(lái)源,流量分布更貼近真實(shí)情況。在 Rhino 平臺(tái)上可以選擇不同地域不同運(yùn)營(yíng)商,從全國(guó)各個(gè)地區(qū)發(fā)起壓測(cè)流量。
為了應(yīng)對(duì)線上壓測(cè)風(fēng)險(xiǎn),Rhino 平臺(tái)提供兩種熔斷方式,來(lái)應(yīng)對(duì)壓測(cè)過(guò)程中的突發(fā)事件,來(lái)降低對(duì)線上服務(wù)造成的影響。
每個(gè)壓測(cè)任務(wù),都可以關(guān)聯(lián)調(diào)用鏈中任意服務(wù)的告警規(guī)則。在壓測(cè)任務(wù)執(zhí)行過(guò)程,Rhino 平臺(tái)會(huì)主動(dòng)監(jiān)聽告警服務(wù)。 當(dāng)調(diào)用鏈中有服務(wù)出現(xiàn)了告警,會(huì)立即停止壓測(cè)。對(duì)于沒(méi)有關(guān)聯(lián)的告警,Rhino 平臺(tái)也會(huì)記錄下來(lái),便于壓測(cè)問(wèn)題定位。
自定義監(jiān)控指標(biāo)及閾值,到達(dá)閾值后,也會(huì)自動(dòng)停止壓測(cè)。目前支持 CPU、Memory、 上游穩(wěn)定性、錯(cuò)誤日志,以及其他自定義指標(biāo)。
此外,除了 Rhino 平臺(tái)自身提供的熔斷機(jī)制以外,公司服務(wù)治理架構(gòu)也提供了很多額外的熔斷機(jī)制,如壓測(cè)開關(guān),一鍵切斷壓測(cè)流量;過(guò)載保護(hù),服務(wù)過(guò)載時(shí)自動(dòng)丟棄壓測(cè)流量。
對(duì)于 HTTP 協(xié)議,參考了 Postman,全部可視化操作,保證所有人都能上手操作,極大降低了壓測(cè)的使用門檻和成本。
對(duì)于 RPC 任務(wù),Rhino 也自動(dòng)完成了對(duì) IDL 的解析,然后轉(zhuǎn)換成 JSON 格式,便于用戶參數(shù)化處理。
對(duì)于非 HTTP/RPC 的協(xié)議,以及有復(fù)雜邏輯的壓測(cè)任務(wù),Rhino 平臺(tái)也提供了完善的解決方案——Go Plugin。
Go Plugin 提供了一種方式,通過(guò)在主程序和共享庫(kù)直接定義一系列的約定或者接口,就可以動(dòng)態(tài)加載其他人編譯的 Go 語(yǔ)言共享對(duì)象,使得主程序可以在編譯后動(dòng)態(tài)加載共享庫(kù),實(shí)現(xiàn)熱插拔的插件系統(tǒng)。此外主程序和共享庫(kù)的開發(fā)者不需要共享代碼,只要雙方的約定不變,修改共享庫(kù)后也不再需要重新編譯主程序。
用戶只要根據(jù)規(guī)范要求,實(shí)現(xiàn)一段發(fā)壓業(yè)務(wù)邏輯代碼即可。Rhino 平臺(tái)可以自動(dòng)拉取代碼,觸發(fā)編譯。并將編譯后的插件 SO 文件分發(fā)到多個(gè)壓測(cè) Agent。 Agent 動(dòng)態(tài)加載 SO 文件,并發(fā)運(yùn)行起來(lái),就可以達(dá)到壓測(cè)的目的。此外,Rhino 還針對(duì)常見 Go Plugin 壓測(cè)場(chǎng)景,建立了壓測(cè)代碼示例代碼庫(kù)。對(duì)于壓測(cè)新手,簡(jiǎn)單修改下業(yè)務(wù)邏輯代碼,就可以完成壓測(cè)了。這樣就解決了非常見協(xié)議,以及復(fù)雜壓測(cè)場(chǎng)景等的壓測(cè)問(wèn)題。
壓測(cè)調(diào)度的最小單元是壓測(cè) Agent,但是實(shí)際每個(gè) Agent 中有掛載多種壓測(cè)引擎的,來(lái)支撐不同的壓測(cè)場(chǎng)景。Rhino 平臺(tái)在壓測(cè)數(shù)據(jù)和壓測(cè)引擎之間增加了一個(gè)壓測(cè)引擎適配層,實(shí)現(xiàn)了壓測(cè)數(shù)據(jù)與壓測(cè)引擎的解耦。壓測(cè)引擎適配層,會(huì)根據(jù)選擇不同的壓測(cè)引擎,生成不同 Schema 的壓測(cè)數(shù)據(jù),啟用不同的引擎來(lái)完成壓測(cè),而這些對(duì)用戶是透明的。
在壓測(cè)引擎上,我們有開源的壓測(cè)引擎,也有自研的壓測(cè)引擎。
開源壓測(cè)引擎的優(yōu)點(diǎn)是維護(hù)人多,功能比較豐富,穩(wěn)定且性能好,缺點(diǎn)就是輸入格式固定,定制難度大。此外 Agent 與開源壓測(cè)引擎之間通常是不同進(jìn)程,進(jìn)程通信也存在比較大的問(wèn)題,不容易控制。
自研壓測(cè)引擎,優(yōu)點(diǎn)是和 Agent 通常運(yùn)行在單進(jìn)程內(nèi),比較容易控制;缺點(diǎn)可能就是性能稍微差一些。但是 Golang 天然支持高并發(fā),因此自研和開源之間的性能差距并不明顯。
由于公司監(jiān)控系統(tǒng),最小時(shí)間粒度是 30s,30s 內(nèi)的數(shù)據(jù)會(huì)聚合成一個(gè)點(diǎn)。這個(gè)時(shí)間粒度對(duì)于壓測(cè)來(lái)說(shuō)是比較難以接受的。因此,Rhino 平臺(tái)自己搭建了一套客戶端監(jiān)控系統(tǒng)。
服務(wù)端監(jiān)控,直接接入了公司 Metric 系統(tǒng)。
在壓測(cè)過(guò)程中,Rhino 平臺(tái)還可以實(shí)時(shí)采集目標(biāo)服務(wù)進(jìn)程的性能 Profile,并通過(guò)火焰圖的方式展示出來(lái),方便用戶進(jìn)行性能問(wèn)題分析和優(yōu)化,如圖。
Rhino 壓測(cè)平臺(tái)是一個(gè)面向全字節(jié)跳動(dòng)公司的,為了所有研發(fā)同學(xué)提供的一站式全鏈路壓測(cè)的平臺(tái)。Rhino 平臺(tái)的研發(fā)團(tuán)隊(duì),不僅負(fù)責(zé) Rhino 平臺(tái)的研發(fā)任務(wù),還會(huì)配合 QA&RD 來(lái)完成公司大型項(xiàng)目,重點(diǎn)業(yè)務(wù)的性能壓測(cè)工作。
公司內(nèi)重大項(xiàng)目的壓測(cè),Rhino 平臺(tái)都會(huì)積極參與,全力支撐的。其中,比較典型的項(xiàng)目有抖音春晚,西瓜百萬(wàn)英雄,春節(jié)紅包雨等活動(dòng)。
其中字節(jié)春節(jié)紅包雨活動(dòng),完成是由 Rhino 團(tuán)隊(duì)來(lái)負(fù)責(zé)和完成的。字節(jié)春節(jié)紅包雨活動(dòng)是在春節(jié)期間,所有字節(jié)客戶端發(fā)起的,諸如抽卡分現(xiàn)金,紅包錦鯉,紅包雨等一系列的超大規(guī)模的紅包引流活動(dòng)。其流量規(guī)模巨大,流量突發(fā)性強(qiáng),業(yè)務(wù)邏輯和網(wǎng)絡(luò)架構(gòu)復(fù)雜度高等等,都對(duì) Rhino 平臺(tái)提出不小的挑戰(zhàn)。
在春節(jié)紅包雨活動(dòng)中,所有用戶流量都經(jīng)過(guò)運(yùn)營(yíng)商專線接入到網(wǎng)絡(luò)邊緣的匯聚機(jī)房,然后經(jīng)過(guò)過(guò)濾和驗(yàn)證后,再轉(zhuǎn)發(fā)到核心機(jī)房。其中各個(gè) IDC 互為備份,其具體流量路線如圖。在這里,不僅要驗(yàn)證后端各服務(wù)是否能承載預(yù)期流程,還要驗(yàn)證各個(gè)專線帶寬,各個(gè)網(wǎng)關(guān)帶寬及轉(zhuǎn)發(fā)能力,各 IDC 承載能力以及之間帶寬等等。
為此,我們將整個(gè)壓測(cè)拆分成多個(gè)階段,來(lái)簡(jiǎn)化壓測(cè)復(fù)雜性,也降低壓測(cè)問(wèn)題定位的難度:
在這些大型項(xiàng)目的支撐中,Rhino 團(tuán)隊(duì)不僅學(xué)到了大量的業(yè)務(wù)和架構(gòu)設(shè)計(jì)知識(shí),還了解到業(yè)務(wù)研發(fā)同學(xué)如何看待壓測(cè),如何使用平臺(tái),幫助我們發(fā)現(xiàn)更多平臺(tái)的問(wèn)題,促進(jìn)平臺(tái)不斷迭代優(yōu)化。
日常壓測(cè)支撐,也是 Rhino 平臺(tái)非常重要的一項(xiàng)任務(wù)。對(duì)于日常壓測(cè)中遇到的各種問(wèn)題,我們采用了各種方案來(lái)解決:
Rhino 平臺(tái)還實(shí)現(xiàn)了線上流量的定期調(diào)度,以達(dá)到線上實(shí)例自動(dòng)壓測(cè)的目的[8]:
其具體實(shí)現(xiàn)方案如下:
目前已經(jīng)有 500+微服務(wù)接入,每天定時(shí)執(zhí)行流量調(diào)度,來(lái)監(jiān)控線上服務(wù)性能變化趨勢(shì),如下圖。
Rhino 平臺(tái)目前還在公司內(nèi)推行常態(tài)化壓測(cè),通過(guò)周期定時(shí)化的自動(dòng)化全鏈路壓測(cè),來(lái)實(shí)現(xiàn)以下目標(biāo):
目前 Rhino 平臺(tái)上的常態(tài)化壓測(cè),會(huì)周期定時(shí),以無(wú)人值守的方式,自動(dòng)執(zhí)行壓測(cè)任務(wù),并推送壓測(cè)結(jié)果。在壓測(cè)執(zhí)行過(guò)程中,會(huì)根據(jù)調(diào)用鏈自動(dòng)完成壓測(cè)開關(guān)開啟,發(fā)起壓測(cè)流量。實(shí)時(shí)監(jiān)控服務(wù)性能指標(biāo),并根據(jù) Metric 及告警監(jiān)控,自動(dòng)完成壓測(cè)熔斷,以保證壓測(cè)安全。
目前已經(jīng)有多個(gè)業(yè)務(wù)方接入常態(tài)化壓測(cè),以此保證線上服務(wù)的穩(wěn)定性。
服務(wù)在上線時(shí),都會(huì)經(jīng)過(guò)預(yù)發(fā)布,線上小流量灰度,線上全量發(fā)布。在這個(gè)過(guò)程中,我們可以通過(guò)線上測(cè)試 Case 以及灰度發(fā)布,來(lái)攔截服務(wù)線上功能缺陷。但是對(duì)于性能缺陷的攔截,卻不夠有效。
從線上故障跟蹤系統(tǒng)里就可以發(fā)現(xiàn),由于上線前沒(méi)有做好性能壓測(cè),很多性能缺陷都逃逸到了線上。
為了攔截各種性能缺陷,Rhino 平臺(tái)完成了 DevOps 平臺(tái)的打通。將壓測(cè)服務(wù)在 DevOps 平臺(tái)上注冊(cè)成一個(gè)原子服務(wù) ,研發(fā)人員可以將壓測(cè)節(jié)點(diǎn)編排在任意流水線的任意位置,實(shí)現(xiàn)上線前的例行壓測(cè)。DevOps 流水線中的壓測(cè),不僅可以幫助 RD 發(fā)現(xiàn)代碼中的性能問(wèn)題,還能與性能基線進(jìn)行 Diff,來(lái)發(fā)現(xiàn)代碼性能變壞的味道。
Rhino 壓測(cè)平臺(tái)從立項(xiàng)到現(xiàn)在,不到兩年的時(shí)間內(nèi),其發(fā)展已經(jīng)初具規(guī)模,如圖(每月壓測(cè)執(zhí)行統(tǒng)計(jì))。這個(gè)期間,非常非常感謝公司內(nèi)所有合作團(tuán)隊(duì),尤其是架構(gòu)團(tuán)隊(duì),中臺(tái)團(tuán)隊(duì)對(duì)壓測(cè)平臺(tái)的支撐,沒(méi)有他們的支撐,全鏈路壓測(cè)建設(shè)是難以完成的。
通用壓測(cè)平臺(tái)已經(jīng)初步搭建完成,基本上能滿足業(yè)務(wù)線日常壓測(cè)需求。但在日常壓測(cè)支撐過(guò)程中,發(fā)現(xiàn)不同業(yè)務(wù)線在壓測(cè)時(shí),但是仍然有大量的前置和后繼工作需要人工來(lái)完成。
如何更進(jìn)一步降低業(yè)務(wù)方壓測(cè)改造的成本,如何減少壓測(cè)環(huán)境數(shù)據(jù)預(yù)置成本,如何快速完成壓測(cè)數(shù)據(jù)清理,如何快速定位出性能問(wèn)題等等,Rhino 壓測(cè)平臺(tái)后續(xù)將更進(jìn)一步深入業(yè)務(wù),與各大業(yè)務(wù)方開展更深入的合作,提供更深度的業(yè)務(wù)定制,為研發(fā)提效,助力業(yè)務(wù)線發(fā)展。
業(yè)務(wù)目前資源是否充足,其具體容量是多少;按照目前業(yè)務(wù)增長(zhǎng),其機(jī)器資源還能支撐多久?
目前服務(wù)資源利用如何,是否可以優(yōu)化,如何更進(jìn)一步提升資源利用率,降低機(jī)器資源成本?
某大型活動(dòng),需要申請(qǐng)多少資源?是否不需要壓測(cè),或者自動(dòng)化利用線上流量數(shù)據(jù),或者利用日常壓測(cè)數(shù)據(jù),就可以給出上述問(wèn)題的結(jié)論?
如何保證服務(wù)穩(wěn)定性,如何監(jiān)控服務(wù)性能劣化并及時(shí)預(yù)警,限流、超時(shí)、重試以及熔斷等服務(wù)治理措施配置是否合理?以及如何配合混沌測(cè)試進(jìn)行容災(zāi)演練,保證服務(wù)穩(wěn)定性等等,這些 Rhino 平臺(tái)都會(huì)做更進(jìn)一步探索。
目前 Rhino 團(tuán)隊(duì)還非常小,非常缺少性能測(cè)試以及后端開發(fā)相關(guān)的研發(fā)工程師,歡迎感興趣的同學(xué)來(lái)加入。簡(jiǎn)歷投遞郵箱: tech@bytedance.com ;郵件標(biāo)題: 姓名 - 工作年限 - Rhino 。
[1] http://jm.taobao.org/2017/03/30/20170330/
[2] https://testerhome.com/topics/19493
[3] https://tech.meituan.com/2018/09/27/quake-introduction.html
[4] https://tech.meituan.com/2019/02/14/full-link-pressure-test-automation.html
[5] https://www.open-open.com/lib/view/open1484317425690.html
[6] https://www.infoq.cn/article/NvfJekpvU154pwlsCTLW
[7] https://tech.bytedance.net/articles/3199
[8] https://www.usenix.org/conference/osdi16/technical-sessions/presentation/veeraraghavan
Fastbot:行進(jìn)中的智能 Monkey
品質(zhì)優(yōu)化 - 圖文詳情頁(yè)秒開實(shí)踐
Android Camera 內(nèi)存問(wèn)題剖析
字節(jié)跳動(dòng)自研線上引流回放系統(tǒng)的架構(gòu)演進(jìn)
歡迎關(guān)注「字節(jié)跳動(dòng)技術(shù)團(tuán)隊(duì)」
得不佩服,美觀小巧的網(wǎng)頁(yè)內(nèi)容編輯器——ContentTools
愛(ài)分享Coder
2019-12-03 · 軟件開發(fā)工程師 優(yōu)質(zhì)科技領(lǐng)域創(chuàng)作者
ContentTools是一個(gè)美觀小巧的網(wǎng)頁(yè)內(nèi)容工具(一個(gè)JS庫(kù)),具備所見即所得(WYSIWYG)的編輯器功能,只需幾個(gè)簡(jiǎn)單的步驟,即可將ContentTools添加到任何HTML頁(yè)面。如下圖所示頁(yè)面通過(guò)實(shí)時(shí)ContentTool的彈出層實(shí)現(xiàn)實(shí)時(shí)編輯功能。用小而美來(lái)形容它最好不過(guò)了!
https://github.com/GetmeUK
ContentTools是用于HTML頁(yè)面的美觀小巧的內(nèi)容編輯器。它被設(shè)計(jì)為:
ContentTools具有字體加粗、斜體、超鏈接、對(duì)齊、列表、表格、圖片、視頻、代碼、撤銷、重做、刪除等功能
1、加粗顯示
2、斜體顯示
3、超鏈接
4、H標(biāo)題
5、正文
6、有序和無(wú)序列表
7、插入表格
8、插入圖片
9、視頻
以上截圖中的功能還不完整,如果想體驗(yàn)以下完整的功能可以直接去DEMO頁(yè)面體驗(yàn),如果需要在HTML級(jí)別上更改元素的內(nèi)容,那也是可以的。通過(guò)屬性對(duì)話框中的最后一個(gè)選項(xiàng)卡,可以查看所選元素的內(nèi)部HTML代碼并直接對(duì)其進(jìn)行更新。
下載倉(cāng)庫(kù)并打開/ build文件夾,包括預(yù)構(gòu)建的源文件。將文件夾的內(nèi)容復(fù)制到項(xiàng)目的適當(dāng)位置(例如,content-tools.min.js>
/www/scripts/content-tools.min.js)。但是,/ images文件夾和icons.woff字體需要復(fù)制到與content-tools.min.css相同的文件夾中,文件結(jié)構(gòu)應(yīng)類似于:
<head>
<title>My page</title>
<link rel="stylesheet" type="text/css" href="assets/content-tools.min.css">
...
</head>
<body>
...
<script src="assets/content-tools.min.js"></script>
<script src="assets/editor.js"></script>
</body>
包括一個(gè)名為editor.js的附加JS文件。包含初始化我們的編輯器的代碼,繼續(xù)
<div data-editable data-name="main-content">
<blockquote>
Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live.
</blockquote>
<p>John F. Woods</p>
</div>
data-name屬性用于在保存時(shí)標(biāo)識(shí)區(qū)域(默認(rèn)情況下使用id屬性),標(biāo)記可編輯HTML時(shí),常見的誤解是將單個(gè)元素標(biāo)記為可編輯,例如:
<h1 data-editable data-name="heading">Content</h1>
正確的使用方式如下,也就是說(shuō)必須要在特定的容器元素內(nèi)
<div data-editable data-name=heading>
<h1>Content</h1>
</div>
ContentTools使用CSS類來(lái)對(duì)齊文本,圖像,視頻和iframe,需要在自己的CSS中為這些對(duì)齊類定義樣式,例如:
[data-editable] iframe,
[data-editable] image,
[data-editable] [data-ce-tag=img],
[data-editable] img,
[data-editable] video {
clear: both;
display: block;
margin-left: auto;
margin-right: auto;
max-width: 100%;
}
/* 左對(duì)齊 */
[data-editable] .align-left {
clear: initial;
float: left;
margin-right: 0.5em;
}
/* 右對(duì)齊 */
[data-editable].align-right {
clear: initial;
float: right;
margin-left: 0.5em;
}
/* 可編輯區(qū)域中文本的對(duì)齊樣式 */
[data-editable] .text-center {
text-align: center;
}
[data-editable] .text-left {
text-align: left;
}
[data-editable] .text-right {
text-align: right;
}
ContentTools提供了一個(gè)編輯器,但是在初始化它之前,我們需要配置一些東西,即:
將以下代碼添加到我們之前創(chuàng)建的editor.js文件中:
window.addEventListener('load', function() {
var editor;
});
就像文字處理程序一樣,可以為內(nèi)容配置一系列預(yù)定義樣式。當(dāng)用戶從視口底部的檢查器欄中選擇標(biāo)簽時(shí),這些標(biāo)簽就會(huì)出現(xiàn)。盡管可以將樣式設(shè)置為適用于所有標(biāo)簽,但是僅顯示適用于標(biāo)簽類型的樣式。
我們將添加可應(yīng)用于段落<p>標(biāo)記的單一樣式.author。在var編輯器下方聲明添加:
ContentTools.StylePalette.add([
new ContentTools.Style('Author', 'author', ['p'])
]);
StylePalette.add方法使我們可以向編輯器添加樣式列表。每種樣式均聲明為一個(gè)Style實(shí)例,該實(shí)例使用顯示名稱,CSS類和可以應(yīng)用該樣式的標(biāo)簽列表初始化。我們需要添加相關(guān)的CSS來(lái)支持這種樣式,因此在HTML的開頭添加:
<head>
...
<style>
.author {
font-style: italic;
font-weight: bold;
}
</style>
</head>
接下來(lái),我們需要初始化編輯器,并讓它知道頁(yè)面上的哪些元素是可編輯的。為此,將以下代碼添加到editor.js中:
editor=ContentTools.EditorApp.get();
editor.init('*[data-editable]', 'data-name');
我們使用用于頁(yè)面可編輯區(qū)域的CSS選擇器和屬性名稱(“數(shù)據(jù)名稱”)來(lái)初始化編輯器,以告知編輯器元素的哪個(gè)屬性包含其區(qū)域名稱。區(qū)域名稱在同一頁(yè)面中必須唯一。
最后,我們希望在用戶保存頁(yè)面時(shí)得到通知,以便我們可以將每個(gè)區(qū)域的更新內(nèi)容存儲(chǔ)在文件或數(shù)據(jù)庫(kù)中。為此,我們監(jiān)聽由編輯器觸發(fā)的保存事件。在editor.init語(yǔ)句之后,將以下代碼添加到editor.js中:
editor.addEventListener('saved', function (ev) {
var name, payload, regions, xhr;
// 檢查是否已更改
regions=ev.detail().regions;
if (Object.keys(regions).length==0) {
return;
}
// 保存更改時(shí)將編輯器設(shè)置為忙
this.busy(true);
// 將每個(gè)區(qū)域的內(nèi)容收集到一個(gè)FormData實(shí)例中
payload=new FormData();
for (name in regions) {
if (regions.hasOwnProperty(name)) {
payload.append(name, regions[name]);
}
}
// 將更新內(nèi)容發(fā)送到要保存的服務(wù)器
function onStateChange(ev) {
// 檢查請(qǐng)求是否完成
if (ev.target.readyState==4) {
editor.busy(false);
if (ev.target.status=='200') {
// 保存成功,通知前臺(tái)
new ContentTools.FlashUI('保存成功');
} else {
// 保存失敗,通知前臺(tái)
new ContentTools.FlashUI('保存失敗');
}
}
};
xhr=new XMLHttpRequest();
xhr.addEventListener('readystatechange', onStateChange);
xhr.open('POST', '/save-my-page');
xhr.send(payload);
});
當(dāng)用戶保存頁(yè)面時(shí),我們可以使用AJAX將每個(gè)區(qū)域的內(nèi)容發(fā)送到服務(wù)器進(jìn)行保存。在瀏覽器中打開頁(yè)面,尋找左上方的藍(lán)色編輯按鈕,然后單擊它以開始編輯。
這樣一個(gè)美觀且強(qiáng)大的即時(shí)編輯器可謂是非常的實(shí)用,特別是對(duì)于一些內(nèi)容編輯網(wǎng)站,如CMS、靜態(tài)文檔網(wǎng)站、博客等內(nèi)容型網(wǎng)站尤其有用,希望對(duì)你有所幫助,Enjoy it!
1.5萬(wàn)閱讀
搜索
專門制作文字特效軟件
網(wǎng)站制作微信小程序
html5編輯軟件排行榜
傻瓜式網(wǎng)頁(yè)制作軟件
網(wǎng)站制作軟件免費(fèi)版
一鍵網(wǎng)站制作app
實(shí)現(xiàn)css兩端對(duì)齊,我在網(wǎng)上找了很多方法,都不怎么實(shí)用,都是兼容性鬧得,column是css3的屬性,是多列布局,使用column來(lái)實(shí)現(xiàn)兩端對(duì)齊簡(jiǎn)單實(shí)用,就要設(shè)置下模塊的個(gè)數(shù)跟column的列數(shù)一致就行,先看它的的3個(gè)屬性:
1.column-count 屬性規(guī)定元素應(yīng)該被分隔的列數(shù)
2.column-gap 屬性規(guī)定列之間的間隔
2.column-rule 屬性設(shè)置列之間的寬度、樣式和顏色規(guī)則。
CSS3 多列屬性的兼容性:Internet Explorer 10 和 Opera 支持多列屬性,F(xiàn)irefox 需要前綴 -moz-,Chrome 和 Safari 需要前綴 -webkit-,特別注意:Internet Explorer 9 以及更早的版本不支持多列屬性。
實(shí)現(xiàn)css兩端對(duì)齊的例子:用column-count定義對(duì)象的列數(shù),例子中有4個(gè)p(即4個(gè)模塊),那么就定義為4列,再用column-gap定義了對(duì)象中列與列的間距,間距不能設(shè)置為百分比,但是只能用px,具體的看下面的代碼:
<!Doctype html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gbk2312"/>
<title>實(shí)現(xiàn)css兩端對(duì)齊</title>
<style type="text/css">
*{margin:0;padding:0;}
.box{
margin:100px 0;
-webkit-column-count:4;-moz-column-count:4;column-count:4;
-webkit-column-gap:30px;-moz-column-gap:30px;column-gap:30px;
}
.box p{
height:30px;
line-height:30px;
text-align:center;
border:1px solid red;
color:#000;
font-size:12px;
}
</style>
</head>
<body>
<div class="box">
<p>第1列</p>
<p>第2列</p>
<p>第3列</p>
<p>第4列</p>
</div>
</body>
</html>
點(diǎn)擊查看css兩端對(duì)齊效果(http://tangjiusheng.com/css3/column.html)
除注明外的文章,均為來(lái)源:湯久生博客,轉(zhuǎn)載請(qǐng)保留本文地址!
原文地址:http://tangjiusheng.com/css3/130.html
*請(qǐng)認(rèn)真填寫需求信息,我們會(huì)在24小時(shí)內(nèi)與您取得聯(lián)系。