Part1先决条件
-
获得并安装好Golang(https://go.dev/doc/install)
-
Protocol buffer compiler(protobuf编译器), protoc version 3(protoc工具版本建议为3版本),获得并安装:https://github.com/protocolbuffers/protobuf/releases
-
安装protocol编译器的Go插件
go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.28
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.2
Part2开发环境准备
-
准备go环境
wget https://go.dev/dl/go1.20.5.linux-amd64.tar.gz
tar -zxf go1.20.5.linux-amd64.tar.gz
mv go /usr/local/
-
安装protobuf编译器protoc
wget https://github.com/protocolbuffers/protobuf/releases/download/v23.4/protoc-23.4-linux-x86_64.zip
mkdir protoc-23.4
mv protoc-23.4-linux-x86_64.zip
cd protoc-23.4
unzip protoc-23.4-linux-x86_64.zip
rm -rf protoc-23.4-linux-x86_64.zip
cd ..
mv protoc-23.4 /usr/local/
-
添加相关环境变量
export GOROOT="/usr/local/go"
export GOPATH="/home/tantianran/goCode"
export GOPROXY="https://goproxy.cn,direct"
export GO111MODULE="on"
export PATH=$PATH:$GOROOT/bin:$GOPATH:$GOPATH/bin
export PROTOC_HOME=/usr/local/protoc-23.4
export PATH=$PATH:$PROTOC_HOME/bin
Part3实战:开发一个简单的gRPC Demo
1创建user-service模块
tantianran@go-dev:~/goCode/src$ mkdir user-service
tantianran@go-dev:~/goCode/src$ cd user-service/
tantianran@go-dev:~/goCode/src/user-service$ go mod init
2第一步:使用protobuf idl语言定义服务接口
创建service包
tantianran@go-dev:~/goCode/src/user-service$ mkdir service
tantianran@go-dev:~/goCode/src/user-service$ cd service/
service/users.proto内容:
syntax = "proto3";
option go_package = "user-service/service";
// 服务和方法
service Users {
rpc GetUser (UserGetRequest) returns (UserGetReply) {}
}
// 请求消息
message UserGetRequest {
string email = 1;
int32 id = 2;
}
// 响应消息
message User {
string id = 1;
string first_name = 2;
string last_name = 3;
int32 age = 4;
}
message UserGetReply {
User user = 1; // 嵌套
}
3第二步:生成客户端和服务端代码
-
首先安装用于编译器的go语言插件protoc-gen-go
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
-
开始生成
tantianran@go-dev:~/goCode/src/user-service/service$ protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative users.proto
tantianran@go-dev:~/goCode/src/user-service/service$ ls -l
total 24
-rw-rw-r-- 1 tantianran tantianran 37 Jul 11 10:05 go.mod
-rw-rw-r-- 1 tantianran tantianran 3387 Jul 11 10:10 users_grpc.pb.go
-rw-rw-r-- 1 tantianran tantianran 8984 Jul 11 10:10 users.pb.go
-rw-rw-r-- 1 tantianran tantianran 362 Jul 11 10:09 users.proto
4第三步:编写服务器
创建server包
tantianran@go-dev:~/goCode/src$ cd user-service/
tantianran@go-dev:~/goCode/src/user-service$ mkdir server
tantianran@go-dev:~/goCode/src/user-service$ cd server/
server/server.go
package main
import (
"context"
"log"
"net"
"os"
users "user-service/service" // 导入之前生成的包
"google.golang.org/grpc"
)
// userService类型是Users服务的服务处理程序
type userService struct {
users.UnimplementedUsersServer // 这个字段对于gRPC中的任何服务实现都是强制性的
}
func (s *userService) GetUser(ctx context.Context, in *users.UserGetRequest) (*users.UserGetReply, error) {
// 打印客户端传过来的数据
log.Printf("已接收到邮件地址: %s, 还有ID: %d", in.Email, in.Id)
// 自定义数据响应给客户端
u := users.User{
Id: "user-782935",
FirstName: "tan",
LastName: "tianran",
Age: 30,
}
return &users.UserGetReply{User: &u}, nil
}
// 向gRPC服务器注册Users服务
func registerServices(s *grpc.Server) {
users.RegisterUsersServer(s, &userService{})
}
// 启动gRPC服务器
func startServer(s *grpc.Server, l net.Listener) error {
return s.Serve(l)
}
func main() {
listenAddr := os.Getenv("LISTEN_ADDR")
if len(listenAddr) == 0 {
listenAddr = ":50051"
}
lis, err := net.Listen("tcp", listenAddr)
if err != nil {
log.Fatal(err)
}
s := grpc.NewServer()
registerServices(s)
log.Fatal(startServer(s, lis))
}
5第四步:编写客户端
tantianran@go-dev:~/goCode/src$ cd user-service/
tantianran@go-dev:~/goCode/src/user-service$ mkdir client/
tantianran@go-dev:~/goCode/src/user-service$ cd client/
client/main.go
package main
import (
"context"
"log"
"os"
users "user-service/service" // 导入之前生成的包
"google.golang.org/grpc"
)
// 建立与服务器的连接(通道)
func setupGrpcConnection(addr string) (*grpc.ClientConn, error) {
return grpc.DialContext(
context.Background(),
addr,
grpc.WithInsecure(),
grpc.WithBlock(),
)
}
// 创建客户端与Users服务通信
func getUserServiceClient(conn *grpc.ClientConn) users.UsersClient {
return users.NewUsersClient(conn)
}
// 调用Users服务中的GetUser()方法
func getUser(client users.UsersClient, u *users.UserGetRequest) (*users.UserGetReply, error) {
return client.GetUser(context.Background(), u)
}
func main() {
if len(os.Args) != 2 {
log.Fatal("缺少gRPC服务器地址")
}
conn, err := setupGrpcConnection(os.Args[1])
if err != nil {
log.Fatal(err)
}
defer conn.Close()
c := getUserServiceClient(conn)
result, err := getUser(c, &users.UserGetRequest{
Email: "tantianran@qq.com",
Id: 801896,
})
if err != nil {
log.Fatal(err)
}
// 打印响应
log.Printf("收到响应: %s %s %s %dn", result.User.Id, result.User.FirstName, result.User.LastName, result.User.Age)
}
Part4验证效果
服务器
tantianran@go-dev:~/goCode/src/user-service/server$ go run server.go
2023/07/12 00:59:01 已接收到邮件地址: tantianran@qq.com, 还有ID: 801896
客户端
tantianran@go-dev:~/goCode/src/user-service/client$ go run main.go localhost:50051
2023/07/12 00:59:01 收到响应: user-782935 tan tianran 30
原文始发于微信公众号(不背锅运维):Go实战:开发一个简单的gRPC Demo
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/149378.html