博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Grpc介绍 — ProToBuf基本使用
阅读量:5873 次
发布时间:2019-06-19

本文共 5101 字,大约阅读时间需要 17 分钟。

hot3.png

RPC(Remote Procedure Call)远程过程调用,关注笔者的同学应该知道之前笔者出过关于Thrift对应的问题,这次主要来说的是Google开源的Grpc,和Thrift有很大的区别Grpc是基于HTTP2.0并且依赖protobuf,为什么又推出关于grpc的文章呢?请大家继续往下看。

附上:

喵了个咪的博客:

博文实例demo:

grpc官网:

protobuf代码仓库:

一,为什么要用grpc它的优势是什么

一个高性能、通用的开源RPC框架,其由Google主要面向移动应用开发并基于HTTP/2协议标准而设计,基于ProtoBuf(Protocol Buffers)序列化协议开发,且支持众多开发语言。 gRPC基于HTTP/2标准设计,带来诸如双向流控、头部压缩、单TCP连接上的多复用请求等特性。这些特性使得其在移动设备上表现更好,更省电和节省空间占用。

性能 Grpc PK Thrift 借鉴:

PS:笔者也做了对应的性能测试,后面的文章会附上详细步骤,通过这个现有的结果一个简单的结论

从压测的结果商米我们可以得到以下重要结论:

  • 整体上看,长连接性能优于短连接,性能差距在两倍以上;
  • 对比Go语言的两个RPC框架,Thrift性能明显优于gRPC,性能差距也在两倍以上;
  • 对比Thrift框架下的的两种语言,长连接下Go 与C++的RPC性能基本在同一个量级,在短连接下,Go性能大概是C++的二倍;
  • 两套RPC框架,以及两大语言运行都非常稳定,5w次请求耗时约是1w次的5倍;

这里主要要回答的一个问题是既然已经用thrift并且性能还是grpc的2倍为什么还要用grpc呢?

这里主要要说到两个Go的微服务框架,go-kit和istio

  • go-kit 支持thrift但是在thrift的情况下不支持链路追踪
  • istio因为是无侵入式连thrift也不支持

主要的导致这个问题的原因在于thrift的传输方式是通过TCP的方式传输,对于这些框架想在传输过程中加入些链路的ID是无法实现的,istio连对于thrift的请求次数感知都做不到,对于grpc因为是基于http2在harder头上可以做很多补充参数,对于这类微服务框架非常友好。


二,安装protobuf

安装protobuf为了生成对应语言的文件必须需要protoc的命名,protoc是c语言的protobuf的命名,有两种访问一个是自己编译:

wget https://github.com/protocolbuffers/protobuf/releases/download/v3.6.1/protobuf-cpp-3.6.1.tar.gz> tar -zxvf protobuf-cpp-3.6.1.tar.gz> cd protobuf-3.6.1> ./configure> make> make install> protoc --versionlibprotoc 3.6.1

或者根据更具系统直接使用编译好的bin文件运行protoc(这里使用的是MAC OSX系统)

wget https://github.com/protocolbuffers/protobuf/releases/download/v3.6.1/protoc-3.6.1-osx-x86_64.zip> tar -zxvf protoc-3.6.1-osx-x86_64.zip> cd protoc-3.6.1-osx-x86_6/bin> ./protoc --version> libprotoc 3.6.1

安装好了我们就要来运行下测试程序了


三,Golang 环境准备

不得不说Go是Google的亲儿子,自然Grpc的支持不会差依赖只需要一个命令就可以(这里使用的是go 1.11版本):

> go get google.golang.org/grpc

如果大家报错,原因是这个代码已经转移到github上面了,但是代码里面的包依赖还是没有修改,还是google.golang.org这种,所以有的不能使用go get的方式安装,可以使用以下安装方式:

> git clone https://github.com/grpc/grpc-go.git $GOPATH/src/google.golang.org/grpc> git clone https://github.com/golang/net.git $GOPATH/src/golang.org/x/net> git clone https://github.com/golang/text.git $GOPATH/src/golang.org/x/text> git clone https://github.com/golang/sys.git $GOPATH/src/golang.org/x/sys> go get -u github.com/golang/protobuf/{proto,protoc-gen-go}> git clone https://github.com/google/go-genproto.git $GOPATH/src/google.golang.org/genproto> cd $GOPATH/src/> go install google.golang.org/grpc

先使用笔者的准备好的:

> cd $GOPATH/src> mkdir -p grpc-php-to-golang-demo/protobuf> cd grpc-php-to-golang-demo/protobuf> vim helloworld.proto

