GO分布式微服务-GRPC

本文详细介绍了如何使用golang实现GRPC微服务,包括GRPC和protobuf的概念、protobuf的基本用法、GRPC的安装及实践。通过示例展示了服务端和客户端的创建,以及GRPC的流模式(服务端流、客户端流、双向流)。还涉及了GRPC的证书认证、双向证书认证、token认证、截取器和验证器的使用,以及如何通过grpc gateway实现HTTPS接口。

grpc是什么?

grpc 是可以在任何环境中运行的现代开源高性能rpc 框架。它可以通过可插拔的支持来有效地连接数据中心内和跨数据中心的服务,以实现负载平衡,跟踪,运行状况检查和身份验证。grpc基于 HTTP/2 标准设计,带来诸如双向流、流控、头部压缩、单 TCP 连接上的多复用请求等特。这些特性使得其在移动设备上表现更好,更省电和节省空间占用。grpc使用protobuf来定义接口,从而实现更高更安全的接口约束。

protobuf 是什么?

protobuf 是一种语言无关、平台无关、可扩展的序列化结构数据的方法,它可用于(数据)通信协议、数据存储等。

Protocol Buffers 是一种灵活,高效,自动化机制的结构数据序列化方法-可类比 XML,但是比 XML 更小(3 ~ 10倍)、更快(20 ~ 100倍)、更为简单。

protobuf 的基础用法

传送门: protobuf 的基础用法.

了解了protobuf的基础用法之后我们也来构建一个示例
在项目中新建一个servers/prod.proto文件,写入以下代码

syntax = "proto3"; //声明其为proto3的语法。
package servers; //声明报名
option go_package = "servers/hello"; //go package 的生成位置
//这里会生成 servers/hello/prod.pd.go 文件,go文件的包为hello.

message Hello{
    string Value = 1; //存储用户名称
}

service HelloServer{
    rpc Print (Hello) returns (Hello); //GRPC服务方法
}

生成之后的文件预览,此图是为了说明option go_package 的作用。
在这里插入图片描述
我们写好代码之后,需要生成go文件了,此时我们需要用到一个grpc插件。

grpc安装

  //grpc运行时接口编解码支持库
  go get -u github.com/golang/protobuf/proto
  //从 Proto文件(gRPC接口描述文件) 生成 go文件 的编译器插件
  go get -u github.com/golang/protobuf/protoc-gen-go

安装完成之后,我们在项目中打开命令行,执行命令

protoc --go_out=plugins=grpc:./ servers/prod.proto
//proto --go_out=plugins=grpc: 输出目录 proto目录

执行之后,在servers/hello 文件下就会生成prod.pd.go 文件。

基础grpc实践

我们在之前讲过,protobuf 是为了更好的作为一个接口约束。其实这个就和我们之前RPC篇所做的接口规范是同样的道理,rpc篇中的common.go 就和我们现在生成的prod.pd.go 文件有着同样的思想,所以同样的我们针对于定义的接口要去实现他的具体方法。

由于grpc生成之后的文件会引用很多Google的包,我们直接go get会因为网络原因无法下载,可以使用 go mod init 进行包管理即可。

服务端

这里我们就创建一个 servers/hello/server.go文件来进行具体的方法实现。
1:查看方法原型,我们在prod.pd.go中直接搜索Print. 找到**Server的接口,里面约束了方法的规范,我们直接复制方法到server.go中进行实现。
在这里插入图片描述
server.go 实现示例如下

package hello

import (
	"context"
	"fmt"
)

type HelloStruct struct {
}

func (this *HelloStruct) Print(ctx context.Context, from *Hello) (*Hello, error) {
	fmt.Println(from.Value + ":hello world") //当服务端调用时打印 客户端名字+helloworld
	return &Hello{ 
		Value: "server",
	}, nil  
	//返回服务端名字
}

客户端的服务已经实现了,现在我们要用grpc的方法启动服务了。
创建main.go文件实现启动服务端,具体代码如下:

package main

