/ 城寒 / Golang - Thrift RPC

Golang - Thrift RPC

2018-01-27 posted in [Golang]

安装

安装golang的thrift包

  1. 直接接执行 go get git.apache.org/thrift.git/lib/go/thrift,运气好可能就成功了,就完成本节安装
  2. 失败的话到git下载源码
  3. 创建文件夹mkdir -p $GOPATH/src/git.apache.org/thrift.git/lib/go
  4. 解压文件,复制目录下thrift.0.10.0/lib/go到该目录下
  5. 执行go install git.apache.org/thrift.git/lib/go/thrift 完成安装

安装thrift

  1. 根据官方教程环境大概需要:autoconf, automake, bison,实测还需要pkg-config
  2. 进入刚才解压的thrift.0.10.0,执行./bootstrap.sh 2.1 可能会提示automake版本过低,下载新版本后,解压进入执行./configure && make && make install
  3. 执行./configure --enable-libs=no进行检查 3.1 缺少Bison,下载后安装 3.2 此时还是可能失败,提示: No compiler with C++11 support was found ./configure: line 16656: syntax error near unexpected tokenQT, ./configure: line 16656: PKG_CHECK_MODULES(QT, QtCore >= 4.3, QtNetwork >= 4.3, have_qt=yes, have_qt=no)' 3.3 这个是由于pkg-config包引起的,官方没有说明,需要安装 3.4 安装后,将系统中的pkg.m4文件复制到thrift/aclocalcp /usr/share/aclocal/pkg.m4 aclocal 3.5 然后重新从第一步开始,就可以了
  4. make 4.1 如果还是出现蜜汁错误,可以在第三步configure中,加一些配置,去掉不需要的功能 ./configure --without-qt4 --without-qt5 --without-c_glib --without-cpp --without-csharp --enable-libs=no 4.2 观察日志,问题多处在cpp和c_glib,如果需要还需要解决提示的问题
  5. make install

例子

实现一对client和server之间的通信,client调用server端的一个函数,将字符串转换成大写

Thrift RPC 接口

namespace py example
struct Data {
    1: string text
}
service format_data {
    Data do_format(1:Data data),
}

生成golang包,放到$GOPATH/srcthrift -out $GOPATH/src/ThriftDemo --gen go example.thrift

client 端

package main
import (
    "git.apache.org/thrift.git/lib/go/thrift"
    "context"
    "net"
    "fmt"
    "ThriftDemo/example"
    "log"
)
const (
    HOST = "localhost"
    PORT = "9999"
)
func main()  {
    tSocket, err := thrift.NewTSocket(net.JoinHostPort(HOST, PORT))
    if err != nil {
        log.Fatalln("tSocket error:", err)
    }
    transportFactory := thrift.NewTFramedTransportFactory(thrift.NewTTransportFactory())
    transport,_ := transportFactory.GetTransport(tSocket)
    protocolFactory := thrift.NewTBinaryProtocolFactoryDefault()
    client := example.NewFormatDataClientFactory(transport, protocolFactory)
    if err := transport.Open(); err != nil {
        log.Fatalln("Error opening:", HOST + ":" + PORT)
    }
    defer transport.Close()
    ctx, _ := context.WithCancel(context.Background())
    data := example.Data{Text:"hello,world!"}
    d, err := client.DoFormat(ctx, &data)
    fmt.Println(d.Text)
}

server 端

package main
import (
    "ThriftDemo/example"
    "context"
    "strings"
    "git.apache.org/thrift.git/lib/go/thrift"
    "fmt"
    "log"
)
type FormatDataImpl struct {}
func (fdi *FormatDataImpl) DoFormat(ctx context.Context, data *example.Data) (r *example.Data, err error){
    var rData example.Data
    rData.Text = strings.ToUpper(data.Text)
    return &rData, nil
}
const (
    HOST = "localhost"
    PORT = "9999"
)
func main() {
    handler := &FormatDataImpl{}
    processor := example.NewFormatDataProcessor(handler)
    serverTransport, err := thrift.NewTServerSocket(HOST + ":" + PORT)
    if err != nil {
        log.Fatalln("Error:", err)
    }
    transportFactory := thrift.NewTFramedTransportFactory(thrift.NewTTransportFactory())
    protocolFactory := thrift.NewTBinaryProtocolFactoryDefault()
    server := thrift.NewTSimpleServer4(processor, serverTransport, transportFactory, protocolFactory)
    fmt.Println("Running at:", HOST + ":" + PORT)
    server.Serve()
}

测试

go run server.go
go run client.go

client端可以看到HELLO,WORLD!

其他高级用法可以到这里查看