在golang中使用protoc

【Golang】proto生成go的相关文件

在这里插入图片描述

推荐个人主页:席万里的个人空间

前言:1、为什么要使用 protoc 以及 Protobuf 与 gRPC?

在构建分布式系统和微服务架构时,服务之间的通信方式至关重要。随着互联网技术的发展,我们往往需要处理大量的数据交互,并且希望在各种平台之间高效、可靠地交换信息。为了解决这些问题,Protobuf(Protocol Buffers)和 gRPC(Google Remote Procedure Call)成为了许多开发者的首选技术。

1.1 什么是 protoc

protoc 是 Protocol Buffers(简称 Protobuf)的一部分,是一个用于编译 .proto 文件的工具。Protobuf 是一种由 Google 开发的数据序列化协议,它比传统的 XML 和 JSON 更加紧凑高效。它允许你定义消息结构,然后将这些结构序列化成字节流,可以方便地在不同的编程语言和平台之间进行交换。

protoc 是 Protobuf 的编译器工具,用于将 .proto 文件编译为不同语言(如 Go、Java、Python 等)中的类或结构体,并生成相应的序列化和反序列化代码。通过 protoc 工具,我们可以快速生成可以在客户端和服务端之间共享的代码,使得服务间的数据交换变得简单且高效。

1.2为什么选择 Protobuf 和 gRPC?

1.2.1 高效的序列化和反序列化

Protobuf 是一种二进制格式,相比于 JSON 或 XML,它具有更小的体积和更高的解析效率。这使得它非常适合用于高性能要求的分布式系统,尤其是微服务架构中的服务间通信。

  • 体积小:Protobuf 使用紧凑的二进制格式,而 JSON 和 XML 则是文本格式,Protobuf 编码的数据量远小于 JSON 和 XML,相同的数据可以占用更少的存储空间和传输带宽。
  • 解析快:Protobuf 数据的序列化和反序列化速度非常快,尤其在数据量大时,Protobuf 的优势更加明显。

1.2.2 跨语言支持

Protobuf 提供了多种语言的支持,包括 Go、Java、Python、C++ 等。这使得在多语言的系统中,Protobuf 可以作为标准数据格式,在不同语言的服务之间无缝传递数据。

  • 跨平台通信:通过 Protobuf 和 gRPC,我们可以轻松实现不同语言和平台之间的高效数据交换。例如,Go 服务可以与 Python 服务、Java 服务进行通信,而不需要担心平台和语言的差异。

1.2.3 强类型和自定义数据结构

与 JSON 等格式不同,Protobuf 强制要求定义明确的消息结构。这种强类型定义确保了数据格式的一致性和可靠性,避免了数据格式不匹配导致的错误。

  • 定义清晰的消息格式:在 .proto 文件中,我们定义了消息的字段和类型,例如 stringint32 等。这种结构化定义使得代码更加易读且容易维护。
  • 向后兼容性:Protobuf 支持向后兼容性,允许我们在不破坏现有 API 的情况下对数据结构进行扩展。

1.2.4 gRPC 提供高效的 RPC 调用

gRPC 是 Google 推出的一个高性能、开源的远程过程调用(RPC)框架。gRPC 基于 Protobuf 提供了一个简单且高效的方式来实现服务间的通信。

  • 高效的调用:gRPC 使用 HTTP/2 协议,这意味着它支持双向流、头部压缩和多路复用,从而减少延迟并提升性能。
  • 支持流式数据:gRPC 支持客户端与服务器之间的双向流通信,这在需要长时间保持连接或持续交换数据的应用场景中非常有用。
  • 简化的 API 调用:gRPC 通过自动生成的客户端和服务器代码简化了 RPC 的调用逻辑,开发者只需关注接口定义和业务实现。

1.2.5 适用于微服务架构

在微服务架构中,服务间的通信是一个核心问题。gRPC 提供了一种基于 HTTP/2 的高效、低延迟的通信机制,使得微服务之间的通信变得更加高效和可靠。

  • 跨语言支持:gRPC 支持多语言客户端和服务器,适用于由不同编程语言编写的微服务之间的通信。
  • 服务发现与负载均衡:gRPC 结合了现代服务发现和负载均衡机制,使得它在微服务架构中尤为适用。

实际操作:2、查看proto的版本号

protoc --version

3、安装protoc-gen-go和protoc-gen-go-grpc

go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latests

4、生成protobuff以及grpc的文件

 protoc --go_out=./ --go-grpc_out=./ *.proto

5、HelloWorld案例

注:在使用客户端调用服务函数的时候注意不要传nil,不然会发生panic()。

proto文件,及生成go-grpc

syntax = "proto3";
option go_package = ".;helloworld";

service Greeter {
  rpc SayHello (HelloRequest) returns (HelloReply) {}
}

message HelloRequest {
  string msg = 1;
}

message HelloReply {
  string msg = 1;
}

client.go 客户端

package main

import (
	"context"
	"fmt"
	"google.golang.org/grpc"
	"log"
	pb "test/yunfuwu/examples/helloworld/helloworld"
)

func main() {
	conn, err := grpc.Dial("0.0.0.0:5001", grpc.WithInsecure())
	if err != nil {
		log.Fatalf("did not connect: %v", err)
	}
	defer conn.Close()
	client := pb.NewGreeterClient(conn)

	msg := "英雄联盟"
	r, err := client.SayHello(context.Background(), &pb.HelloRequest{
		Msg: msg,
	})
	if err != nil {
		//panic(err)
	}
	fmt.Println(r.Msg)
}

server.go 服务端

package main

import (
	"context"
	"fmt"
	"google.golang.org/grpc"
	"log"
	"net"

	pb "test/yunfuwu/examples/helloworld/helloworld"
)

type server struct {
}

func (s *server) SayHello(ctx context.Context, req *pb.HelloRequest) (*pb.HelloReply, error) {
	return &pb.HelloReply{Msg: "hello " + req.Msg}, nil
}
func main() {
	lis, err := net.Listen("tcp", ":5001")
	if err != nil {
		log.Fatalf("failed to listen: %v", err)
		return
	}
	fmt.Println(":5001")
	s := grpc.NewServer()
	pb.RegisterGreeterServer(s, &server{})
	if err := s.Serve(lis); err != nil {
		log.Fatalf("failed to serve: %v", err)
	}
}

在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

万里code

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值