[go微服务-17] gRPC和 Apache Thrift 之间 如何进行选型?
Posted IT技术小屋
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[go微服务-17] gRPC和 Apache Thrift 之间 如何进行选型?相关的知识,希望对你有一定的参考价值。
引言
上一课时已经对Go语言原生RPC的使用和具体实现原理进行了详细讲解
推荐使用gRPC
Facebook开源的Thrift框架也是业界较为流行的RPC方案
gRPC简介和使用
服务端和客户端需要依赖共同的proto文件
客户端可以十分方便地发送RPC请求
服务端也可以很简单地建立RPC服务器、处理RPC请求并且将返回值作为响应发送给客户端
定义和编译proto文件
syntax = "proto3";
package pb;
service UserService{
rpc CheckPassword(LoginRequest) returns(LoginResponse){}
}
message LoginRequest {
string Username = 1;
string Password = 2;
}
message LoginResponse {
string Ret = 1;
string err= 2;
}
protoc --go_out=plugins=grpc:. pb/user.proto
客户端的本地定义方法
其方法名、参数和返回值与服务端定义的方法相同
gRPC生成的客户端代码会将请求转换为网络消息发送到服务端
客户端发送 RPC请求
func main(){
serviceAddress := "127.0.0.1:1234"
conn, err := grpc.Dial(serviceAddress, grpc.WithInsecure())
if err != nil {
panic( "connect error")
}
defer conn.Close()
userClient := pb.NewUserServiceClient(conn)
userReq := &pb.LoginRequest{Username: "", Password: ""}
reply, _ :=userClient.CheckPassword(context.Background(), userReq)
fmt.Printf("UserService CheckPassword : %s ", reply.Ret)
}
服务端建立RPC服务
func main(){flag.Parse()
lis, err := net.Listen("tcp","127.0.0.1:1234")
if err !=nil{
log.Fatalf("failed to listen: %v", err)
}
grpcServer := grpc.NewServer()
userService := new(user_service.UserService)
pb.RegisterUserServiceServer(grpcServer, userService)
grpcServer.Serve(lis)
}
type UserService struct{}
func (s * UserService) CheckPassword(ctx context.Context, reqpb.LoginRequest)(pb.LoginResponse, error){
if req.Username = "admin" && req.Password == "admin" {
response := pb.LoginResponse{Ret: "success"}
return &response, nil
}
response := pb.LoginResponse{Ret: "fail"}
return &response, nil
}
Thrift简介
Thrift
由Facebook开源的跨平台、支持多语言的成熟 RPC框架,通过定义中间语言(IDL)自动生成RPC客户端与服务端通信代码,可以在C++、Java .Python、php和Go等多种编程语言间构建无缝结合的、高效的 RPC通信服务
定义和编译Thrift文件
namespace go user
struct LoginRequest {
1: string username;
2: string password;
}
struct LoginResponse {
1: string msg;
}
service User {
LoginResponse checkPassword(1: LoginRequest req);
}
使用thrift工具将上述定义编译,生成对应的go代码
thrift -r--gen go user.thrift
客户端发送RPC请求
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 := user.NewUserClientFactory(transport, protocolFactory)
if err :=transport.Open();
err != nil {
log.Fatalln("Error opening:", HOST + ":" + PORT)
defer transport.Close()
req :=user.LoginRequest{Username:"admin", Password: "admin"}
res,err := client.CheckPassword(&req)
fmt.Println(res.Msg)
}
服务端建立RPC服务
func main(){
handler := &UserService}//类似上边的gRPC,是一个实现生成代码中接口的函数的结构体
processor := user.NewUserProcessor(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()
}
对于通信协议(TProtocol)
对于传输方式(TTransport)
对于服务端模型(TServer)
Thrift 框架示意图
gRPC和Thrift的区别和选择
小结
本课时介绍了gRPC和Thrift的整体概念和示例,对二者进行了分析和对比
对比二者,会发现它们缺少了大量的功能
比如:连接池、服务框架、服务发现、服务治理、分布式链路追踪、埋点和上下文日志等
以上是关于[go微服务-17] gRPC和 Apache Thrift 之间 如何进行选型?的主要内容,如果未能解决你的问题,请参考以下文章