gRPC 初探

gRPC 初探

  • 前言
  • 安装
  • 使用
  • 参考

前言

gRPC 出来很久了,很多地方都在使用中。因为是google 出品的所以一直受到很大的关注。

在实际的学习中,和其他的rpc框架还是有些特点:

  1. 跨语言,如果项目是跨语言通信的可以考虑使用gRPC。
  2. gRPC 基于 HTTP/2 标准设计,使其在移动设备上表现更好,更省电和节省空间占用。
  3. 通信格式默认使用protocolbuffer(是google 的一种数据交换的格式,它独立于语言,独立于平台),二进制,性能好,现在使用 proto3的新风格。

下面是使用中的一些笔记,已 golang 为基础

安装

我们先安装gRPC-Go:

 #直接使用 get 安装,源码中包括了后面的examples
go get -u google.golang.org/grpc

现在还不能使用gRPC,还需要安装前面提到的protocolbuffer

protocolbuffer 安装,golang需要编译安装
git clone git@github.com:google/protobuf.git
cd protobuf/

 #以防万一
brew install autoconf automake libtool

./autogen.sh

./configure
make
make check
sudo make install
  
 #验证,命令
protoc
  
安装go的protobuf插件
 #安装,提供golang运行protobuf的环境和go服务端源码生成功能(?)
 go get -u github.com/golang/protobuf/{proto,protoc-gen-go}
 
 #protoc-gen-go 命令需要直接能被执行到
 export PATH=$PATH:$GOPATH/bin

使用

目录结构


helloworld/helloworld.proto
此为 protobuf 的IDL,定义了rpc服务的具体内容,内容不做解释了

helloworld/helloworld.pb.go
此为根据 helloworld.proto 生成golang的protobuf定义文件,客户端服务端同时需要引入并使用

我们直接看例子,先跑起来

 #第一个例子目录
cd GOPAHT/src/google.golang.org/grpc/examples/helloworld

 #运行go 服务端
go run greeter_server/main.go
 
 #运行go 客户端
go run greeter_client/main.go haha

 #客户端返回内容,成功!
2017/10/10 01:09:24 Greeting: Hello haha
使用代码生成插件
 #修改proto文件时,需要使用命令重现生成go的protobuf依赖文件
 
protoc -I helloworld/ helloworld/helloworld.proto --go_out=plugins=grpc:helloworld
修改我们的helloworld代码

下面我们修改下helloworld代码在完整的试一试

helloworld/helloworld.proto

package helloworld;

// The greeting service definition.
service Greeter {
  // Sends a greeting
  rpc SayHello (HelloRequest) returns (HelloReply) {}
  // Sends another greeting
  
  //我们新增了 SayHelloAgain rpc 方法
  rpc SayHelloAgain (HelloRequest) returns (HelloReply) {}
}

// The request message containing the user's name.
message HelloRequest {
  string name = 1;
}

// The response message containing the greetings
message HelloReply {
  string message = 1;
}

greeter_server/main.go

type server struct{}

// SayHello implements helloworld.GreeterServer
func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
    return &pb.HelloReply{Message: "Hello " + in.Name}, nil
}

//我们对应增加了 服务端的 支持 SayHelloAgain
func (s *server) SayHelloAgain(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
        return &pb.HelloReply{Message: "Hello again " + 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)
    }
}

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]
    }
    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)
    
    //我们又加了 客户端 的调用逻辑
    r, err = c.SayHelloAgain(context.Background(), &pb.HelloRequest{Name: name})
    if err != nil {
        log.Fatalf("could not greet: %v", err)
    }
    log.Printf("Greeting: %s", r.Message)
    
}
 #使用protoc 重现生成 protobuf依赖文件  
protoc -I helloworld/ helloworld/helloworld.proto --go_out=plugins=grpc:helloworld

 #执行验证
go run greeter_client/main.go haha
 
 #返回,调用了两次rpc
2017/10/10 01:48:20 Greeting: Hello haha
2017/10/10 01:48:20 Greeting: Hello again haha

这就是gRPC初探,后面会写一篇php做为客户端使用gRPC的小文章。


参考


成长之路
围绕php, java相关程序设计与开发。

Java,源码分析,敏捷开发, PM

314 声望
58 粉丝
0 条评论
推荐阅读
[学习笔记-Java并发源码-2] volatile的实现原理
volatile这个关键字可能很多朋友都听说过,或许也都用过。在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果。在Java 5之后,volatile关键字才得以重获生机。

df007df2阅读 1.7k

Golang 中 []byte 与 string 转换
string 类型和 []byte 类型是我们编程时最常使用到的数据结构。本文将探讨两者之间的转换方式,通过分析它们之间的内在联系来拨开迷雾。

机器铃砍菜刀22阅读 55.2k评论 1

年度最佳【golang】map详解
这篇文章主要讲 map 的赋值、删除、查询、扩容的具体执行过程,仍然是从底层的角度展开。结合源码,看完本文一定会彻底明白 map 底层原理。

去去100214阅读 11.1k评论 2

年度最佳【golang】GMP调度详解
Golang最大的特色可以说是协程(goroutine)了, 协程让本来很复杂的异步编程变得简单, 让程序员不再需要面对回调地狱, 虽然现在引入了协程的语言越来越多, 但go中的协程仍然是实现的是最彻底的. 这篇文章将通过分析...

去去100213阅读 11.3k评论 4

【已结束】SegmentFault 思否技术征文丨浅谈 Go 语言框架
亲爱的开发者们:我们的 11 月技术征文如期而来,这次主题围绕 「 Go 」 语言,欢迎大家来参与分享~征文时间11 月 4 日 - 11 月 27 日 23:5911 月 28 日 18:00 前发布中奖名单参与条件新老思否作者均可参加征文...

SegmentFault思否11阅读 4.7k评论 11

封面图
【Go微服务】开发gRPC总共分三步
之前我也有写过RPC相关的文章:《 Go RPC入门指南:RPC的使用边界在哪里?如何实现跨语言调用?》,详细介绍了RPC是什么,使用边界在哪里?并且用Go和php举例,实现了跨语言调用。不了解RPC的同学建议先读这篇文...

王中阳Go8阅读 3.7k评论 6

封面图
【golang】sync.WaitGroup详解
上一期中,我们介绍了 sync.Once 如何保障 exactly once 语义,本期文章我们介绍 package sync 下的另一个工具类:sync.WaitGroup。

去去100213阅读 30.2k评论 2

Java,源码分析,敏捷开发, PM

314 声望
58 粉丝
宣传栏