import (
	"log"
	"net"
	"server/servers/hello"
	"google.golang.org/grpc"
)

func main() {
	grpcServer := grpc.NewServer()                                      //新建服务
	hello.RegisterHelloServerServer(grpcServer, new(hello.HelloStruct)) //注册服务
	listen, err := net.Listen("tcp", ":1234")                           //启动网络监听
	if err != nil {
		log.Fatal("listen tcp :1234 fail:", err)
		return
	}
	grpcServer.Serve(listen) //为网络监听提供grpc服务
}

此时服务端的目录结构为

server  服务端项目录
|—servers 	 grpc服务目录
|—|—prod.proto 	protobuf文件
|—|—hello  	hello 服务包 
|—|—|—prod.pd.go 	生成的规范条件,由grpc生成
|—|—|—server.go 	 服务接口方法的实现,用户自己实现。
|—main.go 	启动grpc服务入口文件
客户端

在RPC篇中,我们的客户端实现是将服务端中的common.go复制到客户端,然后在实现接口约束调用服务端的方法,在此我们也是一样的,但是比起我们之前,这里更简便了一些,我们只需要讲服务端生成的prod.pd.go文件复制到客户端即可,所有的客户端约束实现,他都已经帮我们做了。
接下来我们进行实操,建立client项目,再建立servers/hello 目录,我们直接将服务端的prod.pd.go文

