記事ディレクトリ
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导入不同项目下包。前面先了解下,大神可以略过。
再次说明:这些都是我自己学习过程中小笔记,如有错误望告知。还有就是一些相关介绍少,想详细了解请自行百度。