Go语言零到一:gRPC(远程过程调用)
ccwgpt 2025-07-14 12:53 1 浏览 0 评论
引言
gRPC 是 Google 基于HTTP/2 协议开发的一个高性能的 RPC 框架,它使用 Protocol Buffers 作为接口定义语言,并支持多种语言。gRPC 提供了丰富的功能,如双向流式通信、消息压缩、身份验证等。
1. 准备
- 安装 gRPC 必要的工具和依赖项:
go install google.golang.org/grpc/cmd/protoc-gen-go@latest
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
- 新建文件夹grpc,cd ./grpc执行go mod init grpc初始化模块管理文件
- 项目文件结构:
└─grpc
| go.mod
| go.sum
+---arith
| arith.pb.go
| arith_grpc.pb.go
+---client
| main.go
+---proto_file
| arith.proto
\---server
main.go
2. 定义 gRPC 服务
首先,定义一个 .proto 文件来描述服务接口。
2.1 .proto 文件
创建一个名为 arith.proto 的文件:
syntax = "proto3";
package arith;
option go_package = "../arith";
service Arithmetic {
rpc Add (AddRequest) returns (AddResponse) {};
rpc StreamSum (stream SumRequest) returns (stream SumResponse) {};
}
message AddRequest {
int32 a = 1;
int32 b = 2;
}
message AddResponse {
int32 result = 1;
}
message SumRequest {
int32 number = 1;
}
message SumResponse {
int32 result = 1;
}
// protoc --go_out=. --go-grpc_out=. .\arith.proto
2.2 生成 Go 代码
进入 proto_file 目录,使用 protoc 编译器生成 Go 代码:
protoc --go_out=. --go-grpc_out=. .\arith.proto
这将生成两个文件:arith.pb.go 和 arith_grpc.pb.go。
3. 实现 gRPC 服务端
package main
import (
"context"
pb "grpc/arith"
"log"
"net"
"google.golang.org/grpc"
"google.golang.org/grpc/reflection"
)
type server struct {
pb.UnimplementedArithmeticServer
}
func (*server) Add(ctx context.Context, req *pb.AddRequest) (*pb.AddResponse, error) {
result := req.GetA() + req.GetB()
return &pb.AddResponse{Result: result}, nil
}
func (*server) StreamSum(stream pb.Arithmetic_StreamSumServer) error {
sum := int32(0)
for {
req, err := stream.Recv()
if err != nil {
return err
}
sum += req.GetNumber()
if err := stream.Send(&pb.SumResponse{Result: sum}); err != nil {
return err
}
}
}
func main() {
lis, err := net.Listen("tcp", ":8086")
if err != nil {
log.Fatalf("failed to listen: %v", err)
}
s := grpc.NewServer()
pb.RegisterArithmeticServer(s, &server{})
reflection.Register(s) // Enable reflection for development
log.Println("Starting gRPC server on :8086...")
if err = s.Serve(lis); err != nil {
log.Fatalf("failed to serve: %v", err)
}
}
4. 实现 gRPC 客户端
package main
import (
"context"
pb "grpc/arith"
"log"
"time"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
)
func main() {
conn, err := grpc.NewClient(":8086", grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
log.Fatalf("did not connect: %v", err)
}
defer conn.Close()
client := pb.NewArithmeticClient(conn)
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
resp, err := client.Add(ctx, &pb.AddRequest{A: 100, B: 200})
if err != nil {
log.Fatalf("could not add: %v", err)
}
log.Printf("Addition Result: %d", resp.GetResult())
log.Println("Starting streaming sum...")
stream, err := client.StreamSum(ctx)
if err != nil {
log.Fatalf("could not stream sum: %v", err)
}
reqs := []*pb.SumRequest{
{Number: 1},
{Number: 2},
{Number: 3},
{Number: 4},
{Number: 5},
}
for _, req := range reqs {
if err := stream.Send(req); err != nil {
log.Fatalf("could not send request: %v", err)
}
resp, err := stream.Recv()
if err != nil {
log.Fatalf("could not receive response: %v", err)
}
log.Printf("Streamed Sum: %d", resp.GetResult())
}
}
5. 最佳实践
5.1 设计良好的 API
- 明确的命名约定:确保所有服务、方法和字段的命名清晰且具描述性。
- 合理的服务划分:将功能相关的 RPC 方法归类到同一个服务中。
- 合理的请求和响应:请求和响应消息应该包含必要的信息,避免冗余。
5.2 使用 Protocol Buffers
- 简洁的消息结构:保持消息结构简单,避免过于复杂的设计。
- 使用枚举:对于有限的选择,使用枚举类型(enum)来定义,这样可以减少混淆和错误。
- 版本控制:为协议缓冲区定义版本,确保向前兼容。
5.3 异常处理
- 定义错误码:在 proto 文件中定义错误码,并在服务端返回相应的状态码。
- 优雅地处理错误:在客户端优雅地处理错误,提供用户友好的反馈。
5.4 认证和安全
- 使用 TLS/SSL:确保 gRPC 通信的安全性,使用 TLS/SSL 加密。
- 认证机制:实现身份验证机制,例如 JWT(JSON Web Tokens)。
5.5 流量控制和限流
- 流量控制:在服务端实现流量控制,防止过载。
- 限流:根据需要实现限流策略,保护服务免受滥用。
5.6 日志记录和监控
- 日志记录:记录详细的日志,便于调试和追踪问题。
- 健康检查:实现健康检查机制,确保服务可用性。
- 性能监控:使用 Prometheus、Grafana 等工具进行性能监控。
5.7 测试
- 单元测试:为每个服务实现单元测试,确保基本功能的正确性。
- 集成测试:编写集成测试,确保服务之间的交互正确无误。
5.8 文档
- 编写文档:编写详细的 API 文档,包括每个服务、方法和消息的描述。
- 生成文档:使用工具自动生成文档,例如 Swagger 或者其他文档生成工具。
5.9 代码生成
- 代码生成工具:使用 protoc 生成客户端和服务端代码。
- 遵循约定:遵循代码生成工具的约定,避免手动修改生成的代码。
5.10 高可用性和负载均衡
- 高可用性:部署多个实例,实现高可用性。
- 负载均衡:使用负载均衡器(如 Nginx 或 Envoy)来分发请求。
相关推荐
- RACI矩阵:项目管理中的角色与责任分配利器
-
作者:赵小燕RACI矩阵RACI矩阵是项目管理中的一种重要工具,旨在明确团队在各个任务中的角色和职责。通过将每个角色划分为负责人、最终责任人、咨询人和知情人四种类型,RACI矩阵确保每个人都清楚自己...
- 在弱矩阵组织中,如何做好项目管理工作?「慕哲制图」
-
慕哲出品必属精品系列在弱矩阵组织中,如何做好项目管理工作?【慕哲制图】-------------------------------慕哲制图系列0:一图掌握项目、项目集、项目组合、P2、商业分析和NP...
- Scrum模式:每日站会(Daily Scrum)
-
定义每日站会(DailyScrum)是一个Scrum团队在进行Sprint期间的日常会议。这个会议的主要目的是为了应对Sprint计划中的不断变化,确保团队能够有效应对挑战并达成Sprint目标。为...
- 大家都在谈论的敏捷开发&Scrum,到底是什么?
-
敏捷开发作为一种开发模式,近年来深受研发团队欢迎,与瀑布式开发相比,敏捷开发更轻量,灵活性更高,在当下多变环境下,越来越多团队选择敏捷开发。什么是敏捷?敏捷是一种在不确定和变化的环境中,通过创造和响应...
- 敏捷与Scrum是什么?(scrum敏捷开发是什么)
-
敏捷是一种思维模式和哲学,它描述了敏捷宣言中的一系列原则。另一方面,Scrum是一个框架,规定了实现这种思维方式的角色,事件,工件和规则/指南。换句话说,敏捷是思维方式,Scrum是规定实施敏捷哲学的...
- 敏捷项目管理与敏捷:Scrum流程图一览
-
敏捷开发中的Scrum流程通常可以用一个简单的流程图来表示,以便更清晰地展示Scrum框架的各个阶段和活动。以下是一个常见的Scrum流程图示例:这个流程图涵盖了Scrum框架的主要阶段和活动,其中包...
- Mockito 的最佳实践(mock方法)
-
记得以前面试的时候,面试官问我,平常开发过程中自己会不会测试?我回答当然会呀,自己写的代码怎么不测呢。现在想想我好像误会他的意思了,他应该是想问我关于单元测试,集成测试以及背后相关的知识,然而当时说到...
- EffectiveJava-5-枚举和注解(java枚举的作用与好处)
-
用enum代替int常量1.int枚举:引入枚举前,一般是声明一组具名的int常量,每个常量代表一个类型成员,这种方法叫做int枚举模式。int枚举模式是类型不安全的,例如下面两组常量:性别和动物种...
- Maven 干货 全篇共:28232 字。预计阅读时间:110 分钟。建议收藏!
-
Maven简介Maven这个词可以翻译为“知识的积累”,也可以翻译为“专家”或“内行”。Maven是一个跨平台的项目管理工具。主要服务于基于Java平台的项目构建、依赖管理和项目信息管理。仔...
- Java单元测试框架PowerMock学习(java单元测试是什么意思)
-
前言高德的技术大佬在谈论方法论时说到:“复杂的问题要简单化,简单的问题要深入化。”这句话让我感触颇深,这何尝不是一套编写代码的方法——把一个复杂逻辑拆分为许多简单逻辑,然后把每一个简单逻辑进行深入实现...
- Spring框架基础知识-第六节内容(Spring高级话题)
-
Spring高级话题SpringAware基本概念Spring的依赖注入的最大亮点是你所有的Bean对Spring容器的存在是没有意识的。但是在实际的项目中,你的Bean必须要意识到Spring容器...
- Java单元测试浅析(JUnit+Mockito)
-
作者:京东物流秦彪1.什么是单元测试(1)单元测试环节:测试过程按照阶段划分分为:单元测试、集成测试、系统测试、验收测试等。相关含义如下:1)单元测试:针对计算机程序模块进行输出正确性检验工作...
- 揭秘Java代码背后的质检双侠:JUnit与Mockito!
-
你有没有发现,现在我们用的手机App、逛的网站,甚至各种智能设备,功能越来越复杂,但用起来却越来越顺畅,很少遇到那种崩溃、卡顿的闹心事儿?这背后可不是程序员一拍脑袋写完代码就完事儿了!他们需要一套严谨...
- 单元测试框架哪家强?Junit来帮忙!
-
大家好,在前面的文章中,给大家介绍了以注解和XML的方式分别实现IOC和依赖注入。并且我们定义了一个测试类,通过测试类来获取到了容器中的Bean,具体的测试类定义如下:@Testpublicvoid...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- 框架图 (58)
- flask框架 (53)
- quartz框架 (51)
- abp框架 (47)
- jpa框架 (47)
- springmvc框架 (49)
- 分布式事务框架 (65)
- scrapy框架 (56)
- shiro框架 (61)
- 定时任务框架 (56)
- java日志框架 (61)
- JAVA集合框架 (47)
- mfc框架 (52)
- abb框架断路器 (48)
- ui自动化框架 (47)
- beego框架 (52)
- java框架spring (58)
- grpc框架 (65)
- ppt框架 (48)
- 内联框架 (52)
- cad怎么画框架 (58)
- ps怎么画框架 (47)
- ssm框架实现登录注册 (49)
- oracle字符串长度 (48)
- oracle提交事务 (47)