goマイクロサービスのgrpcコンポーネント

grpcの使用

grpcについて知りたい場合は、まずrpcを理解してください(これらは記事の中で私自身のものであり、調査の小さなメモは詳細ではありません。詳しく知りたい場合は、Baiduをご覧ください。たくさんの情報があります。)

RPCとは何ですか?

定義:

リモートプロシージャコールプロトコルはhttp要求に似ていますが、プロトコルが異なります。ほとんどのrpcはTCPを使用し、http要求はHTTPプロトコルを使用します。

これは、単に別のノードを呼び出すノードとして理解できます。

組成:

  • クライアント:クライアント、サービスの呼び出し元。
  • クライアントスタブ:サーバーアドレス情報を格納し、クライアントのリクエストパラメータデータ情報をネットワークメッセージにパッケージ化し、ネットワーク伝送を介してサーバーに送信するクライアントスタブ
  • ネットワーク転送モジュール:TCまたはHTTPのネットワークサービス、基礎となる転送
  • サーバースタブ:サーバースタブ。クライアントから送信された要求メッセージを受信して​​アンパックし、ローカルサービスを呼び出して処理します。
  • サーバーなど:サーバーサービスの実際のプロバイダー。

実装プロセス:

  • クライアントクライアントは、ローカル呼び出しを通じてサービスを呼び出します。
  • 呼び出し要求を受信した後、クライアントスタブは、メソッドや入力パラメーターなどの情報を、ネットワーク伝送が可能なメッセージ本文にシリアル化(アセンブル)します。
  • クライアントスタブはリモートサービスアドレスを見つけ、ネットワークを介してサーバーにメッセージを送信します。
  • ネットワーク伝送
  • サーバースタブは、メッセージを受信した後にデコードします(逆シリアル化操作)。
  • サーバースタブは、デコード結果に基づいて、関連する処理のためにローカルサービスを呼び出します
  • サーバー(サーバー)ローカルサービスビジネス処理。
  • 処理結果はサーバースタブに返されます。
  • サーバースタブのシリアル化結果。
  • サーバースタブは、ネットワーク経由でコンシューマに結果を送信します。
  • クライアントスタブはメッセージを受信して​​デコードします(逆シリアル化)。
  • クライアントが最終結果を取得します。

grpcとは

定義:

  • これは、高性能でオープンソースのユニバーサルRPCフレームワークです。
  • HTTP2プロトコルがgRPCで使用されています
  • Google製品
  • gRPCはデフォルトでprotoBufを使用します

構成:rpcに類似

実行プロセス:rpcと同様

注意:

rpcとgrpcの詳細について
は、Baiduで検索してください。記事にエラーがある場合は、私に連絡してください。

rpcを実装する

サーバ:

rpc_sample/go_rpc_server.go

package main

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

type Say struct{
    
    }

/*
注意:对外暴露的服务方法定义
1、对外暴露的方法有且只能有两个参数,这两个参数只能是输出类型或内建类型,两种类型中的一种。
2、方法的第二个参数必须是指针类型。
3、方法的返回类型为error。
*/
func (s *Say) Hello(inputArg string, outputArg *string) error {
    
    
	*outputArg = "hello " + inputArg
	return nil
}

func main() {
    
    
	// new一个对象
	say := new(Say)

	// 将对象注册到rpc服务中
	rpc.Register(say)

	// 把say中的服务注册到HTTP协议上,方便调用者可以利用http的方式进行数据传递
	rpc.HandleHTTP()
	listen, err := net.Listen("tcp", "127.0.0.1:8080")
	if err != nil {
    
    
		fmt.Printf("net.Listen failed ,%v\n", err)
		return
	}

	http.Serve(listen, nil)
}

运行:go run go_rpc_server.go

クライアント:

rpc_sample/go_rpc_client.go

package main

import (
	"fmt"
	"net/rpc"
)

func main() {
    
    
	// DialHTTP:使用http去拨号,与服务端创建连接
	client, err := rpc.DialHTTP("tcp", "127.0.0.1:8080")
	if err != nil {
    
    
		fmt.Printf("rpc.DialHTTP failed ,%v\n", err)
		return
	}
	// 返回值
	var say string

	/*
		远程调用函数:被调用的方法,传入值 ,返回值
	*/
	err = client.Call("Say.Hello", "world!", &say)
	if err != nil {
    
    
		fmt.Printf("client.Call failed ,%v\n", err)
		return
	}
	fmt.Println("结果为:", say)
}
/*
结果为: hello world!
*/

go run go_rpc_client.go

grpcの使用

grpcインストール

GO111MODULE=on
GOPROXY=https://goproxy.io,direct

# 设置GO111MODULE、GOPROXY下载无压力
go get google.golang.org/[email protected]
go get google.golang.org/genproto

プロトコンテンツ定義

grpc_sample/grpc_protoBuf_sample/say_hi_sample.proto

