网站首页 > 博客文章 正文
1.本节知识点
- 了解gRPC与gRPC-Gateway
- 了解buf
- proto文件配置
- 代码演示
2. 了解gRPC与gRPC-Gateway
gRPC: gRPC(gRPC Remote Procedure Calls)是由Google开发的开源RPC(远程过程调用)框架,它使用Protocol Buffers作为接口定义语言。
gRPC特点
- 基于HTTP/2: gRPC使用HTTP/2作为传输协议,提供了低延迟、多路复用和流控制等特性。HTTP/2相较于旧版本的HTTP,更加高效和性能更好。
- 多语言支持: gRPC支持多种编程语言,包括但不限于C, C++, Java, Python, Go, Ruby,以及其他一些语言。
- IDL(接口定义语言): 使用Protocol Buffers(ProtoBuf)作为接口定义语言,这使得定义服务和消息变得简单、清晰,并且具有很好的可读性。
- 双向流和流控制: gRPC支持双向流通信,服务端和客户端可以同时发送多个消息。同时,它还提供了流控制机制,允许客户端和服务器以可控制的方式进行通信。
- 自动代码生成: 根据服务和消息的ProtoBuf定义,gRPC可以生成用于不同编程语言的客户端和服务器端的代码,这样可以在不同的语言中无缝调用gRPC服务。
- 支持拦截器: gRPC允许使用拦截器(Interceptors)来处理请求和响应。这使得可以在请求和响应的不同阶段进行自定义处理。
- 跨语言、跨平台: 由于使用了标准的ProtoBuf和HTTP/2,gRPC可以在不同语言和平台之间进行通信,使得各种系统和服务能够协同工作。
gRPC-Gateway: 是一个用于将 gRPC 服务转换为 RESTful JSON API 的代理工具,使得可以通过HTTP/JSON 访问原本基于 gRPC 的服务
gRPC-Gateway特点
- RESTful JSON API: gRPC-Gateway 提供了一种将 gRPC 服务转换为 RESTful JSON API 的方法。这样可以方便地与不支持 gRPC 的客户端进行通信。
- 自动生成: gRPC-Gateway 使用 Protocol Buffers 文件中的 gRPC 服务定义,并通过代码生成的方式创建反向代理。这意味着你可以专注于定义 gRPC 服务,而无需手动编写 HTTP 接口。
- 基于 HTTP/JSON: 通过 gRPC-Gateway,你可以使用 HTTP/JSON 协议而不是 gRPC 协议来与服务进行通信。这对于与一些仅支持 HTTP/JSON 的工具和框架进行集成非常有用。
- Swagger 文档生成: gRPC-Gateway 支持生成 Swagger 文档,使得你可以轻松地了解和测试你的 API。
- 多语言支持: gRPC-Gateway 支持多种编程语言,因此你可以在多种语言中使用 gRPC 服务,同时提供 HTTP/JSON 接口。
- 反向代理服务: gRPC-Gateway 充当 gRPC 服务的反向代理,将 HTTP 请求转发到对应的 gRPC 服务,并将 gRPC 响应转换为 HTTP 响应。
3. 了 解buf工具
buf 是一个用于 Protocol Buffers 的构建和 lint 工具。它提供了一种规范和一致性的方式来管理 Protocol Buffers 文件
4. 步骤说明(有代码)
- 安装 工具过程 省略, 自行网络搜索安装吧
- 编写demo.proto文件,代码如下
syntax = "proto3";
//proto的包名
package demo;
//生成go文件的包名
option go_package="/gen;demobp";
message Request {
string name = 1;
}
message Response {
string message = 1;
}
service HelloService {
rpc SayHello(Request) returns (Response) {
}
}
- 创建一个buf.gen.yaml文件,用于buf工具
version: v1
plugins:
#插件
- plugin: go
#输出到指定当前路径的指定目录
out: gen
opt:
- paths=source_relative
- plugin: go-grpc
out: gen
opt:
- paths=source_relative
- plugin: grpc-gateway
out: gen
opt:
- paths=source_relative
- generate_unbound_methods=true
#gateway要依赖的自定义url的yaml文件
- grpc_api_configuration=demo.yaml
- 创建一个demo.yaml文件,用于存放grpc-gateway自己定义url
type: google.aip.Service
config_version: 3
http:
#路由规则 demo.HelloService.SayHello 第一部分demo 这里对应着是 demo.proto文件里定义的包名 package demo; 如果改为package demo1;则selector 也要改成相应的demo1.HelloService.SayHello才可以 ,第二部分HelloService 是服务名,第三部分SayHello 是服务的方法名
#参数中的{name} 要和demo.proto中的message中Request中的name相同
rules:
- selector: demo.HelloService.SayHello
get: /v1/hello/{name}
body:"*"
- 执行 buf命令
#说明: 如果不加参数,需要与buf.gen.yaml在同一个目录下执行,否则要使用参数指定配置文件才可以
buf generate
- 目录结构如下
demo
├── bp
│ ├── buf.gen.yaml
│ ├── demo.proto
│ ├── demo.yaml
│ ├── gen
│ │ ├── demo.pb.go
│ │ ├── demo.pb.gw.go
│ │ └── demo_grpc.pb.go
│ └── genpb.sh
├── client
│ └── main.go
├── go.mod
├── go.sum
├── gw
│ └── main.go
└── server
└── main.go
5. 编写 go代码(只是用来演示使用,代码质量差)
- service端
package main
import (
bp "bpdemo/bp/gen"
"context"
"google.golang.org/grpc"
"log"
"net"
)
type server struct {
//必须有,向下兼容的处理
bp.UnimplementedHelloServiceServer
}
func (s *server) SayHello(ctx context.Context, req *bp.Request) (*bp.Response, error) {
return &bp.Response{Message: "Hello " + req.Name}, nil
}
func main() {
lis, err := net.Listen("tcp", ":8080")
if err != nil {
panic(err)
}
s := grpc.NewServer()
bp.RegisterHelloServiceServer(s, &server{})
if err := s.Serve(lis); err != nil {
log.Fatalf("faild to server %v", err)
}
}
- gateway端
package main
import (
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
"google.golang.org/grpc"
demobp "bpdemo/bp/gen"
"context"
"fmt"
"net/http"
)
func main() {
ctx := context.Background()
ctx, cancelFunc := context.WithCancel(ctx)
defer cancelFunc()
//自定义服务
mux := runtime.NewServeMux()
err := demobp.RegisterHelloServiceHandlerFromEndpoint(ctx, mux, "127.0.0.1:8080", []grpc.DialOption{grpc.WithInsecure()})
if err != nil {
panic(err)
}
err = http.ListenAndServe(":9090", mux)
fmt.Println(err)
}
- client端
package main
import (
bp "bpdemo/bp/gen"
"context"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
"log"
"time"
)
func main() {
conn, err := grpc.Dial("localhost:8080", grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
panic(err)
}
defer conn.Close()
c := bp.NewHelloServiceClient(conn)
ctx, cancelFunc := context.WithTimeout(context.Background(), 10*time.Second)
defer cancelFunc()
r, err := c.SayHello(ctx, &bp.Request{Name: "hello"})
if err != nil {
log.Fatalf("get name err: %v", err)
}
log.Printf("收到内容:%v", r.GetMessage())
}
- 测试
- curl http://localhost:9090/v1/hello/123
#返回数据
{"message":"Hello 123"}
猜你喜欢
- 2024-10-16 Spring Boot集成grpc快速入门demo
- 2024-10-16 如何在 Go 中使用 gRPC?(golang grpc etcd)
- 2024-10-16 gRPC 1.34.0 发布,高性能 RPC 框架
- 2024-10-16 gRPC入坑记(grpc教程 go)
- 2024-10-16 凌鲨(linksaas)的客户端架构(凌肖 鲨鱼)
- 2024-10-16 Python gRPC 入门(grpc python asyncio)
- 2024-10-16 纯干货:微服务开发手册之GRPC(微服务开发入门)
- 2024-10-16 gRPC学习记录(一) 概念性知识(grpc特点)
- 2024-10-16 GRPC-C++源码分析(六)--Server-Register
- 2024-10-16 漫谈gRPC:Google自研的rpc框架(grpc go-micro)
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- powershellfor (55)
- messagesource (56)
- aspose.pdf破解版 (56)
- promise.race (63)
- 2019cad序列号和密钥激活码 (62)
- window.performance (66)
- qt删除文件夹 (72)
- mysqlcaching_sha2_password (64)
- ubuntu升级gcc (58)
- nacos启动失败 (64)
- ssh-add (70)
- jwt漏洞 (58)
- macos14下载 (58)
- yarnnode (62)
- abstractqueuedsynchronizer (64)
- source~/.bashrc没有那个文件或目录 (65)
- springboot整合activiti工作流 (70)
- jmeter插件下载 (61)
- 抓包分析 (60)
- idea创建mavenweb项目 (65)
- vue回到顶部 (57)
- qcombobox样式表 (68)
- vue数组concat (56)
- tomcatundertow (58)
- pastemac (61)
本文暂时没有评论,来添加一个吧(●'◡'●)