GRPC简介

GRPC简介

在了解GRPC之前,先了解RPC:

RPC

RPC(Remote Procedure Call Protocol)——远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。

简单来说,就是跟远程访问或者web请求差不多,都是一个client向远端服务器请求服务返回结果,但是web请求使用的网络协议是http高层协议,而rpc所使用的协议多为TCP,是网络层协议,减少了信息的包装,加快了处理速度。

golang本身有rpc包,可以方便的使用,来构建自己的rpc服务,下边是一个简单是实例,可以加深我们的理解:

流程

GRPC简介_第1张图片

1.调用客户端句柄;执行传送参数

2.调用本地系统内核发送网络消息

3.消息传送到远程主机

4.服务器句柄得到消息并取得参数

5.执行远程过程

6.执行的过程将结果返回服务器句柄

7.服务器句柄返回结果,调用远程系统内核

8.消息传回本地主机

9.客户句柄由内核接收消息

10.客户接收句柄返回的数据

服务端

注意:

  • 方法是导出的

  • 方法有两个参数,都是导出类型或内建类型

  • 方法的第二个参数是指针

  • 方法只有一个error接口类型的返回值

方法样式:

func (t *T) MethodName(argType T1, replyType *T2) error

package main

import (
	"net/rpc"
	"net"
	"net/http"
	"fmt"
)

type Panda struct {
}

func (this *Panda)GetAdd(In int ,Out *int)error{
	*Out = In +10000
	return nil
}

func main() {

	//结构体实例化
	pd :=new(Panda)
	//注册服务
	//Register在默认服务中注册并公布 接收服务 pd对象 的方法
	rpc.Register(pd)
	//rpc网络
	rpc.HandleHTTP()
	//建立网络监听
	listener , err :=net.Listen("tcp","127.0.0.1:22306")
	if err != nil{
		fmt.Println("网络错误",err)
	}

	//等待网络连接
	http.Serve(listener,nil)

}
客户端
package main

import (
	"net/rpc"
	"fmt"
)

func main() {

//	1连接服务器
	cli ,err :=rpc.DialHTTP("tcp","127.0.0.1:22306")
	if err!=nil{
		fmt.Println("连接服务器失败",err)
		return
	}

//	2调用函数
//接受变量
	var size int
//call(服务器的方法 , 传入参数 ,返回参数)
//Call(serviceMethod string, args interface{}, reply interface{})
	err = cli.Call("Panda.GetAdd",12345 ,&size)
	if err!=nil{
		fmt.Println("方法调用失败",err)
		return
	}
//	3打印结果
	fmt.Println("得到计算结果为",size)
}

GRPC

gRPC 是一个高性能、开源和通用的 RPC 框架,面向移动和 HTTP/2 设计。

gRPC基于 HTTP/2标准设计,带来诸如双向流、流控、头部压缩、单 TCP连接上的多复用请求等特。这些特性使得其在移动设备上表现更好,更省电和节省空间占用。

gRPC默认使用protoBuf

GRPC理念:

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

1.golang标准库的扩展包:

由于 go官网进不去,所以 我们需要的一些扩展包不能够 通过 go get 直接进行获取 ,可以通过go语言在github的地址 进行获取内容 https://github.com/golang

git clone 对应的内容地址 就可以

2.grpc包:

https://github.com/grpc/grpc-go

go语言实现GRPC远程调用
定义服务

如果想要将消息类型用在RPC(远程方法调用)系统中,可以在.proto文件中定义一个RPC服务接口,protocol buffer编译器将会根据所选择的不同语言生成服务接口代码及存根。如,想要定义一个RPC服务并具有一个方法,该方法能够接收 SearchRequest并返回一个SearchResponse,此时可以在.proto文件中进行如下定义:

service SearchService {
	//rpc 服务的函数名 (传入参数)返回(返回参数)
  rpc Search (SearchRequest) returns (SearchResponse);
}

在当前文件下,编译 .proto文件

$ protoc --go_out=./ *.proto #不加grpc插件
$ protoc --go_out=plugins=grpc:./ *.proto #添加grpc插件
#对比发现内容增加
#得到 helloServer.pb.go文件 
案例

.proto文件

// 版本
syntax = "proto3" ;

//包名
package myproto ;

//服务
service Hello {
    // 加法
    rpc GetAdd(In)returns(Out); //不能写注释
}

//传入

message In{
    //num
    int64 num = 1 ; //不能写注释
}

//传出

message Out{
    //size
    int64 size =1 ;//不能写注释
}

服务端

package main

import (
	"context"
	pb "0609/grpc/myproto"
	"net"
	"fmt"
	"google.golang.org/grpc"
)

//1 结构体
type Panda struct {
}

//2 结构体的方法
func (this *Panda ) GetAdd(ctx context.Context, in *pb.In) ( *pb.Out, error){
	return &pb.Out{Size:10086+in.Num} ,nil
}

func main() {

//	3 创建网络
	ln ,err :=net.Listen("tcp","127.0.0.1:12580")
	if err!=nil{
		fmt.Println("网络连接失败 ",err)
		return
	}
	defer  ln.Close()

//	4 创建grpc句柄
	srv :=grpc.NewServer()

//	5 将grpc 句柄和 结构体注册
	pb.RegisterHelloServer(srv ,&Panda{})

// 	6 等待网络连接
	err =srv.Serve(ln)
	if err!=nil{
		fmt.Println("连接失败 ",err)
		return
	}
}

客户端

package main

import (
	"google.golang.org/grpc"
	"fmt"
	pb "0609/grpc/myproto"
	"context"
)

func main() {
//	1 连接服务端
	conn ,err :=grpc.Dial("127.0.0.1:12580",grpc.WithInsecure())
	if err!=nil{
		fmt.Println("网络连接失败 ",err)
		return
	}
	defer  conn.Close()

//	2 创建客户端句柄
	cli :=pb.NewHelloClient(conn)

//	3 调用函数
	out ,err :=cli.GetAdd(context.Background(),&pb.In{Num:12345})
	if err!=nil{
		fmt.Println("函数调用失败 ",err)
		return
	}

//	4打印结果
	fmt.Println("计算结果为:",out.Size)
}

你可能感兴趣的:(微服务)