syntax = "proto3";
option go_package = ".;hello";
package hello;
// 上面跟rpc基本一样定义

/*
	grpc + protobuf
	定义一个service类型
	SayHi暴露函数名
	可以定义多个服务,每个服务内可以定义多个接口
*/
service TestService {
  // 定义接口 (结构体可以复用)
  // 方法 (请求消息结构体) returns (返回消息结构体) {}
  //rpc 服务端对外的函数名(传入参数)returns(返回参数)
  rpc SayHi (HiRequest) returns (HiResponse){}
}

// 定义HiRequest消息结构
message HiRequest {
  string name = 1;
}

// 定义HiResponse消息结构
message HiResponse {
  string ret = 1;
}

protoはgo言語ファイル(grpc)を生成します

注:grpcはgrpcプラグインを使用します

# 直接到say_hi_sample.proto文件目录执行
protoc --go_out=plugins=grpc:. say_hi_sample.proto

# 会生成say_hi_sample.pb.go文件

grpcサーバー(サーバー)

grpc_sample/go_grpc_server.go

package main

import (
	"context"
	"fmt"
	"google.golang.org/grpc"
	"net"
	hello "sample/grpc_sample/grpc_protoBuf_sample"
)

type Server struct{
    
    } //服务对象

/*
	SayHi实现在proto中定义的TestServiceServer interface接口
	
	type TestServiceServer interface {
	//rpc 服务端对外的函数名(传入参数)returns(返回参数)
	SayHi(context.Context, *HiRequest) (*HiResponse, error)
	}
	
	TestServiceServer接口是如何来的?
	1.grpc_sample/grpc_protoBuf_sample/say_hi_sample.proto
	  proto文件中定义service类型的名为:TestService

	2.proto转成go文件就会生成2个接口:
    生成规律也很明显,就是proto文件中定义service类型的名后面加Client、Server
		TestServiceClient
		TestServiceServer
		看名称很明显肯定关于客户端、服务端
*/
func (s *Server) SayHi(ctx context.Context, in *hello.HiRequest) (*hello.HiResponse, error) {
    
    
	res := &hello.HiResponse{
    
    Ret: "hello " + in.Name}
	return res, nil
}

// name  -->   "hello name"
func main() {
    
    
	// 创建grpc服务
	server := grpc.NewServer()

	/*
		**注册接口服务:
		 * 以定义proto时的service为单位注册,服务中可以有多个方法
		 * (proto编译时会为每个service生成Register***Server方法)
		 * 包.注册服务方法(gRpc服务实例,包含接口方法的结构体[指针])
			hello.RegisterTestServiceServer
			grpc注册服务:
				1.hello是包名
				2.RegisterTestServiceServer注册服务一个方法
			RegisterTestServiceServer:
				1.参数一:grpc服务
				2.参数二:服务对象
	*/
	hello.RegisterTestServiceServer(server, &Server{
    
    })

	listen, err := net.Listen("tcp", "127.0.0.1:8080")
	if err != nil {
    
    
		fmt.Printf("监听失败: %v\n", err)
	}
	fmt.Println("监听8080端口...")

	// 用grpc服务启动
	server.Serve(listen)
}

运行:go run go_grpc_server.go

grpc client(クライアント)

grpc_sample/go_grpc_client.go

package main

import (
	"context"
	"fmt"
	"google.golang.org/grpc"
	hello "sample/grpc_sample/grpc_protoBuf_sample"
)

func main() {
    
    
	/*
		**建立连接到gRPC服务:
		 * WithInsecure:跳过证书的验证
	*/
	conn, err := grpc.Dial("127.0.0.1:8080", grpc.WithInsecure())
	if err != nil {
    
    
		fmt.Printf("grpc.Dial failed, :%v\n", err)
	}

	// 结束时关闭连接
	defer conn.Close()

	// 创建TestService服务的客户端
	client := hello.NewTestServiceClient(conn)

	// 调用gRPC接口
	rep, err1 := client.SayHi(context.Background(), &hello.HiRequest{
    
    Name: "world!"})
	if err1 != nil {
    
    
		fmt.Printf("client.SayHi failed, :%v\n", err1)
		return
	}
	fmt.Println(rep.Ret)
}

/* 运行结果:
hello wrold!
*/

运行:go run go_grpc_client.go

注意:

开启go module
用GoLand创建项目会有个go.mod,没有go mod init。详细go mod自行百度
grpc演示中hello "sample/grpc_sample/grpc_protoBuf_sample"
我这个go.mod中module sample是sample,引入同项目不同目录下包就是sample/...
后面使用micro会使用go module导入不同项目下包。前面先了解下,大神可以略过。

再次说明:这些都是我自己学习过程中小笔记,如有错误望告知。还有就是一些相关介绍少,想详细了解请自行百度。

おすすめ

転載: blog.csdn.net/Maggie_up/article/details/108702287