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

相关推荐
Chester_19995 小时前
CSP202203C.计算资源调度器
开发语言·数据结构·c++·蓝桥杯
2601_962218475 小时前
万象生鲜系统区块链溯源技术帮助生鲜企业搭建食品安全数字化体系
大数据·运维·微服务·云原生·架构
EXI-小洲6 小时前
Java 操作 Word:字符串替换、图片插入、动态生成表格与API接口下载
java·开发语言·spring boot·word
会周易的程序员6 小时前
给 PLC 写一个字节码虚拟机:STVM 虚拟机架构设计
开发语言·c++·虚拟机·软plc·iec61131·stvm
机器视觉知识推荐、就业指导6 小时前
为什么老说“纯 Qt 没啥就业市场”?
开发语言·qt
telepan6 小时前
Qt 开发避坑与性能指南:如何优雅、安全地定义全局常量字符串?
开发语言·qt
m0_695251497 小时前
Qt MaintenanceTool 使用国内镜像加速下载(超详细教程)
开发语言·qt
大衛說8 小时前
《Python 从入门到精通》系列总览与学习路线
开发语言·python·学习
可乐鸡翅yeah_9 小时前
hls.js 内存泄漏实战排查,直播 M3U8 长时间播放异常定位方案
开发语言·javascript·python·django·ecmascript·m3u8·m3u8在线
2601_962203519 小时前
Java进阶07集合(续)
java·开发语言