聶永的博客

          記錄工作/學(xué)習(xí)的點點滴滴。

          Tsung筆記之插件編寫篇

          前言

          Tsung對具體協(xié)議、通道的支持,一般以插件形式提供接口,接口不是很復(fù)雜,插件也很容易編寫,支持協(xié)議多,也就不足為怪了。

          下面首先梳理一下當前Tsung 1.6.0所有內(nèi)置插件,然后為一個名稱為Qmsg的私有二進制協(xié)議編寫插件, 運行Qmsg服務(wù)器端程序,執(zhí)行壓力測試,最后查看測試報告。

          已支持插件梳理

          Tsung 1.6.0支持的協(xié)議很多,簡單梳理一下:

          Tsung Controller  Support Plugins V2-1?

          • 壓測的協(xié)議首先需要支持xml形式配置,配置內(nèi)容需要 tsung_config_protocolname 模塊解析
            • 存放在tsung_controller目錄下
          • 其次是tsung client端也要插件 ts_protocolname 模塊支持數(shù)據(jù)操作
            • 存放在tsung目錄下
          • 同時在tsung項目examples目錄下也給出了已支持協(xié)議配置簡單示范xml文件

          已經(jīng)支持協(xié)議簡單說明:

          1. amqp,Advanced Message Queuing Protocol縮寫,只要支持高級消息隊列協(xié)議的應(yīng)用,都可以用來做壓測,比如RabbitMQ,ActiveMQ等
          2. http,基本協(xié)議,構(gòu)建于HTTP協(xié)議之上的,還有類似于BOSH,WebDav等上層業(yè)務(wù)協(xié)議
          3. jabber,也稱之為XMPP,支持的相當豐富,除了TCP/SSl,還可以通過Websocekt進行傳遞
          4. raw,針對原始類型消息,不做編解碼處理,直接在TCP / UDP / SSL等傳輸層中傳遞,這個對部分私有協(xié)議,比較友好,不用寫單獨的編解碼處理,直接透傳好了
          5. shell,針對LInux/Unix終端命令調(diào)用進行壓測,這種場景比較小眾
          6. fs,filesystem縮寫,針對文件系統(tǒng)的讀寫性能進行壓測
          7. job,針對任務(wù)調(diào)度程序進行的壓測,比如PBS/torqueLSF、OAR等

          Tsung插件工作機制

          粗一點來看Tsung插件的工作流程(點擊可以看大圖):

          tsung_qmsg_flo?

          放大一些(引用 hncscwc 博客圖片,相當贊!):

          為什么要編寫插件

          Tsung針對通用協(xié)議有支持,若是私有或不那么通用的協(xié)議,就不會有專門的插件支持了,那么可選的有兩條路子:

          • 使用raw模式發(fā)送原始消息,需要自行組裝
          • 自己編寫插件,靈活處理編解碼

          既然談到了插件,我們也編寫一個插件也體驗一下編寫插件的過程。

          Qmsg協(xié)議定義

          假設(shè)一個虛擬場景,打造一個新的協(xié)議Qmsg,二進制格式組成:

          qmsg_protoco?

          這種隨意假象出來的格式,不妨稱作為qmsg(Q可愛形式的message)協(xié)議,僅作為Demo演示而存在。簡單場景:

          • 用戶發(fā)言,包含用戶id和發(fā)言內(nèi)容
            • User ID,32位自然數(shù)類型
            • 發(fā)言為文字內(nèi)容,字符串形式,長度不固定
            • 組裝后的請求體為二進制協(xié)議格式
            • PocketLen:**##UserId + UserComment##**
          • 服務(wù)器端返回用戶ID和一個幸運數(shù)字(32位表示)
            • PocketLen:**##UserId + RandomCode##**

          為了卡哇伊一些,多了一些點綴的“**####**”符號。

          編寫一個完整插件

          這里基于Tsung 1.6.0版本構(gòu)建一個Qmsg插件,假定你懂一些Erlang代碼,以及熟悉Tsung一些基本概念。

          0. 創(chuàng)建一個項目

          要創(chuàng)建Tsung的一個Qmsg插件項目,雖沒有固定規(guī)范,但按照已有格式組織好代碼層級也是有必要的。

          ├── include
          │?? └── ts_qmsg.hrl
          ├── src
          │?? ├── tsung
          │?? │?? └── ts_qmsg.erl
          │?? └── tsung_controller
          │??     └── ts_config_qmsg.erl
          └── tsung-1.0.dtd
          

          1. 創(chuàng)建配置文件

          Tsung的壓測以xml文件驅(qū)動,因此需要界定一個Qmsg插件形式的完整會話的XML呈現(xiàn),比如:

          <session probability="100" name="qmsg-demo" type="ts_qmsg">
              <request>
                <qmsg uid="1001">Hello Tsung Plugin</qmsg>
              </request>
          
              <request>
                <qmsg uid="1002">This is a Tsung Plugin</qmsg>
              </request>
          </session>
          
          • ts_qmsg,會話類型所依賴協(xié)議模擬客戶端實現(xiàn)
          • <qmsg uid="Number">Text</qmsg> 定義了qmsg會話可配置形式,內(nèi)嵌在request元素內(nèi)
          • uid為屬性

          此時,你若直接在xml文件中編輯,會遇到校驗錯誤。

          2. 更新DTD文件

          Tsung的xml文件依賴tsung-1.0.dtd文件進行校驗配置是否有誤,需要做對DTD文件做修改,以支持所添加新的協(xié)議。

          tsung-1.0.dtd項目中,最小支持:

          1. session元素type屬性中添加上 ts_qmsg
          2. request元素處添加 qmsg : <!ELEMENT request ( match*, dyn_variable*, ( http | jabber | raw | pgsql | ldap | mysql |fs | shell | job | websocket | amqp | mqtt | qmsg) )>
          3. 添加qmsg元素定義:
          <!ELEMENT qmsg (#PCDATA) >
          <!ATTLIST qmsg
              uid         CDATA   "0"
              ack         (local | no_ack | parse) #REQUIRED
              >
          

          完整內(nèi)容,可參考tsung_plugin_demo/tsung-1.0.dtd文件。

          3. 頭文件 include/ts_qmsg.hrl

          頭文件include/ts_qmsg.hrl定義數(shù)據(jù)保存的結(jié)構(gòu)(也稱之為記錄/record):

          -record(qmsg_request, {
                    uid,
                    data
                   }).
          
          -record(qmsg_dyndata, {
                    none
                   }
                 ).
          
          1. qmsg_request: 存儲從xml文件解析的qmsg請求數(shù)據(jù),用于生成壓力請求
          2. qmsg_dyndata: 存儲動態(tài)參數(shù)(當前暫未使用到)

          4. XML文件解析

          ts_config_qmsg.erl文件,用于解析和協(xié)議Qmsg關(guān)聯(lián)的配置:
          - 只需要實現(xiàn)parse_config/2唯一方法
          - 解析xml文件中所配置Qmsg協(xié)議請求相關(guān)配置
          - 被ts_config:parse/1在遇到Qmsg協(xié)議配置時調(diào)用

          備注:

          1. 若要支持動態(tài)替換,需要的字段以字符串形式讀和存儲

          5. ts_qmsg.erl

          ts_qmsg.erl模塊主要提供Qmsg協(xié)議的編解碼的完整動作, 以及當前協(xié)議界定下的用戶會話屬性設(shè)定。

          首先需要實現(xiàn)接口ts_plugin規(guī)范定義的所有需要函數(shù),定義了參數(shù)值和返回值。

          -behavior(ts_plugin).
          
          ...
          
          -export([add_dynparams/4,
                   get_message/2,
                   session_defaults/0,
                   subst/2,
                   parse/2,
                   parse_bidi/2,
                   dump/2,
                   parse_config/2,
                   decode_buffer/2,
                   new_session/0]).
          

          相對來說,核心為協(xié)議的編解碼功能:

          • get_message/2,構(gòu)造請求數(shù)據(jù),編碼成二進制,上層ts_client模塊通過Socket連接發(fā)送給目標服務(wù)器
          • parse/2,(當對響應(yīng)作出校驗時)從原始Socket上返回的數(shù)據(jù)進行解碼,取出協(xié)議定義業(yè)務(wù)內(nèi)容

          這部分代碼可以參考 tsung_plugin_demo/src/tsung/ts_client.erl 文件。

          6. 如何編譯

          雖然理論上可以單獨編,生成的beam文件直接拷貝到已經(jīng)安裝的tsung對應(yīng)目錄下面,但實際上插件編寫過程中要依賴多個tsung的hrl文件,這造成了依賴路徑問題。采用直接和tsung打包一起部署,實際操作上有些麻煩,

          為了節(jié)省體力,使用一個shell腳本 - build_plugin.sh,方便快速編譯、部署:

          # !/bin/bash
          
          cp tsung-1.0.dtd $1/
          cp include/ts_qmsg.hrl $1/include/
          cp src/tsung_controller/ts_config_qmsg.erl $1/src/tsung_controller/
          cp src/tsung/ts_qmsg.erl $1/src/tsung/
          
          cd $1/
          make uninstall
          ./configure --prefix=/usr/local
          make install
          

          這里指定安裝Tsung的指定目錄為/usr/local,可以根據(jù)需要修改

          需要提前準備好tsung-1.6.0目錄:

          wget http://tsung.erlang-projects.org/dist/tsung-1.6.0.tar.gz
          tar xf tsung-1.6.0.tar.gz
          

          在編譯Qmsg插件腳本時, 指定一下tsung-1.6.0解壓后的路徑即可:

          sh build_plugin.sh /your_path/tsung-1.6.0
          

          后面嘛,就等著自動編譯和安裝唄。

          啟動Qmsg協(xié)議的壓測

          1. 首先啟動Qmsg服務(wù)器端程序

          既然有壓測端,就需要一個Qmsg協(xié)議處理的后端程序qmsg_server.erl,用于接收客戶端請求,獲得用戶ID值之后,生成一個隨機數(shù)字,組裝成二進制協(xié)議,然后發(fā)給客戶端,這就是全部功能。

          這個程序,簡單一個文件,在 tsung_plugin_demo目錄下面,編譯運行, 默認監(jiān)聽5678端口:

          erlc qmsg_server.erl && erl -s qmsg_server start
          

          另外,還提供了一個手動調(diào)用接口,方便在Erlang Shell端調(diào)試:

          %% 下面為
          qmsg_server:sendmsg(1001, "這里是用戶發(fā)言").
          
          

          啟動之后,監(jiān)聽地址 *: 5678

          源碼見:tsung_plugin_demo/qmsg_server.erl

          2. 編寫Qmsg壓測XML配置文件

          因為是演示示范,一臺Linxu主機上就可以進行了:

          • 連接本機的 127.0.0.1:5678
          • 最多產(chǎn)生10個用戶,每秒產(chǎn)生1個,壓力負載設(shè)置的很低
          • 兩個不同類型會話,比重10% + 90% = 100%
          • qmsg-subst-example會話使用了用戶ID個和用戶發(fā)言內(nèi)容自動生成機制
          <tsung loglevel="debug" dumptraffic="false" version="1.0">
            <clients>
              <client host="localhost" use_controller_vm="true"/>
            </clients>
          
            <servers>
              <server host="127.0.0.1" port="5678" type="tcp"/>
            </servers>
          
            <load>
              <arrivalphase phase="1" duration="1" unit="minute">
                <users maxnumber="10" interarrival="1" unit="second"/>
              </arrivalphase>
            </load>
          
            <sessions>
              <session probability="10" name="qmsg-example" type="ts_qmsg">
                <request>
                  <qmsg uid="1001" ack="parse">Hello Tsung Plugin Qmsg!</qmsg>
                </request>
              </session>
              <session probability="90" name="qmsg-subst-example" type="ts_qmsg">
                <setdynvars sourcetype="random_number" start="3" end="32">
                  <var name="random_uid"/>
                </setdynvars>
                <setdynvars sourcetype="random_string" length="13">
                  <var name="random_txt"/>
                </setdynvars>
                <request subst="true">
                  <qmsg uid="%%_random_uid%%" ack="parse">Haha : %%_random_txt%%</qmsg>
                </request>
                <thinktime value="6"/>
                <request subst="true">
                  <qmsg uid="%%_random_uid%%" ack="parse">This is a Tsung Plugin</qmsg>
                </request>
              </session>
            </sessions>
          </tsung>
          

          這部分內(nèi)容,請參考 tsung_plugin_demo/tsung_qmsg.xml 文件。

          3. 執(zhí)行壓力測試

          當Qmsg的壓力測試配置文件寫好之后,可以開始執(zhí)行壓力測試了:

          tsung -f tsung_qmsg.xml start
          

          其輸出:

          tarting Tsung
          Log directory is: /root/.tsung/log/20160621-1334
          [os_mon] memory supervisor port (memsup): Erlang has closed
          [os_mon] cpu supervisor port (cpu_sup): Erlang has closed
          

          其中, 其日志為:/root/.tsung/log/20160621-1334

          4. 查看壓測報告

          進入其生成壓測日志目錄,然后生成報表,查看壓測結(jié)果哈:

          cd /root/.tsung/log/20160621-1334
          
          /usr/local/lib/tsung/bin/tsung_stats.pl
          
          echo "open your browser (URL: http://IP:8000/report.html) and vist the report now :))"
          /usr/bin/python -m SimpleHTTPServer
          

          嗯,打開你的瀏覽器,輸出所在服務(wù)器的IP地址,就可以看到壓測結(jié)果了。

          小結(jié)

          以上代碼已經(jīng)放入github倉庫:https://github.com/weibomobile/tsung_plugin_demo

          實際業(yè)務(wù)的私有協(xié)議內(nèi)容要比上面Demo出來的Qmsg復(fù)雜的多,但其私有協(xié)議插件編寫,如上面所述幾個步驟,按照規(guī)范編寫,單機測試,然后延伸到分布式集群,完整流程都是一致的。

          嗯,搞定了插件,就可以對系統(tǒng)愉快地進行壓測了 :))

          posted on 2016-07-30 19:37 nieyong 閱讀(5164) 評論(0)  編輯  收藏 所屬分類: 壓測

          公告

          所有文章皆為原創(chuàng),若轉(zhuǎn)載請標明出處,謝謝~

          新浪微博,歡迎關(guān)注:

          導(dǎo)航

          <2016年7月>
          262728293012
          3456789
          10111213141516
          17181920212223
          24252627282930
          31123456

          統(tǒng)計

          常用鏈接

          留言簿(58)

          隨筆分類(130)

          隨筆檔案(151)

          個人收藏

          最新隨筆

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 石家庄市| 水富县| 浙江省| 开平市| 车致| 探索| 贵港市| 亚东县| 平泉县| 金寨县| 确山县| 比如县| 汉阴县| 习水县| 同德县| 曲水县| 德令哈市| 长治市| 呼伦贝尔市| 亚东县| 千阳县| 阿勒泰市| 波密县| 泰和县| 辽宁省| 米脂县| 邳州市| 弥渡县| 广德县| 巴彦县| 巫山县| 龙游县| 上林县| 邢台县| 金寨县| 武穴市| 韶山市| 冕宁县| 武定县| 同德县| 乌恰县|