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工具安裝過程中可能會報錯,關於如何安裝依賴,請參看Building Apache Thrift on CentOS 6.5.
另外,一個問題,編譯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 文件夾包括以下文件
[lanyang@localhost 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。
參考
github
https://github.com/apache/thrift/
github go thrift
https://github.com/apache/thrift/tree/master/lib/go
Building Apache Thrift on CentOS 6.5
http://thrift.apache.org/docs/install/centos
不同系統如何安裝thrift工具
http://thrift.apache.org/docs/install/
go thrift example(很有參考價值)
https://github.com/apache/thrift/tree/master/tutorial/go/src
golang 網絡框架之 thrift
https://segmentfault.com/a/1190000013127570
Golang通過Thrift框架完美實現跨語言調用
https://my.oschina.net/qinerg/blog/165285