文件内容如下:

syntax = "proto3";option java_multiple_files = true;option java_package = "io.grpc.examples.helloworld";option java_outer_classname = "HelloWorldProto";option objc_class_prefix = "HLW";package helloworld;// The greeting service definition.service Greeter {  // Sends a greeting  rpc SayHello (HelloRequest) returns (HelloReply) {}}// The request message containing the user's name.message HelloRequest {  string name = 1;}// The response message containing the greetingsmessage HelloReply {  string message = 1;}

生成对应的文件:

> mkdir -p go-server/helloworld> protoc --go_out=plugins=grpc:./go-server/helloworld ./helloworld.proto> cd go-server/helloworld/> lltotal 16drwxr-xr-x  3 wenzhenxi  staff    96  2 15 14:24 ./drwxr-xr-x  3 wenzhenxi  staff    96  2 15 14:23 ../-rw-r--r--  1 wenzhenxi  staff  6915  2 15 14:24 helloworld.pb.go

编写服务端和客户端Go程序:

> cd $GOPATH/src/grpc-php-to-golang-demo> mkdir -p golang/holleworld> cd golang/holleworld

服务端:

> vim server.go package mainimport (	"log"	"net"	pb "grpc-php-to-golang-demo/protobuf/go-server/helloworld"	"google.golang.org/grpc"	"golang.org/x/net/context"	"google.golang.org/grpc/reflection")const (	port = ":50051")// server is used to implement helloworld.GreeterServer.type server struct{}// SayHello implements helloworld.GreeterServerfunc (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {	return &pb.HelloReply{Message: "Hello " + in.Name}, nil}func main() {	lis, err := net.Listen("tcp", port)	if err != nil {		log.Fatalf("failed to listen: %v", err)	}	s := grpc.NewServer()	pb.RegisterGreeterServer(s, &server{})	// Register reflection service on gRPC server.	reflection.Register(s)	if err := s.Serve(lis); err != nil {		log.Fatalf("failed to serve: %v", err)	}}

客户端:

> vim client.gopackage mainimport (	"log"	"os"	"time"	pb "grpc-php-to-golang-demo/protobuf/go-server/helloworld"	"google.golang.org/grpc"	"golang.org/x/net/context")const (	address     = "localhost:50051"	defaultName = "world")func main() {	// Set up a connection to the server.	conn, err := grpc.Dial(address, grpc.WithInsecure())	if err != nil {		log.Fatalf("did not connect: %v", err)	}	defer conn.Close()	c := pb.NewGreeterClient(conn)	// Contact the server and print out its response.	name := defaultName	if len(os.Args) > 1 {		name = os.Args[1]	}	go func() {		r, err := c.SayHello(context.Background(), &pb.HelloRequest{Name: name})		if err != nil {			log.Fatalf("could not greet: %v", err)		}		log.Printf("Greeting: %s", r.Message)	}()	time.Sleep(10 * time.Second)}

运行测试:

> go build server.go> go build client.go./server./client2019/02/15 14:35:35 Greeting: Hello world

此时在go to go的场景就调用通了

最终产物可以参考demo

转载于:https://my.oschina.net/wenzhenxi/blog/3016007

你可能感兴趣的文章
[Contiki系列论文之1]Contiki——为微传感器网络而生的轻量级的、灵活的操作系统...
查看>>
Android 网络编程 记录
查看>>
微软同步发行Windows 10和Windows 10 Mobile系统更新
查看>>
Maven 传递依赖冲突解决(了解)
查看>>
Zeppelin的入门使用系列之使用Zeppelin运行shell命令(二)
查看>>
安装kali linux 2017.1 【二、安装VMware-tools 以及相关问题处理】
查看>>
[Spark][Python]Spark Join 小例子
查看>>
form表单下的button按钮会自动提交表单的问题
查看>>
大战设计模式【11】—— 模板方法模式
查看>>
springBoot介绍
查看>>
Intellij IDEA 快捷键整理
查看>>
Redis 通用操作2
查看>>
性能优化——统计信息——SQLServer自动更新和自动创建统计信息选项
查看>>
11. Spring Boot JPA 连接数据库
查看>>
洛谷P2925 [USACO08DEC]干草出售Hay For Sale
查看>>
MapReduce工作原理流程简介
查看>>
那些年追过的......写过的技术博客
查看>>
小米手机解锁bootload教程及常见问题
查看>>
Python内置函数property()使用实例
查看>>
Spring MVC NoClassDefFoundError 问题的解决方法。
查看>>