<think>好的,用户现在让我介绍一下github.com/grpc-ecosystem/go-grpc-middleware这个包。首先,我需要回想一下之前用户的问题历史。之前他们询问了Gin框架的跨域处理,现在转到了gRPC的中间件包,可能是在构建微服务架构,需要了解如何增强gRPC的功能。 首先,用户可能正在使用gRPC进行服务间通信,但发现需要一些通用功能,比如日志记录、认证、重试机制等。这时候,他们需要中间件来统一处理这些横切关注点,而go-grpc-middleware正好提供了这样的解决方案。 接下来,我需要确定这个包的主要功能和用途。这个仓库是gRPC中间件的集合,支持拦截器链,允许开发者组合多个中间件。常见的中间件包括日志、认证、监控、限流、重试、超时等。用户可能希望了解它的核心功能、使用场景、如何集成到现有项目,以及具体的例子。 然后,我需要考虑用户可能的真实需求。他们可能对gRPC有一定的了解,但不太清楚如何高效地管理中间件,或者如何将多个中间件组合使用。可能他们遇到了代码重复的问题,或者需要统一处理一些通用逻辑,比如认证和日志记录,而不想在每个服务中重复编写代码。 此外,用户可能关心如何安装和使用这个包,是否有示例代码,以及在生产环境中需要注意什么。比如,中间件的顺序可能会影响功能,或者某些中间件需要特定的配置,如认证中间件需要与具体的认证逻辑结合。 我需要分结构来介绍这个包,先讲它的作用,再讲核心功能,比如支持的中间件类型、链式调用、与各种工具的集成。然后给出安装方法和使用示例,比如如何添加日志和认证中间件。接着,说明适用场景,比如微服务中的统一日志、API限流、重试机制等。 还要注意比较与其他中间件库的不同,可能这个包的优势在于社区支持和丰富的中间件集合。同时,注意事项部分需要强调中间件顺序的重要性,性能影响,以及生产环境的配置建议,比如启用监控和链路追踪。 最后,用户可能有更深层次的需求,比如如何自定义中间件,或者如何处理复杂的拦截器链,这些可能需要进一步解释或提供文档链接。不过根据当前问题,先覆盖基本介绍和常见使用场景,确保用户能快速上手并理解其价值。</think>--- `github.com/grpc-ecosystem/go-grpc-middleware` 是一个为 gRPC 服务提供**链式中间件**支持的 Go 语言库。它通过拦截器(Interceptor)机制,帮助开发者在 gRPC 请求处理过程中插入通用逻辑(如日志、认证、监控等),是构建企业级 gRPC 服务的核心工具之一。 --- ### **核心功能** | 功能 | 作用 | 典型中间件示例 | |-------------------|---------------------------------------------------------------------------------------|------------------------------------------------------------------------------| | **链式拦截器** | 支持同时组合多个中间件(客户端和服务端均可使用) | `ChainUnaryServer(logger, auth, retry)` | | **常用中间件** | 提供开箱即用的中间件实现 | 日志、认证、重试、超时、限流、链路追踪、恢复(Recovery)等 | | **与生态集成** | 无缝对接 Prometheus、OpenTelemetry、Zap 等工具 | `grpc_prometheus.NewServerMetrics()` 用于 Prometheus 监控 | | **流式拦截支持** | 同时支持 Unary(一元)和 Streaming(流式)RPC 的拦截 | 流式请求的日志记录和超时控制 | --- ### **安装与基础使用** ```bash go get github.com/grpc-ecosystem/go-grpc-middleware/v2 ``` #### **服务端示例**(日志 + 认证) ```go import ( "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/logging" "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/auth" ) func main() { // 创建中间件链 chain := grpc.ChainUnaryServer( logging.UnaryServerInterceptor(logger), // 日志中间件 auth.UnaryServerInterceptor(authFunc), // 认证中间件(需自定义 authFunc) ) // 启动 gRPC 服务 server := grpc.NewServer(grpc.UnaryInterceptor(chain)) pb.RegisterYourServiceServer(server, &service{}) server.Serve(lis) } ``` --- ### **典型应用场景** | 场景 | 实现方式 | |---------------------|--------------------------------------------------------------------------| | **统一请求日志** | 使用 `logging` 中间件记录 RPC 方法、耗时、状态码 | | **JWT 认证** | 通过 `auth` 中间件解析请求头中的 Token | | **自动重试** | 客户端使用 `retry` 中间件实现幂等请求的重试逻辑 | | **API 限流** | 结合 `ratelimit` 中间件限制每秒请求数 | | **错误监控** | 集成 Prometheus 中间件统计 RPC 调用次数和延迟 | --- ### **关键中间件列表** | 中间件类型 | 功能说明 | |------------------|--------------------------------------------------------------------------| | `logging` | 结构化日志记录(支持 Zap、Logrus 等日志库) | | `recovery` | 捕获 panic 防止服务崩溃 | | `validator` | 自动验证请求参数(需结合 protoc-gen-validate 使用) | | `ratelimit` | 基于令牌桶算法的限流控制 | | `retry` | 客户端自动重试(可配置重试条件和次数) | | `opentracing` | 分布式链路追踪(兼容 Jaeger、Zipkin 等) | --- ### **高级用法示例** #### **自定义中间件开发** ```go // 实现一个 Unary 拦截器(统计请求耗时) func metricsInterceptor(ctx context.Context, req any, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (any, error) { start := time.Now() resp, err := handler(ctx, req) prometheus.ObserveLatency(info.FullMethod, time.Since(start)) return resp, err } ``` #### **流式拦截器组合** ```go // 流式 RPC 中间件链 streamChain := grpc.ChainStreamServer( logging.StreamServerInterceptor(logger), recovery.StreamServerInterceptor(), ) ``` --- ### **注意事项** 1. **中间件顺序** 中间件按添加顺序执行(类似洋葱模型),例如: ```go // 执行顺序:日志 → 认证 → 业务逻辑 → 认证 → 日志 grpc.ChainUnaryServer(loggingInterceptor, authInterceptor) ``` 2. **性能影响** 避免在拦截器中执行阻塞操作(如直接访问数据库),必要时使用异步处理。 3. **生产建议** - 启用 `recovery` 中间件防止服务崩溃 - 集成 Prometheus 监控关键指标 - 使用 `validator` 确保请求参数安全 --- 通过该库,开发者可以快速构建高可观测性、高可靠性的 gRPC 微服务,同时保持代码的简洁性。其模块化设计使得功能扩展和维护成本大幅降低。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值