thrift協議的服務進壓力測試


Thrift vs  Grpc內容如下鏈接

http://blog.csdn.net/dazheng/article/details/48830511

 

背景:Facebook 開發的遠程服務調用框架 Apache Thrift,它采用接口描述語言定義並創建服務,支持可擴展的跨語言服務開發,所包含的代碼生成引擎可以在多種語言中創建高效的、無縫的服務,其傳輸數據采用二進制格式,相對 XML 和 JSON 體積更小,對於高並發、大數據量和多語言的環境更有優勢。

負責的搜索服務使用thrift,之前是對其http的上游服務進行壓測,從而壓到該thrift服務;后續想調研一種方式能夠直接對thrift服務進行壓測。

thrift框架的C++小程序見:http://www.cnblogs.com/zhaoxd07/p/5387215.html

調研方向:

一 Jmeter

具體邏輯與使用Jmeter進行java請求的壓測方式相似:http://www.cnblogs.com/zhaoxd07/p/4895224.html

區別在於setUp中對於協議的選擇,會對結果有較大影響

TProtocol protocol = new TCompactProtocol(transport);
client = new Service.Client(protocol);

原則為:與被測代碼使用協議一致即可

二 bender

https://github.com/pinterest/bender

為Pinterest公司開發的,可以對http和thrift協議做壓測,使用go語言實現的。我試了一下挺好用的,就是go語言用不太習慣

主要難點在於main.go文件的實現,與Jmeter需要注意點一致:協議的使用

具體操作步驟如下:

1  Go環境初始化

1)  下載安裝     

# 下載安裝go
cd /usr/local/  自己選擇安裝目錄和工作目錄
wget https://storage.googleapis.com/golang/go1.8.3.linux-amd64.tar.gz
tar -xzvf go1.8.3.linux-amd64.tar.gz

2) 配置環境變量   

# 環境變量配置
vim /etc/profile 增加如下行:
#go variable
export GOROOT=/usr/local/go
export PATH=$PATH:/usr/local/go/bin
export GOPATH=/data/bender/
export GOBIN=/data/bender/bin
完成后保存 並使其生效 source /etc/profile

3) 確認變量配置是否生效

#echo $GOROOT
/usr/local/go

2  下載安裝需要的插件

cd $GOPATH
go get git.apache.org/thrift.git/lib/go/thrift go get github.com/pinterest/bender

3 准備server和client

准備server和client

因為我這是個實際項目,server已經由開發同學實現並啟動,所以此時只需要准備server即可。如下

Server

 

cd $GOPATH/workspace/myProject/                # 進入我的工作目錄
rz my_interface.thrift                         # 上傳我的接口文件
thrift  -gen go my_interface.thrift            # 將thrift文件轉成go語言

 

4 准備壓測腳本bender

編寫壓測文件 在myProject目錄下 新建 myBender文件夾,vim main.sh如下:

package main

// import 若提示有錯,就看下目錄下文件是否可用
import (    
    "github.com/pinterest/bender"
    bthrift "github.com/pinterest/bender/thrift"
    "git.apache.org/thrift.git/lib/go/thrift"
    ....
    "github.com/pinterest/bender/hist"
)

// 准備壓測數據,我用的服務的日志,解析后作為請求發送,相當於回放
func SyntheticRequests(n int) chan interface{} {
    f, err := os.Open("./advanced_search.info")
    paramList := make([]*as.QueryParam, 0)
    if err != nil {
        panic(err)
    }   
    defer f.Close()
    
    rd := bufio.NewReader(f)
    for {
        line, err := rd.ReadString('\n')
        
        if err != nil || io.EOF == err {
            break
        } else {
            json_transport := thrift.NewTMemoryBufferLen(len([]rune(line)))
            json_transport.WriteString(line)
            json_protocol := thrift.NewTJSONProtocol(json_transport)
            param := as.NewQueryParam()
            param.Read(json_protocol)
            paramList = append(paramList, param)
        }
    }
    max := len(paramList)
    c := make(chan interface{}, 100)
    go func() {
        for i := 0; i < n; i++ {
            rand.Seed(int64(time.Now().Nanosecond()))
            c <- paramList[rand.Intn(max)]
        }
        close(c)
    }()
    return c
}

//重要:需要跟服務端所用協議一致
func ASExecutor(request interface{}, transport thrift.TTransport) (interface{}, error) {
    pFac := thrift.NewTCompactProtocolFactory()
    client := as.NewRecommendSrvClientFactory(transport, pFac)
    return client.GetCampaigns(request.(*as.QueryParam))   
}

// 主要是用bender的接口,完成壓測
func main() {
    intervals := bender.ExponentialIntervalGenerator(150)      // 150 -- qps
    requests := SyntheticRequests(150*60*1)                    //總請求數
    //buffer字節數, clientExec, 超時時間, hosts--寫server所在的ip和端口,如非同一機器,保證端口可訪問
    exec := bthrift.NewThriftRequestExec(thrift.NewTBufferedTransportFactory(125), ASExecutor, 100 * time.Second, "127.0.0.1:9099")
    recorder := make(chan interface{}, 128)
    bender.LoadTestThroughput(intervals, requests, exec, recorder)
    l := log.New(os.Stdout, "", log.LstdFlags)
    h := hist.NewHistogram(60000, 1000000)
    bender.Record(recorder, bender.NewLoggingRecorder(l), bender.NewHistogramRecorder(h))
    fmt.Println(h)
}

5 運行及結果

1  編譯

cd $GOPATH
go install workspace/asthrift/asbender    // main.go在目錄asbender下

編譯后的可執行文件在目錄bin下,貌似新文件不能直接覆蓋舊文件,因此我會先手動刪除舊文件

2 執行

如下結果是因為所請求的server未啟動(因該服務現階段不屬於我維護,該結果僅做參考示例)

[root@ip bin]#./asbender
Percentiles:
 Min:     0
 Median:  1
 90th:    1
 99th:    1
 99.9th:  1
 99.99th: 4
 Max:     10
Stats:
 Average: 0.923222
 Total requests: 9000
 Elapsed Time (sec): 59.5483
 Average QPS: 151.14
 Errors: 9000
 Percent errors: 100.00

6 問題與解決

 使用直接下載的bender運行時,會打印出請求的詳細資料,導致壓測的qps不能完成預期,可手動注釋掉bender相關代碼,並重新編譯。

vim src/github.com/pinterest/bender/recorders.go,注釋掉第44行。

 

 41 // NewLoggingRecorder creates a new log.Logger-based recorder.
 42 func NewLoggingRecorder(l *log.Logger) Recorder {
 43     return func(msg interface{}) {
 44 //      logMessage(l, msg)
 45     }
 46 }

 

刪除目錄下的pkg/linux_amd64/github.com/pinterest/bender.a文件,並重新編譯:

go install github.com/pinterest/bender

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM