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

相关推荐
清水白石0083 小时前
突破并行瓶颈:Python 多进程开销全解析与 IPC 优化实战
开发语言·网络·python
百锦再4 小时前
Java之Volatile 关键字全方位解析:从底层原理到最佳实践
java·开发语言·spring boot·struts·kafka·tomcat·maven
daad7774 小时前
rcu 内核线程
java·开发语言
xzjiang_3654 小时前
检查是否安装了MinGW 编译器
开发语言·qt·visual studio code
百锦再5 小时前
Java JUC并发编程全面解析:从原理到实战
java·开发语言·spring boot·struts·kafka·tomcat·maven
清水白石0085 小时前
突破性能瓶颈:深度解析 Numba 如何让 Python 飙到 C 语言的速度
开发语言·python
Eternity∞5 小时前
Linux系统下,C语言基础
linux·c语言·开发语言
wangluoqi7 小时前
c++ 树上问题 小总结
开发语言·c++
Go_Zezhou7 小时前
pnpm下载后无法识别的问题及解决方法
开发语言·node.js
前路不黑暗@7 小时前
Java项目:Java脚手架项目的 C 端用户服务(十五)
java·开发语言·spring boot·学习·spring cloud·maven·mybatis