<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          編寫一個接口壓測工具

          共 2446字,需瀏覽 5分鐘

           ·

          2021-11-18 02:40

          前言

          前段時間有個項(xiàng)目即將上線,需要對其中的核心接口進(jìn)行壓測;由于我們的接口是 gRPC 協(xié)議,找了一圈發(fā)現(xiàn)壓測工具并不像 HTTP 那么多。

          最終發(fā)現(xiàn)了 ghz 這個工具,功能也非常齊全。

          事后我在想為啥做 gRPC 壓測的工具這么少,是有什么難點(diǎn)嘛?為了驗(yàn)證這個問題于是我準(zhǔn)備自己寫一個工具。

          特性

          前前后后大概花了個周末的時間完成了相關(guān)功能。

          https://github.com/crossoverJie/ptg/

          也是一個命令行工具,使用起來效果如上圖;完整的命令如下:

          NAME:
          ???ptg?-?Performance?testing?tool?(Go)

          USAGE:
          ???ptg?[global?options]?command?[command?options]?[arguments...]

          COMMANDS:
          ???help,?h??Shows?a?list?of?commands?or?help?for?one?command

          GLOBAL?OPTIONS:
          ???--thread?value,?-t?value??????????????-t?10?(default:?1?thread)
          ???--Request?value,?--proto?value????????-proto?http/grpc?(default:?http)
          ???--protocol?value,?--pf?value??????????-pf?/file/order.proto
          ???--fully-qualified?value,?--fqn?value??-fqn?package.Service.Method
          ???--duration?value,?-d?value????????????-d?10s?(default:?Duration?of?test?in?seconds,?Default?10s)
          ???--request?value,?-c?value?????????????-c?100?(default:?100)
          ???--HTTP?value,?-M?value????????????????-m?GET?(default:?GET)
          ???--bodyPath?value,?--body?value????????-body?bodyPath.json
          ???--header?value,?-H?value??????????????HTTP?header?to?add?to?request,?e.g.?"-H?Content-Type:?application/json"
          ???--target?value,?--tg?value????????????http://gobyexample.com/grpc:127.0.0.1:5000
          ???--help,?-h????????????????????????????show?help?(default:?false)

          考慮到受眾,所以同時支持 HTTPgRPC 接口的壓測。

          gRPC 壓測時所需的參數(shù)要多一些:

          ptg?-t?10?-c?100?-proto?grpc??-pf?/xx/xx.proto?-fqn?hello.Hi.Say?-body?test.json??-tg?"127.0.0.1:5000"

          比如需要提供 proto 文件的路徑、具體的請求參數(shù)還有請求接口的全路徑名稱。

          目前只支持最常見的 unary call 調(diào)用,后續(xù)如果有需要的話也可以 stream。

          同時也支持壓測時間、次數(shù)兩種壓測方式。

          安裝

          想體驗(yàn)度朋友如果本地有 go 環(huán)境那直接運(yùn)行:

          go?get?github.com/crossoverJie/ptg

          沒有環(huán)境也沒關(guān)系,可以再 release 頁面下載與自己環(huán)境對應(yīng)的版本解壓使用。

          https://github.com/crossoverJie/ptg/releases

          設(shè)計(jì)模式

          整個開發(fā)過程中還是有幾個點(diǎn)想和大家分享,首先是設(shè)計(jì)模式。

          因?yàn)橐婚_始設(shè)計(jì)時就考慮到需要支持不同的壓測模式(次數(shù)、時間;后續(xù)也可以新增其他的模式)。

          所以我便根據(jù)壓測的生命周期定義了一套接口:

          type?(
          ?Model?interface?{
          ??Init()
          ??Run()
          ??Finish()
          ??PrintSate()
          ??Shutdown()
          ?}
          )?

          從名字也能看出來,分別對應(yīng):

          • 壓測初始化
          • 運(yùn)行壓測
          • 停止壓測
          • 打印壓測信息
          • 關(guān)閉程序、釋放資源

          然后在兩個不同的模式中進(jìn)行實(shí)現(xiàn)。

          這其實(shí)就是一個典型的依賴倒置原則。

          程序員要依賴于抽象接口編程、不要依賴具體的實(shí)現(xiàn)。

          其實(shí)大白話就是咱們 Java 里常說的面向接口編程;這個編程技巧在開發(fā)框架、SDK或是多種實(shí)現(xiàn)的業(yè)務(wù)中常用。

          好處當(dāng)然是顯而易見:當(dāng)接口定義好之后,不同的業(yè)務(wù)只需要根據(jù)接口實(shí)現(xiàn)自己的業(yè)務(wù)就好,完全不會互相影響;維護(hù)、擴(kuò)展都很方便。

          支持 HTTPgRPC 也是同理實(shí)現(xiàn)的:

          type?(
          ?Client?interface?{
          ??Request()?(*Response,?error)
          ?}
          )?

          當(dāng)然前提得是前期的接口定義需要考慮周全、不能之后頻繁修改接口定義,這樣的接口就沒有意義了。

          goroutine

          另外一點(diǎn)則是不得不感嘆 goroutine+select+channel 這套并發(fā)編程模型真的好用,并且也非常容易理解。

          很容易就能寫出一套并發(fā)代碼:

          func?(c?*CountModel)?Init()?{
          ?c.wait.Add(c.count)
          ?c.workCh?=?make(chan?*Job,?c.count)
          ?for?i?:=?0;?i???go?func()?{
          ???c.workCh?<-?&Job{
          ????thread:???thread,
          ????duration:?duration,
          ????count:????c.count,
          ????target:???target,
          ???}
          ??}()
          ?}
          }

          比如這里需要初始化 N 個 goroutine 執(zhí)行任務(wù),只需要使用 go 關(guān)鍵字,然后利用 channel 將任務(wù)寫入。

          當(dāng)然在使用 goroutine+channel 配合使用時也得小心 goroutine 泄露的問題;簡單來說就是在程序員退出時還有 goroutine 沒有退出。

          比較常見的例子就是向一個無緩沖的 channel 中寫數(shù)據(jù),當(dāng)沒有其他 goroutine 來讀取數(shù)時,寫入的 goroutine 就會被一直阻塞,最終導(dǎo)致泄露。

          總結(jié)

          gRPC 接口壓測需求的朋友歡迎試用,提出寶貴意見;當(dāng)然 HTTP 接口也可以。

          源碼地址:https://github.com/crossoverJie/ptg/

          最后如果有同樣在學(xué)習(xí) go 的朋友,特別是有 Java 開發(fā)經(jīng)驗(yàn)的(這里大部分應(yīng)該都寫 Java)朋友,感興趣的可以在公眾號后臺回復(fù) "go群" 加入我創(chuàng)建的一個與 go 開發(fā)相關(guān)的技術(shù)群。


          瀏覽 69
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  久久久久久久九九九九 | 国产无码精品毛片 | 哦美草逼视频 | 操逼无码高清 | 黄色电影网站免费在线观看 |