Go微服务(二)——Protobuf详细入门 下

本文涉及的产品
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
简介: Go微服务(二)——Protobuf详细入门 下

4. 基于Protobuf的RPC(可跳过这部分)

对于没有⽤过Protobuf的读者,建议先从官⽹了解下基本⽤法。这⾥我们尝试将Protobuf和RPC结合在 ⼀起使⽤,通过Protobuf来最终保证RPC的接⼝规范和安全。Protobuf中最基本的数据单元是 message,是类似Go语⾔中结构体的存在。在message中可以嵌套message或其它的基础数据类型的 成员。

定义RPC数据结构:

07-pbrpc/service/service.proto

syntax = "proto3";
package hello;
// go module = MicroServiceStudy01
option go_package = "MicroServiceStudy01/07-pbrpc/service";
message Request{
  string value = 1;
}
message Response{
  string value = 1;
}

生成go语言结构:

$ cd 07-pbrpc
$ protoc -I ./service --go_out=./service --go_opt=module="MicroServiceStudy01/07-pbrpc/service" service/service.prot
o

定义RPC接口:

基于 生成的数据结构,定义接口:

07-pbrpc/service/interface.go

package service
const HelloServiceName = "HelloService"
type HelloService interface {
  // Hello
  // 这里的 Request 和  Response 是基于protobuf生成的service.pb.go里的结构
  Hello(request *Request, response *Response) error
}

这个接口时为了约束参数,详见2.更安全的RPC接口


向之前没有联合protobuf使用的时候,我们这里的接口方法的参数类型是我们自己写的结构体类型,而使用了protobuf之后,这里的参数类型就需要引用我们通过protobuf生成的.pb.go文件里的结构体类型。


我们定义的接口要放在一个 独立的文件里类似于当前的service包,他就相当于一个契约包,用来 约束服务端server(提供RPC服务)和我们的客户端client(调用RPC服务)。


定义服务端:

07-pbrpc/server/server.go

type HelloService struct{}
func (hs *HelloService) Hello(req *service.Request, resp *service.Response) error {
  resp.Value = "hello:" + req.Value
  return nil
}
// 通过接口约束 Server 端
var _ service.HelloService = (*HelloService)(nil)
func main() {
  rpc.RegisterName(service.HelloServiceName, new(HelloService))
  listen, err := net.Listen("tcp", ":1234")
  if err != nil {
    log.Fatal("Listen TCP err:", err)
  }
  for {
    conn, err := listen.Accept()
    if err != nil {
      log.Fatal("Accept err:", err)
    }
        // 这里使用的还是json,先忽略 往下看
    go rpc.ServeCodec(jsonrpc.NewServerCodec(conn))
  }
}

定义客户端:

07-pbrpc/client/client.go

type HelloServiceClient struct {
  *rpc.Client
}
func (hsc HelloServiceClient) Hello(req *service.Request, resp *service.Response) error {
  return hsc.Client.Call(service.HelloServiceName+".Hello", req, resp)
}
// 通过接口约束 Client 端
var _ service.HelloService = (*HelloServiceClient)(nil)
func DialHelloService(network, address string) (*HelloServiceClient, error) {
  conn, err := net.Dial(network, address)
  if err != nil {
    log.Fatal("net.Dail err: ", err)
  }
  client := rpc.NewClientWithCodec(jsonrpc.NewClientCodec(conn))
  return &HelloServiceClient{client}, nil
}
func main() {
  client, err := DialHelloService("tcp", "localhost:1234")
  if err != nil {
    log.Fatal("Dial err: ", err)
  }
  resp := &service.Response{}
  err = client.Hello(&service.Request{Value: "world"}, resp)
  if err != nil {
    log.Fatal(err)
  }
  fmt.Println(resp)
}

此时我们只是Hello方法的参数使用的是protobuf生成的service.pb.go中的结构体,但是其他逻辑依然没有改变,使用的还是json-rpc,所以这里会发现,我们这次虽然定义了相关的protobuf,但是我们和protobuf还没有半毛钱关系,只是用到了他为我们生成的结构体;


那么我们如何将json编码换成protobuf编码呢?


将07-pbrpc/server/server.go里的go rpc.ServeCodec(jsonrpc.NewServerCodec(conn))修改成go rpc.ServeCodec(server.NewServerCodec(conn))即可。


