golang grpc

X_4655 · · 1554 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

golang grpc

rpc种类

1.支持多语言的rpc框架,例如Google的grpc,facebook thrift, 百度的brpc

2.支持特定语言的rpc框架, 例如新浪微博的Motan

3.支持服务治理微服务化特性框架,其底层仍是rpc框架,例如 阿里的Dubbo

目前业内主要使用基于多语言的 RPC 框架来构建微服务,是一种比较好的技术选择,例如netflix ,API服务编排层和后端微服务之间采用微服务rpc进行通信

grpc含义

gRPC是Google的RPC框架,开源、高性能、跨语言,基于HTTP/2通讯协议和Protocol Buffer 3数据序列化协议

    定义一个服务,指定其能够被远程调用的方法(包含参数和返回类型)。在服务端实现这个接口,并运行一个 gRPC 服务器来处理客户端调用。在客户端拥有一个存根能够像服务端一样的方法。

    直白的说就是调用的双方可以使用完全不同的两种语言来实现,分别实现client端和server端,按照约定的protobuf协议进行交互。client端会保存与server端的长连接对象或叫存根,通过这个存根可以直接调用服务端的方法。而服务端则实现了proto中指定的服务接口。

grpc 优势

1. 多语言
Grpc的多语言是他做的很牛逼的地方,特别是在设备端,客户端支持ios,android,而基于http2.0的多路复用也的确让设备真正的省了流量,省了电,也省了空间

2.基于Http2.0
采用HTTP2的好处在于,因为添加了头信息,可以方便在框架层面对调用做拦截和控制(比如说限流,调用链分析,安全认证等)而且http2为标准协议,也方便以后扩展兼容其它调用端

grpc 原理

1.gRPC消息由netty /http/2 协议负责接入,通过grpc 注册的Http2Framelister将解码后的Http header和Http body 发送到gRPC的NettyServerHandler ,实现netty http/2的消息接入

2.gRPC 的线程模型遵循 Netty 的线程分工原则,即:协议层消息的接收和编解码由 Netty 的 I/O(NioEventLoop) 线程负责;后续应用层的处理由应用线程负责,防止由于应用处理耗时而阻塞 Netty 的 I/O 线程 (因为分工原则,grpc 之间会做频繁的线程切换,如果在一次grpc调用过程中,做了多次I/O线程到应用线程之间的切换,会导致性能的下降 所以一些私有协议不太友好)

grpc 模型

异步非阻塞的线程模型

服务端线程模型主要包括
1.服务端的写入,客户端的接入线程(HTTP/2 Acceptor)
2.网络I/O的读写线程
3.服务接口调用线程

客户端线程模型主要包含
1.客户端的链接 (HTTP/2 Connector)
2.网络I/O读写线程
3.接口调用线程
4.响应回调通知线程

linux grpc 安装与使用示范

前言:
要编译proto文件生成go代码需要两个工具
    1.protoc :用于编译(其他语言只需要protoc足以)
    2.protoc-gen-go : 用于生成go语言的文件(go语言专用插件)

安装

1).安装grpc运行环境
    go get google.golang.org/grpc

2).安装protoc
    1. 去官网 (https://github.com/protocolbuffers/protobuf/releases) 下载对应的linux版本 例如我下载的protobuf-cpp-3.9.1.zip
    2.unzip protobuf-cpp-3.9.1.zip 
    3.cd protobuf-3.9.1/
    4. ./configure  // 加--prefix=/路径  指定安装位置
    5.make && make install

3).安装protoc-gen-go
    go get -v -u github.com/golang/protobuf/protoc-gen-go

    go get -v -u github.com/gogo/protobuf/gogoprot

使用

1).编写proto文件
    示例:
        //testHello.proto
        syntax = "proto3";

        package protos;

        // The service definition.
        service Devops {
            // 定义服务
            rpc SayHello (HelloRequest) returns (Response) {}
        }

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

        // The response message
        message HelloReply {
            string message = 1;
        }

        message Response {
            enum StatusCode {
                UNDEFINED = 0;
                SUCCESS = 200;
                FAILURE = 500;
            }
            StatusCode status = 1;
            HelloReply msg = 2;
        }

2).在终端自动生成pb.go
    protoc -I. --go_out=plugins=grpc:. 绝对路径/*.proto

    参数说明:

3).编写服务端
    示范:
        package main

        const (
            port = ":50051"
        )

        type myserver struct{}

        //这里myserver实现了SayHello
        func (s *myserver) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.Response, error) {
            fmt.Print("receive " + in.Name)
            return &pb.Response{
                Status:pb.Response_SUCCESS,
                Msg:&pb.HelloReply{Message:"receive " + in.Name},
            }, nil
        }

        func main() {
            //绑定端口
            lis, err := net.Listen("tcp", port)
            if err != nil{
                log.Fatal("fail to listen")
            }

            s := grpc.NewServer()
            pb.RegisterDevopsServer(s, &myserver{})
            s.Serve(lis)
        }

4).编写客户端
    package main

    const (
        address = "localhost:50051"
    )

    func main()  {
       //grpc.WithInsecure()指定后才不会报错
        conn, err := grpc.Dial(address, grpc.WithInsecure())

        if err != nil{
            log.Fatal("error....", err)
        }
        c := pb.NewDevopsClient(conn)
        res, _ := c.SayHello(context.Background(), &pb.HelloRequest{"eeee"})

        fmt.Print(res)
    }

有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:X_4655

查看原文:golang grpc

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1554 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传