GRPC是google开源的一个高性能、跨语言的RPC框架,基于HTTP2协议,基于protobuf 3.x,基于Netty 4.x。

前面写过一篇golang标准库的rpc包的用法,这篇文章接着讲一下google的grpc。

介绍

在 gRPC 里客户端应用可以像调用本地对象一样直接调用另一台不同的机器上服务端应用的方法,使得您能够更容易地创建分布式应用和服务。

使用grpc的优点很多,支持多种语言,二进制的数据可以加快传输速度,基于http2的多路复用可以减少服务之间的连接次数,和函数一样的调用方式也有效的提升了开发效率。

grpc提供有go版本,下面介绍一下grpc在golang中的使用。

安装

grpc支持1.5及以上版本。

用以下命令安装grpc-go:

go get google.golang.org/grpc

安装Protocol Buffers v3

https://github.com/google/protobuf/releases下载最新的稳定的版本,然后解压缩,把里面的文件放到$PATH中。

安装插件

go get -u github.com/golang/protobuf/{proto,protoc-gen-go}

别忘了将$GOPATH/bin添加到$PATH中:

export PATH=$PATH:$GOPATH/bin

示例

示例代码获取地址:https://github.com/andyidea/go-example

代码文件结构如下

├── bin
│   ├── grpc-client
│   └── grpc-server
└── src
└── grpc-helloworld
├── greeter_client
│   └── main.go
├── greeter_server
│   └── main.go
└── helloworld
├── helloworld.pb.go
└── helloworld.proto

grpc-helloworld里有三个包,greeter_client是客户端代码,greeter_server是服务端代码,helloworld是协议文件。

先看下协议。

helloworld.proto

syntax = "proto3";

option java_multiple_files = true;
option java_package = "io.grpc.examples.helloworld";
option java_outer_classname = "HelloWorldProto"; 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 greetings
message HelloReply {
string message = 1;
}

协议中定义了两个结构体HelloRequest和HelloReply,还有一个函数SayHello,函数的参数是HelloRequest,返回HelloReply。

src/下用下面命令生成协议的go文件:

protoc -I helloworld/ helloworld/helloworld.proto --go_out=plugins=grpc:helloworld

这样就生成了helloworld.pb.go协议文件。

接着我们看下服务器端的代码:

package main

import (
"log"
"net" "golang.org/x/net/context"
"google.golang.org/grpc"
pb "grpc-helloworld/helloworld"
"google.golang.org/grpc/reflection"
) const (
port = ":50051"
) // server is used to implement helloworld.GreeterServer.
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
} 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)
}
}

服务器端主要逻辑就是实现之前协议中的SayHello方法,这里是将字符串Hello和参数拼接在一起返回。

协议生成的go文件给了一个RegisterGreeterServer方法,我们用这个方法绑定实现函数的结构体和server。

然后是客户端代码:

package main

import (
"log"
"os" "golang.org/x/net/context"
"google.golang.org/grpc"
pb "grpc-helloworld/helloworld"
) 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]
}
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)
}

客户端的思路也很清晰,建立一个rpc客户端连接,将这个连接用pb.NewGreeterClient和协议绑定,返回一个client对象,用这个对象就可以调用远程的函数了。

调用输出如下:

Greeting: Hello world

示例到此结束。示例代码获取地址:https://github.com/andyidea/go-example

google的grpc在golang中的使用的更多相关文章

  1. python golang中grpc 使用示例代码详解

    python 1.使用前准备,安装这三个库 pip install grpcio pip install protobuf pip install grpcio_tools 2.建立一个proto文件 ...

  2. golang中的rpc包用法

    RPC,即 Remote Procedure Call(远程过程调用),说得通俗一点就是:调用远程计算机上的服务,就像调用本地服务一样. 我所在公司的项目是采用基于Restful的微服务架构,随着微服 ...

  3. Go语言入门篇-gRPC基于golang & java简单实现

    一.什么是RPC 1.简介: RPC:Remote Procedure Call,远程过程调用.简单来说就是两个进程之间的数据交互. 正常服务端的接口服务是提供给用户端(在Web开发中就是浏览器)或者 ...

  4. Golang中的坑二

    Golang中的坑二 for ...range 最近两周用Golang做项目,编写web服务,两周时间写了大概五千行代码(业务代码加单元测试用例代码).用Go的感觉很爽,编码效率高,运行效率也不错,用 ...

  5. Golang中设置函数默认参数的优雅实现

    在Golang中,我们经常碰到要设置一个函数的默认值,或者说我定义了参数值,但是又不想传递值,这个在python或php一类的语言中很好实现,但Golang中好像这种方法又不行.今天在看Grpc源码时 ...

  6. Golang中如何正确的使用sarama包操作Kafka?

    Golang中如何正确的使用sarama包操作Kafka? 一.背景 在一些业务系统中,模块之间通过引入Kafka解藕,拿IM举例(图来源): 用户A给B发送消息,msg_gateway收到消息后,投 ...

  7. golang中的rpc开发

    golang中实现RPC非常简单,官方提供了封装好的库,还有一些第三方的库 golang官方的net/rpc库使用encoding/gob进行编解码,支持tcp和http数据传输方式,由于其他语言不支 ...

  8. golang中的标准库context解读

    简介 golang 中的创建一个新的 goroutine , 并不会返回像c语言类似的pid,所有我们不能从外部杀死某个goroutine,所有我就得让它自己结束,之前我们用 channel + se ...

  9. golang中的反射reflect详解

    先重复一遍反射三定律: 1.反射可以将"接口类型变量"转换为"反射类型对象". 2.反射可以将"反射类型对象"转换为"接口类型变量 ...

随机推荐

  1. Java设计模式总汇二(小白也要飞)

    PS:上一篇我介绍了适配器设计模式.单例设计模式.静态代理设计模式.简单工厂设计模式,如果没有看过第一篇的小火鸡可以点这个看看http://www.cnblogs.com/cmusketeer/p/8 ...

  2. Percona XtraBackup 核心文档

    1. 介绍 1.1 MySQL 备份工具特性对比 Features Percona XtraBackup MySQL Enterprise backup License GPL Proprietary ...

  3. Django--权限组件

    创建组件 需求分析: 创建独立app, rbac ##注意: app创建后需要注册到setting.py中 INSTALLED_APPS = [ 'django.contrib.admin', 'dj ...

  4. 原生js选项卡

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. 七牛php-sdk使用-多媒体处理

    在七牛对象存储可以创建公共的bucket和私有的bucket,私有的不可以直接使用域名加资源key的方式进行访问,需要附加下载凭证. 私有bucket 关于下载凭证的生成,php-sdk已经提供了方法 ...

  6. HDU 2296:Ring

    Problem Description For the hope of a forever love, Steven is planning to send a ring to Jane with a ...

  7. [bzoj1692] [Usaco2007 Dec]队列变换 (hash||暴力)

    本题同bzoj1640...双倍经验双倍幸福 虽然数据范围n=3w然而O(n²)毫无压力= = http://blog.csdn.net/xueyifan1993/article/details/77 ...

  8. codeforces A. Orchestra B. Island Puzzle

    A. Orchestra time limit per test 2 seconds memory limit per test 256 megabytes input standard input ...

  9. Exponentiation(java 大实数)

    http://acm.hdu.edu.cn/showproblem.php?pid=1063 Exponentiation Time Limit: 2000/500 MS (Java/Others)  ...

  10. python面向对象进阶

    前言 上节大话python面向对象对面向对象有了一些了解,这次就不用大话风格了 (ps:真心不好扯啊) isinstance与issubclass isinstance(obj,cls)检查是否obj ...