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具体实现。

相关推荐
北冥you鱼14 小时前
Go 语言 GORM 使用 Preload:从关联查询到嵌套预加载的完整实践
开发语言·jvm·golang
dingzd9515 小时前
TikTok账号登录态失效的Cookie字段排查路径
开发语言·php·跨境电商·营销策略
microrain15 小时前
把规则链存成文件之后,上线一条规则只需改一个字段
物联网·golang·规则引擎·sagooiot
曹牧15 小时前
C#:The operation has timed out
开发语言·c#
你看我名字15 小时前
数眼智能 Search + Reader 实战:联网问答怎样避免“搜到了,却引用错了”
android·java·开发语言
小嘉丶学长15 小时前
Day13 · 列表与元组
linux·运维·服务器·开发语言·python
努力努力再努力wz15 小时前
【Lua入门系列】从 C++ 迭代器到 Lua 迭代器:一文深入理解 Lua 有状态以及无状态迭代器与泛型for、闭包、ipairs、pairs 和 next
开发语言·c++·lua
努力实干15 小时前
第二阶段 · 第 7 课:C++ 多线程与线程安全
开发语言·c++·安全
每天一道题16 小时前
微服务为什么会发生级联故障?从 Timeout、Retry 到熔断、限流与 Backpressure
微服务·云原生·架构
爱聊灵光的维C16 小时前
C语言初阶:关于函数设计的详细讲解和注意事项
c语言·开发语言·青少年编程·蓝桥杯·学习方法