这是我们4.基于Protobuf的RPC的重点,官方的net/rpc包里是没有protoc的插件


我看的视频的发布者仿照net/rpc/jsonrpc自己写了个关于Proto Codec 编解码的包,但是视频中没有放出来,而这里的NewServerCodec就用到了那个包里的方法,大家不用深究,逻辑就是这么个逻辑,重在理解。

相关文章
|
6天前
|
消息中间件 Go API
基于Go语言的微服务架构实践
随着云计算和容器化技术的兴起,微服务架构成为了现代软件开发的主流趋势。Go语言,以其高效的性能、简洁的语法和强大的并发处理能力,成为了构建微服务应用的理想选择。本文将探讨基于Go语言的微服务架构实践,包括微服务的设计原则、服务间的通信机制、以及Go语言在微服务架构中的优势和应用案例。
|
6天前
|
JavaScript 前端开发 Go
Go语言的入门学习
【4月更文挑战第7天】Go语言,通常称为Golang,是由Google设计并开发的一种编程语言,它于2009年公开发布。Go的设计团队主要包括Robert Griesemer、Rob Pike和Ken Thompson,这三位都是计算机科学和软件工程领域的杰出人物。
17 1
|
6天前
|
消息中间件 Go API
Golang深入浅出之-Go语言中的微服务架构设计与实践
【5月更文挑战第4天】本文探讨了Go语言在微服务架构中的应用,强调了单一职责、标准化API、服务自治和容错设计等原则。同时,指出了过度拆分、服务通信复杂性、数据一致性和部署复杂性等常见问题,并提出了DDD拆分、使用成熟框架、事件驱动和配置管理与CI/CD的解决方案。文中还提供了使用Gin构建HTTP服务和gRPC进行服务间通信的示例。
32 0
|
6天前
|
监控 Java 应用服务中间件
【微服务系列笔记】Sentinel入门-微服务保护
Sentinel是一个开源的分布式系统和应用程序的运维监控平台。它提供了实时数据收集、可视化、告警和自动化响应等功能,帮助用户监控和管理复杂的IT环境。本文简单介绍了微服务保护以及常见雪崩问题,解决方案。以及利用sentinel进行入门案例。
33 3
|
6天前
|
JSON API Go
Go-Zero从0到1实现微服务项目开发(二)
继续更新GoZero微服务实战系列文章:上一篇被GoZero作者万总点赞了,本文将继续使用 Go-zero 提供的工具和组件,从零开始逐步构建一个基本的微服务项目。手把手带你完成:项目初始化+需求分析+表结构设计+api+rpc+goctl+apifox调试+细节处理。带你实现一个完整微服务的开发。
|
6天前
|
Go 开发者
Golang深入浅出之-Go语言结构体(struct)入门:定义与使用
【4月更文挑战第22天】Go语言中的结构体是构建复杂数据类型的关键,允许组合多种字段。本文探讨了结构体定义、使用及常见问题。结构体定义如`type Person struct { Name string; Age int; Address Address }`。问题包括未初始化字段的默认值、比较含不可比较字段的结构体以及嵌入结构体字段重名。避免方法包括初始化结构体、自定义比较逻辑和使用明确字段选择器。结构体方法、指针接收者和匿名字段嵌入提供了灵活性。理解这些问题和解决策略能提升Go语言编程的效率和代码质量。
32 1
|
6天前
|
编译器 Go 开发者
Go语言入门|包、关键字和标识符
Go语言入门|包、关键字和标识符
34 0
|
6天前
|
Kubernetes Cloud Native Go
《Go 简易速速上手小册》第10章:微服务与云原生应用(2024 最新版)(下)
《Go 简易速速上手小册》第10章:微服务与云原生应用(2024 最新版)
66 0
|
6天前
|
Cloud Native 算法 Go
《Go 简易速速上手小册》第10章:微服务与云原生应用(2024 最新版)(上)
《Go 简易速速上手小册》第10章:微服务与云原生应用(2024 最新版)
70 0
|
6天前
|
运维 监控 Go
Go语言微服务实战与最佳实践
【2月更文挑战第14天】本文将深入探讨使用Go语言进行微服务实战中的最佳实践,包括服务拆分、API设计、并发处理、错误处理、服务治理与监控等方面。通过实际案例和详细步骤,我们将分享如何在Go语言环境中构建高效、稳定、可扩展的微服务系统。