1. 程式人生 > >Go thrift使用舉例

Go thrift使用舉例

thrift 最初是 facebook 開發使用的 rpc 通訊框架,後來貢獻給了 apache 基金會,出來得比較早,幾乎支援所有的後端語言,使用非常廣泛,是不可不知的一個網路框架。

和 grpc 一樣,需要先定義通訊協議,然後實現自己業務邏輯。

下面介紹其使用方法。

下載go thrift 庫

$ go get git.apache.org/thrift.git/lib/go/thrift/...

注意:此時的版本庫時間是2017.7,因此當時不支援context。

下載協議轉換工具thrift

$ wget http://www-us.apache.org/dist/thrift/0.10
.0/thrift-0.10.0.tar.gz $ tar -xzvf thrift-0.10.tar.gz $ cd thrift-0.10.0 $ ./configure --prefix=/usr $ make -j8 $ [sudo] make install

另外,一個問題,編譯thrift時報錯:

GOPATH=pwd /home/lanyang/work/pkgs/go/bin/go get github.com/golang/mock/gomock
package golang.org/x/net/context: unrecognized import path “golang.org/x/net/context” (https fetch: Get

https://golang.org/x/net/context?go-get=1: dial tcp 216.239.37.1:443: i/o timeout)

網上各種方法都試過,無法搞定。

根據報錯提示,註釋掉 test/go/Makefile 檔案中

#GOPATH=pwd $(GO) get github.com/golang/mock/gomock

然後,手動下載gomock。
由於gomock依賴net,所以先下載net。
直接 go get golang.org/x/net 會失敗,是由於被牆。
可採用
https://github.com/golang/net下載(可以直接 go get github.com/golang/net),然後把目錄改成golang.org/x/net。

完成net下載和配置後,接著下載mock

$ go get github.com/golang/mock/gomock

最後編譯通過。

定義協議檔案echo.thrift

在GOPATH目錄下建立thriftExample目錄,在該目錄建立檔案echo.thrift,內容如下:

namespace go echo

struct EchoReq {
    1: string msg;
}

struct EchoRes {
    1: string msg;
}

service Echo {
    EchoRes echo(1: EchoReq req);
}

協議轉換

命令格式

thrift --gen <language> <Thrift filename>

至於thrift的用法,可以使用thrift -help檢視幫助。

執行以下命令會生成 gen-go 資料夾,這個過程其實是將上面的協議翻譯成 golang 程式碼。

$ thrift -r --gen go echo.thrift 

生成的gen-go 資料夾包括以下檔案

[[email protected] thriftExample]$ ll gen-go/ -R
gen-go:
total 4
drwxrwxr-x. 3 lanyang lanyang 4096 May 13 23:18 echo

gen-go/echo:
total 28
-rw-rw-r--. 1 lanyang lanyang   349 May 13 23:18 echo-consts.go
-rw-rw-r--. 1 lanyang lanyang 16161 May 13 23:18 echo.go
drwxrwxr-x. 2 lanyang lanyang  4096 May 13 23:18 echo-remote
-rw-rw-r--. 1 lanyang lanyang   159 May 13 23:18 GoUnusedProtection__.go

gen-go/echo/echo-remote:
total 4
-rwxr-xr-x. 1 lanyang lanyang 4017 May 13 23:18 echo-remote.go

其中,echo.go是生成的型別和方法定義,echo-remote是client示例程式碼。

示例程式碼

下面簡單舉例說明其使用。

服務端程式碼

服務端程式碼server.go如下:

package main

import (

    "fmt"
    "git.apache.org/thrift.git/lib/go/thrift"

    "thriftExample/gen-go/echo"

)


type EchoServer struct {
}

func (e *EchoServer) Echo(req *echo.EchoReq) (*echo.EchoRes, error) {
    fmt.Printf("message from client: %v\n", req.GetMsg())

    res := &echo.EchoRes{
        Msg: "success",
    }

    return res, nil
}

func main() {
    transport, err := thrift.NewTServerSocket(":9898")
    if err != nil {
        panic(err)
    }

    handler := &EchoServer{}
    processor := echo.NewEchoProcessor(handler)

    transportFactory := thrift.NewTBufferedTransportFactory(8192)
    protocolFactory := thrift.NewTCompactProtocolFactory()
    server := thrift.NewTSimpleServer4(
        processor,
        transport,
        transportFactory,
        protocolFactory,
    )

    if err := server.Serve(); err != nil {
        panic(err)
    }
}

客戶端程式碼

客戶端程式碼client.go如下

package main

import (
    "fmt"
    "log"
    "net"
    "os"

    "git.apache.org/thrift.git/lib/go/thrift"

    "thriftExample/gen-go/echo"
)

func main() {
    transportFactory := thrift.NewTBufferedTransportFactory(8192)
    protocolFactory := thrift.NewTCompactProtocolFactory()

    transport, err := thrift.NewTSocket(net.JoinHostPort("127.0.0.1", "9898"))
    if err != nil {
        fmt.Fprintln(os.Stderr, "error resolving address:", err)
        os.Exit(1)
    }

    useTransport, err := transportFactory.GetTransport(transport)
    client := echo.NewEchoClientFactory(useTransport, protocolFactory)
    if err := transport.Open(); err != nil {
        fmt.Fprintln(os.Stderr, "Error opening socket to 127.0.0.1:9898", " ", err)
        os.Exit(1)
    }
    defer transport.Close()

    req := &echo.EchoReq{Msg:"You are welcome."}
    res, err := client.Echo(req)
    if err != nil {
        log.Println("Echo failed:", err)
        return
    }

    log.Println("response:", res.Msg)
    fmt.Println("well done")

}

server ouput:

$ ./server
message from client: You are welcome.

client output:

$ ./client
2018/05/19 11:12:37 response: success
well done

注意:服務端和客戶端進行通訊時使用的協議一定要相同,例如上例中的,transport factory是 buffer transport factroy,protocol factory 是compact protcol。

參考

相關推薦

Go thrift使用舉例

thrift 最初是 facebook 開發使用的 rpc 通訊框架,後來貢獻給了 apache 基金會,出來得比較早,幾乎支援所有的後端語言,使用非常廣泛,是不可不知的一個網路框架。 和 grpc 一樣,需要先定義通訊協議,然後實現自己業務邏輯。 下面介紹

go thrift報錯問題--WriteStructEnd

AC tcl index com lock 0xc4 created src IT 問題 go thrift開發過程中,多個goroutine共用一個client時,報錯: panic: runtime error: index out of range goroutin

go thrift oprot.Flush() not enough arguments in

per targe snapshot 版本 ofo 工程 frame main 客戶 代碼在GitHub上托管 https://github.com/xej520/xingej-thrift/tree/master/hw-thrift 環境說明 windo

window go thrift

pen 拷貝 技術分享 main apache mat nts tps [] 代碼在GitHub上托管 https://github.com/xej520/xingej-thrift/tree/master/hw-thrift 環境說明 windows 1

go thrift 開發

thrift 從 0.9.1版本開始,可以完美支援 go 語言,可以完美的實現跨語言的 rpc 呼叫了。下面以 go 和 java 語言相互呼叫為例。   編輯協議檔案,go 語言示例 /** example.thrift */ namespace go example se

k8s client-go使用舉例

容器中執行命令: https://github.com/appscode/searchlight/blob/22632646424bdd34c98bdaec87553fd182a85945/plugins/check_pod_exec/lib.go#L62 建立client和controll

go 函式舉例練習

1. 求1到100之內的所有質數,並列印到螢幕上 package main import "fmt" // 求1-100 內的質數 func justfy(i int) bool { if i <= 1 { return false } f

從零開始基於go-thrift建立一個RPC服務

Thrift 是一種被廣泛使用的 rpc 框架,可以比較靈活的定義資料結構和函式輸入輸出引數,並且可以跨語言呼叫。為了保證服務介面的統一性和可維護性,我們需要在最開始就制定一系列規範並嚴格遵守,降低後續維護成本。 Thrift開發流程是:先定義IDL,使用thrift工具生成目標語言介面(interfac

利用thrift rpc進行C++與Go的通信

span 網絡 gen generate golang fun package should edt 一:什麽是rpc rpc通俗來理解就是遠程調用函數,相對於本地調用來說,只需要在主調函數中調用被掉函數即可,代碼如下: 1 void fun(int i) 2 {

Go mysql使用舉例

Go div ret mar idl uri 數據庫 int tab 下載MySQL驅動 $ go get github.com/go-sql-driver/mysql 或者下載源碼放到GOPATH中,下載地址:https://github.com/go-sql-drive

Go 操作mysql使用舉例---連接本地數據庫

sockets unix cnblogs err ini oca .cn ive RoCE 連接數據庫的方式有兩種:TCP和Unix域socket。 本文使用Unix domain sockets連接數據庫。關於TCP連接數據庫可以參考Go 操作mysql使用舉例 pack

go 函數舉例練習

數字 雙引號 har str span ron utf8 之間 ace 1. 求1到100之內的所有質數,並打印到屏幕上 package main import "fmt" // 求1-100 內的質數 func justfy(i int) bool { if

Thrift --- 支持雙向通信

thrift .org 遠程 大量 浪費 int 缺陷 org 請求 【問題】 Thrift采用了C/S模型,不支持雙向通信:client只能遠程調用server端的RPC接口,但client端則沒有RPC供server端調用,這意味著,client端能夠主動與se

go 自己封的postgresql操作包

rep make query res urn mod .exe errors exe 1 package myDB 2 3 import ( 4 "database/sql" 5 "errors" 6 7 _ "g

go-005-變量

整數 func 基礎 字型 開始 import open spl 註意 概述   變量來源於數學,是計算機語言中能儲存計算結果或能表示值抽象概念。變量可以通過變量名訪問。   Go 語言變量名由字母、數字、下劃線組成,其中首個字母不能為數字。   聲明變量的一般形式是

GO中常用包筆記 bytes(四)

g 學習筆記 bytes包Package bytes對字節數組進行操作的包。功能和strings包相似.bytes包提供的功能有:和另一個字節數組切片的關系(逐字節比較大小,是否相等/相似,是否包含/包含次數,位置搜索,是否是前綴後綴)2.字節數組切片和字符串的關系(字符串中是否含有字節數組所包含的rune,

常見的JQuery應用舉例

cnblogs 快捷 mouseover near alert put 模式 遊戲 工作效率 在學習JS之後,JQuery(以下簡稱JQ)為我們提供了一種更加便捷和簡單的操作模式,利用它開發人員將更為高效的進行工作,下面將一些常見的問題進行舉例。 1.點擊某處彈出提醒,例如

CDOJ 1221 Ancient Go

cout#include<bits/stdc++.h>using namespace std;bool ok;char maze[15][15];char Map[12][12];bool vis[15][15];int x[4] = {0,0,1,-1};int y[4] = {1,-1,0,0

Go - 數組

索引 創建 16px class 表示 int32 部分 func amp 數組: Array 1. 定義: var <arrayName> [n] (n>=0) <type> 註: 數組的長度n,也是數組定義的組成部分;所以:var i

Go語言之嵌入類型

go 類型 嵌入類型,或者嵌套類型,這是一種可以把已有的類型聲明在新的類型裏的一種方式,這種功能對代碼復用非常重要。在其他語言中,有繼承可以做同樣的事情,但是在Go語言中,沒有繼承的概念。Go提倡的代碼復用的方式是組合,所以這也是嵌入類型的意義所在。組合而不是繼承,所以Go才會更靈活。type Rea