go-gRPC微服务调用

news/2025/3/19 13:59:53/文章来源:https://www.cnblogs.com/Mickey-7/p/18780899

协议介绍

RPC协议

RPC(远程过程调用协议),通过网络从远程计算机上请求服务,而不需要了解底层网络技术的协议。RPC假定某些协议的存在,例如TCP/UDP等,为通信程序之间携带信息数据。在OSI网络七层模型中,RPC跨越了传输层和应用层,RPC使得开发包括网络分布式多程序在内的应用程序更加容易,过程就是像调用本地方法一样调用远程的过程,RPC采用客户端/服务端的模式,通过request-response消息模式实现

gRPC协议

gRPC是一个现代的开源高性能远程过程调用(RPC)框架,gRPC的客户端可以像调用本地对象一样直接调用另一台不同的机器上服务端应用的方法,使能够更容易地创建分布式应用和服务,gRPC 基于以下理念:

  • 定义一个服务,指定其能够被远程调用的方法(包含参数和返回类型)
  • 在服务端实现这个接口,并运行一个 gRPC 服务器来处理客户端调用
  • 在客户端拥有一个存根能够像服务端一样的方法
HTTP2

gRPC的底层是基于HTTP2协议:

  • HTTP1里的header对应HTTP2里的 HEADERS frame
  • HTTP1里的payload对应HTTP2里的 DATA frame
  • gGRPC把元数据放到HTTP/2 Headers里,请求参数序列化之后放到 DATA frame
  • HTTP2里面gRPC调用需要解码流程,一次是HEADERS frame,一次是DATA frame
  • HTTP2标准本身是只有一个TCP链接,但是实际在gRPC里是会有多个TPC连接

gRPC调用实例

