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

相关推荐
梁山好汉(Ls_man)7 分钟前
鸿蒙_ArkTS解决Duplicate function implementation错误
开发语言·华为·typescript·harmonyos·鸿蒙
xiaoshuaishuai810 分钟前
Git二分法定位Bug
开发语言·python
so2F32hj218 分钟前
一款Go语言Gin框架DDD脚手架,适合快速搭建项目
开发语言·golang·gin
LJianK143 分钟前
Java中的类、普通类,抽象类,接口的区别
java·开发语言
Dev7z43 分钟前
基于MATLAB的5G物理层文本传输系统仿真与性能分析
开发语言·5g·matlab
小智社群44 分钟前
贝壳获取小区的名称
开发语言·前端·javascript
lsx2024061 小时前
Python3 OS模块详解
开发语言
LiLiYuan.1 小时前
【Java线程 vs 虚拟机线程】
java·开发语言
FlDmr4i281 小时前
.NET 10 & C# 14 New Features 新增功能介绍-扩展成员Extension Members
开发语言·c#·.net
原来是猿1 小时前
Linux进程信号详解(三):信号保存
开发语言·c++·算法