Golang Protoc Grpc实现微服务通信

protoc 是什么?

protoc 是 Protobuf 官方提供的命令行编译工具,作用是将 .proto 文件(定义了接口、消息结构的 IDL 文件)编译为 目标编程语言(如 Go、Java、Python 等)的代码,让不同语言的服务能基于统一的 Protobuf 定义进行交互。

1.安装protoc

https://github.com/protocolbuffers/protobuf/releases

根据自己的需要安装版本

注:将对应的bin目录加入环境变量

2.安装protoc-grpc-go

protoc-grpc-go是一个插件,用于生成Go语言的数据结构代码

bash 复制代码
go install github.com/golang/protobuf/protoc-gen-go
3.安装grpc
bash 复制代码
go get -u google.golang.org/grpc
4.安装VSCODE 关于protoc文件插件

protobuf-vsc

以上环境准备好之后开始代码逻辑实现验证
1.原生rpc实现

a.服务端

Go 复制代码
package main

import (
	"fmt"
	"net"
	"net/http"
	"net/rpc"
)

type Server struct {
}

type Req struct {
	Num1 int
	Num2 int
}

type Res struct {
	Num int
}

func (s *Server) Add(req Req, res *Res) error {
	res.Num = req.Num1 + req.Num2
	return nil
}

func main() {
	// 注册RPC服务
	rpc.Register(new(Server))
	rpc.HandleHTTP()
	listen, err := net.Listen("tcp", ":8090")
	if err != nil {
		fmt.Println(err)
		return
	}
	http.Serve(listen, nil)
}

启动

b.客户端

Go 复制代码
package main

import (
	"fmt"
	"net/rpc"
)

type Req struct {
	Num1 int
	Num2 int
}

type Res struct {
	Num int
}

func main() {
	req := Req{Num1: 1, Num2: 2}
	client, err := rpc.DialHTTP("tcp", ":8090")
	if err != nil {
		fmt.Println(err)
		return
	}
	var res Res
	client.Call("Server.Add", req, &res)
	fmt.Println(res.Num)
}

启动

原生rpc缺点:

1.编写相对复杂,需要自己去关注实现过程

2.没有代码提示,容易出错

2.GPRC实现

a.定义proto文件:hello.proto

Go 复制代码
// proto版本
syntax = "proto3";
// 默认包
package proto;

// 包名
option go_package = "/proto";

//定义rpc服务
service HelloService {
  //定义函数体
  rpc SayHello(Request) returns (Response);
}

message Request {
  string name    = 1;
  string message = 2;
}

message Response {
  string name    = 1;
  string message = 2;
}

b.编译proto文件生成go

bash 复制代码
protoc -I . --go_out=plugins=grpc:. .\hello.proto

生成hello.pb.go

c.grpc服务端

Go 复制代码
package main

import (
	"context"
	"fmt"
	"net"
	"project09/grpc/proto"

	"google.golang.org/grpc"
)

// 此结构体可随意命名
type HelloWorld struct {
}

// 结构体中方法
func (hw *HelloWorld) SayHello(ctx context.Context, request *proto.Request) (respose *proto.Response, err error) {
	fmt.Printf("接收请求:%v", request)
	return &proto.Response{
		Name:    request.Name,
		Message: request.Message,
	}, nil
}

func main() {
	listen, err := net.Listen("tcp", ":8010")
	if err != nil {
		fmt.Println("Fail to listen")
	}
	s := grpc.NewServer()
	// 将结构体注册为grpc服务
	server := HelloWorld{}
	proto.RegisterHelloServiceServer(s, &server)

	fmt.Println("grpc server running :8010")
	// 开始处理客户端请求
	s.Serve(listen)
}

启动:

d.客户端

Go 复制代码
package main

import (
	"context"
	"fmt"
	"log"
	"project09/grpc/proto"

	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials/insecure"
)

func main() {
	addr := ":8010"
	// 创建一个客户端连接 且不使用安全证书来实现
	conn, err := grpc.NewClient(addr, grpc.WithTransportCredentials(insecure.NewCredentials()))

	if err != nil {
		log.Fatalf(fmt.Sprintf("grpc connect addr [%v] 连接失败%s", addr, err))
	}
	defer conn.Close()
	client := proto.NewHelloServiceClient(conn)
	result, err := client.SayHello(context.Background(), &proto.Request{
		Name:    "james",
		Message: "ok",
	})
	fmt.Println(result, err)
}

启动:

以上为gprc具体实现。

相关推荐
神仙别闹8 小时前
基于 C++ 实现(控制台)学生成绩管理系统
开发语言·c++
伞伞悦读9 小时前
【第36期】Python 目录与路径详解:pathlib、文件遍历、创建、复制、移动和删除风险
开发语言·python
名字还没想好☜11 小时前
Go context.AfterFunc 实战(Go 1.21):context 一取消就自动跑清理,告别手写 goroutine 监听 Done
后端·golang·go
web守墓人11 小时前
【goed/ui】自定义组件设计思想篇
linux·windows·ui·golang
2601_9669496512 小时前
只拿到股票代码还不够:量化程序到底还需要哪些标的信息?——从数据建模开始理解股票元数据
开发语言·python·数据分析·pandas·量化交易·股票数据·quantdash
m0_7345717612 小时前
深入理解5g <十八>传输块tbsize的计算
开发语言·5g
RAN114267600813 小时前
1.3第一个程序的介绍
开发语言·qt
blue_ice .14 小时前
Verilog DDS 数字信号发生器:DAC 输出模拟波形与 ADC 回采观测
开发语言·单片机·嵌入式硬件·fpga开发
远翔调光芯片^1382879887214 小时前
ECP5702能芯科技PD取电芯片在市场上的优势有哪些?
开发语言·人工智能·单片机·嵌入式硬件·智能家居
泡海椒15 小时前
规则引擎对比:JQuick-Java vs Drools 轻量场景选型对比
java·开发语言