window下golang使用gRPC入门案例

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了window下golang使用gRPC入门案例相关的知识,希望对你有一定的参考价值。

gRPC是google开源高性能分布式RPC框架,支持http/2 双向数据流传输及Protobuff,可以在任何环境下运行。 它可以有效地将数据中心内和跨数据中心的服务与可插拔支持进行负载均衡,跟踪,运行状况检查和身份验证。 它也适用于分布式计算,将设备,移动应用程序和浏览器连接到后端服务。

核心功能:

  1. 10种语言的语言客户端库
  2. 高效的线路和简单的服务定义框架
  3. 基于http / 2传输的双向流式传输
  4. 可插入的身份验证,跟踪,负载平衡和健康检查

主要使用场景:

  1. 在微服务式架构中有效地连接多点服务
  2. 将移动设备,浏览器客户端连接到后端服务
  3. 生成高效的客户端库

可以参考gRPC官方文档 https://grpc.io/docs/
官方支持的语言一览:

RPC的框架还有 facebook的Thrift、阿里的Dubbo、rpcx等,可以自行百度查看资料。提供2篇关于rpc框架性能测试的文章
分布式RPC框架性能大比拼 http://colobu.com/2016/09/05/benchmarks-of-popular-rpc-frameworks/
开源RPC(gRPC/Thrift)框架性能评测 https://www.cnblogs.com/softidea/p/7232035.html

一、检查golang的安装环境

https://golang.org/dl/ 需要墙,或者在这里下载 https://pan.baidu.com/s/12tTmrVIel6sfeBInpt9lQA 最新版本1.10 下载msi安装即可
window下go version 验证安装

二、安装、配置ProtoBuff

  1. 下载protoc-3.5.1-win32.zip 解压,配置环境变量 https://github.com/google/protobuf/releases
  2. window下验证安装
  3. 安装Go语言的protoc插件
go get -u github.com/golang/protobuf/protoc-gen-go

会在GOPATH下Bin目录编译生成protoc-gen-go.exe

三、下载gRPC

注意 :官方文档里的使用 go get -u google.golang.org/grpc 下载,实际情况即使用梯子貌似也下载不了
而且在github里gRPC貌似也已经按照语言来分开了,如图:

下载最新版本 https://github.com/grpc/grpc-go/releases 最新版本是 grpc-go-1.11.1.zip 解压到%GOPATH%下google.golang.org/grpc文件夹,如图:
PS: 不能直接 import github的地址,由于历史原因(grpc内部代码还是用的google.golang.org)和golang的包管理机制不健全

四、官方的grpc示例程序

1.server服务端
package main

import (
	"log"
	"net"

	"golang.org/x/net/context"
	"google.golang.org/grpc"
	pb "google.golang.org/grpc/examples/helloworld/helloworld"
	"google.golang.org/grpc/reflection"
)

const (
	port = ":50051"
)

type server struct{}

// SayHello implements helloworld.GreeterServer 
func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
	return &pb.HelloReply{Message: "hi,你好 " + 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)
	}
}

如果运行报错 cannot find package "golang.org/x/text/secure/bidirule"、cannot find package "golang.org/x/text/unicode/norm"
下载代码 https://github.com/golang/text 复制到%GOPATH%/src/golang.org/x/text文件夹下。
如果运行报错 cannot find package "google.golang.org/genproto/googleapis/rpc/status"
下载代码 https://github.com/google/go-genproto 复制到%GOPATH%/src/google.golang.org/genproto文件夹下。

官方的server/client源代码地址:https://github.com/grpc/grpc-go/tree/master/examples/helloworld
案例server源代码地址:https://github.com/nickchou/grpc-go

2.client客户端

grpc客户端,这里我们重新建一个.Net Core的项目(参考官网的 C#版本)
官方C# 版本的服务器、客户端代码:https://github.com/grpc/grpc/tree/master/examples/csharp/helloworld
新做的.Net Core 客户端,完整代码:https://github.com/nickchou/grpc-netcore
客户端代码如下

using System;
using Grpc.Core;
using Helloworld;

namespace Core.Client
{
    class Program
    {
        static void Main(string[] args)
        {
            //创建一个长连接的channel(不加密、不安全的)
            Channel channel = new Channel("127.0.0.1:50051", ChannelCredentials.Insecure);
            
            var client = new Greeter.GreeterClient(channel);
            String user = "zhangsan";

            var reply = client.SayHello(new HelloRequest { Name = user });
            Console.WriteLine("Greeting: " + reply.Message);

            channel.ShutdownAsync().Wait();
            Console.WriteLine("Press any key to exit...");
            Console.ReadKey();
        }
    }
}

1.上图右侧解决方案Greeter类库中的Helloworld.cs和HelloworldGrpc.cs 是generate_protos.bat 根据protos/helloworld.proto的定义用grpc.tools里的protoc.exe来生成的
2.注意右侧解决方案中的Nuget引用,grpc.tools实际也是Nuget引用但是.Net Core不像C#一样拉组件dll文件在package目录下,而是一个window账户的公共目录,所以是从公共目录中复制在解决方案里,方便根据bat批处理来生成文件。

protos/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;
}

批处理generate_protos.bat的代码如下,由于是net core用所以改了部分

setlocal

@rem enter this directory
cd /d %~dp0

set TOOLS_PATH=grpc.tools\\1.10.0\\tools\\windows_x86

%TOOLS_PATH%\\protoc.exe -I protos --csharp_out Greeter  protos/helloworld.proto --grpc_out Greeter --plugin=protoc-gen-grpc=%TOOLS_PATH%\\grpc_csharp_plugin.exe

endlocal


pause
3.执行结果


总结:
1、感觉c#客户端的还是比较麻烦,如果服务端要给客户端调用还是建议直接Greeter类库打包成DLL组件放Nuget给客户端调用会更方便一些,不要让调用方去生成grpc调用类
2、golang服务端主要是因为各种包管理配置比较复杂,后面重新整理下更好的golang的包管理方法
3、golang服务端总体代码来看还是比较简单方便,grpc虽然不是性能最高的,但是基于http2的应用总体感觉还是足够了。
4、仅供学习参考用 ,基于golang和c#的server/client 官方源代码里都有,可自行测试

以上是关于window下golang使用gRPC入门案例的主要内容,如果未能解决你的问题,请参考以下文章

gRPC最佳入门教程,Golang/Python/PHP多语言讲解

Go 中的 gRPC 入门详解

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

一个简单的案例入门 gRPC

一个简单的案例入门 gRPC

Go GRPC 入门