grpc服务端
  1. .proto文件

    // 请求参数
    message  UserInfoRequest{int32 user_id = 1;
    }// 响应参数
    message  UserInfoResponse {string user_name = 1;
    }// 定义接口
    service  UserInfoService{rpc GetUserInfo(UserInfoRequest) returns(UserInfoResponse);
    }
    
  2. 生成grpc调用的文件,使用plugins=grpc指定

     protoc --go_out=plugins=grpc:./ test.proto     
    
    // 生成对应的test.pb.go文件
    // 生成的部分代码// 自动生成GetUserInfo接口方法
    func (*UnimplementedUserInfoServiceServer) GetUserInfo(context.Context, *UserInfoRequest) (*UserInfoResponse, error) {return nil, status.Errorf(codes.Unimplemented, "method GetUserInfo not implemented")
    }// GetUserInfo方法的响应参数
    type UserInfoResponse struct {state         protoimpl.MessageStatesizeCache     protoimpl.SizeCacheunknownFields protoimpl.UnknownFieldsUserName string `protobuf:"bytes,1,opt,name=user_name,json=userName,proto3" json:"user_name,omitempty"`
    }
    
  3. 实现接口逻辑

    // service/product.go
    // 根据第二步生成的接口,由于只有接口没有业务逻辑实现,所以去实现具体的业务逻辑package serviceimport "context"// 定义对应的实例
    var UserService = &UserInfoService{}type UserInfoService struct {
    }func (u *UserInfoService) GetUserInfo(context.Context, *UserInfoRequest) (*UserInfoResponse, error) {// 实现业务逻辑return &UserInfoResponse{UserName: "名字"}, nil
    }
  4. 注册服务

    package mainimport ("go_rpc_demo/service""google.golang.org/grpc"
    )func main() {// 创建一个grpc服务端rpcServer := grpc.NewServer()// RegisterUserInfoServiceServer是默认生成// 调用RegisterUserInfoServiceServer ,将第三部的接口的实现注册到rpcServerservice.RegisterUserInfoServiceServer(rpcServer, service.UserService)}
    
  5. 启动服务

    package mainimport ("go_rpc_demo/service""google.golang.org/grpc""log""net"
    )func main() {// 创建grpc服务实例rpcServer := grpc.NewServer()// RegisterUserInfoServiceServer是由 Protobuf 编译器根据.ptoto定义的服务自动生成的函数// 调用RegisterUserInfoServiceServer ,将第三步的接口的实现注册到rpcServerservice.RegisterUserInfoServiceServer(rpcServer, service.UserService)// 在tpc协议的8002端口开启监听,返回一个 net.Listener 类型的对象和可能出现的错误listener, err := net.Listen("tcp", ":8002")if err != nil {log.Fatal("启动监听出错", err)}// 调用 rpcServer 的 Serve 方法,让 gRPC 服务器开始在 listener 所监听的端口上提供服务。此方法会一直阻塞,直至服务器关闭err = rpcServer.Serve(listener)if err != nil {log.Fatal("启动服务出错") }}
    
grpc客户端
  1. 在客户端目录中,将 service下的product.go和test.pb.go 复制一份

    image-20250319135354979

  2. 客户端请求

    package mainimport ("context""go_rpc_demo/service""google.golang.org/grpc""google.golang.org/grpc/credentials/insecure""log"
    )func main() {// 创建一个连接// 连接到8002端口的grpc服务器// 第二个参数是连接凭证// grpc.WithTransportCredentials(insecure.NewCredentials()) 表示使用不安全的传输凭证,也就是不进行 TLS 加密,一般用于开发和测试环境conn, err := grpc.Dial(":8002", grpc.WithTransportCredentials(insecure.NewCredentials()))if err != nil {log.Fatal("连接出错", err)}// 执行完关闭连接defer conn.Close()// NewUserInfoServiceClient是由 Protobuf 编译器根据服务名字生成的// 创建客户端,传入对应的连接client := service.NewUserInfoServiceClient(conn)// 请求参数request := &service.UserInfoRequest{UserId: 1}// 通过客户端调用对应的方法,像调用本地方法一样infoResponse, err := client.GetUserInfo(context.Background(), request)if err != nil {log.Fatal("请求失败", err)}// 请求结果log.Println(infoResponse)}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/901506.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

突破性技术:制药冻干机实现EtherCAT与Profinet网关模块无缝监控集成

案例分享:冻干机 EtherCAT 转 Profinet 实现温湿度监控 在现代医药生产过程中,冻干机作为关键设备,对温湿度的控制与监测尤为重要。某医药企业在其冻干机系统升级中,面临一个典型的通讯挑战:主控制系统采用 EtherCAT 协议,而现场的温湿度监控系统及其他过程控制设备则基于…

java-JNDI(二)-高版本绕过

JNDI 高版本的绕过 为了防止 JNDI 攻击,Oracle 对 JNDI 的远程类加载漏洞(如 LDAP 或 RMI 协议的远程代码执行(RCE))进行了限制 com.sun.jndi.rmi.object.trustURLCodebase=false com.sun.jndi.cosnaming.object.trustURLCodebase=false com.sun.jndi.ldap.object.trustUR…

tile

dsfTechnorati Tags: gjhgsdhttp://dfdfdfddfdfdfdsfdfdf

电视机顶盒刷机,更改固件包教程

这几天捣鼓了很久的刷机包,终于学会了怎么把已经弄好的刷机包,更改成自己想要的桌面。下面是我整理好的详细教程,本教程所需工具:刷机包大全、MLK软件、mumu模拟器 刷机包大全: 链接: https://pan.baidu.com/s/1G0on4sV9QmpxPXLUSN5ttQ?pwd=5279 提取码: 5279 一.确定机顶…

Java技术栈面试八股文:掌握这九大关键领域

Java基础:这是Java开发的基石,包括Java语言的基本语法、数据类型、控制结构、面向对象编程(OOP)概念(如类、对象、继承、封装、多态)、异常处理、集合框架等。掌握这些基础知识对于理解更高级的Java特性至关重要。Java Web基础:涉及Java在Web开发中的应用,包括Servlet、…

Unity —— SpriteAtlas + Include in Build

前言在使用atlas Sprite的过程中,会忍不住产生一个疑问,atlas是做什么用的,这个include in Build的含义是什么呢,以及它是否应该被勾选。网上查阅到了很多资源,有的说这个选项大胆勾选,有的说这个选项勾选完后图集打包后的纹理在游戏启动后,会一直常驻内存,需要自己做好…

2025预测:PLM系统集成AI的7种智能决策应用场景

随着科技的飞速发展,产品生命周期管理(PLM)系统与人工智能(AI)的集成正逐渐成为企业提升竞争力的关键因素。这种集成不仅能够优化产品开发流程,还能在多个环节实现智能决策,为企业带来前所未有的价值。在2025 年,我们有望看到 PLM 系统集成 AI 后在众多领域展现出强大的…

PLM项目管理软件在汽车行业的应用案例

PLM项目管理软件在汽车行业的应用案例 汽车行业作为制造业的重要组成部分,面临着日益复杂的产品研发、生产管理等挑战。在这样的背景下,PLM(产品生命周期管理)项目管理软件应运而生,为汽车企业提升竞争力提供了有力支持。PLM项目管理软件涵盖了从产品概念设计到产品退役的…

java自学学习路线笔记+实践项目+面试八股文

基础知识巩固Java基础:掌握基本语法、数据类型、控制结构、面向对象等核心概念。推荐学习资源:韩顺平老师的B站课程。 Java进阶:深入学习集合框架、IO流、反射、注解等高级特性。 Java并发:理解线程、锁、并发工具类等,为高并发项目开发打基础。数据库技术MySQL:掌握SQL语…

awdp pwn

ciscn&ccb半决第十八届CISCN&CCB半决赛 awdp pwn typo snprintf() 是一个 C 语言标准库函数,用于格式化输出字符串,并将结果写入到指定的缓冲区,与 sprintf() 不同的是,snprintf() 会限制输出的字符数,避免缓冲区溢出。 C 库函数 int snprintf(char str, size_t …

matlab并行计算

parfor比较难用,要求变量之间不能有干扰,必须能相互独立,这里推荐一下parfeval,相当于多开了n个matlab。 parfeval可以并行运行同一个函数,赋值不同的参数。 首先创建并行池-: p = parpool(2);%这里相当于使用了两个核心,根据你的CPU核心数决定。parfeval用于并行执行代…