这是一篇关于grpc,etcd,grpc-gateway的实践
目录
相关工具安装
1. protocol安装
下载地址:
https://github.com/protocolbuffers/protobuf/releases
我选的是windows环境的
下载完之后,解压到文件夹内,并添加环境变量。
2. grpc,grpc-gateway安装
代码地址
https://github.com/grpc/grpc-go/tags
golang package
go get -u google.golang.org/grpc
go get google.golang.org/protobuf
// 会在go安装目录 go/bin下生成一个protoc-gen-go.exe
go get -u github.com/golang/protobuf/protoc-gen-go
// go/bin下protoc-gen-grpc-gateway.exe
go get -u github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway
3. etcd安装
docker 安装etcd并运行
- 拉取镜像 https://hub.docker.com/r/bitnami/etcd
docker pull bitnami/etcd:3.4.20
- 创建docker网络
docker network create etcd-bridge --driver bridge
- 运行
docker run -d --name etcd-server \
--network etcd-bridge \
--publish 2379:2379 \
--publish 2380:2380 \
--env ALLOW_NONE_AUTHENTICATION=yes \
--env ETCD_ADVERTISE_CLIENT_URLS=http://etcd-server:2379 \
bitnami/etcd:3.4.20
一个基础微服务demo
1. 程序结构目录
/rpc
/client
-main.go
/etcd_service
-etcd.go
/proto
-product.proto
/proto_service
-pruduct.pb.go
-pruduct.pb.gw.go
/server
-main.go
-pruduct.go
-main.go
2. proto文件
// 使用的语法版本
syntax = "proto3";
// 生成的go文件包
option go_package = "./proto_service";
//service 服务 接口
service ProdService {
rpc GetProductStock(ProductRequest) returns (ProductResponse);
}
// 请求参数
message ProductRequest {
int32 prod_id = 1;
}
// 返回参数
message ProductResponse {
int32 prod_stock = 1;
}
生成go文件
pwd
/rpc/proto
protoc --go_out=plugins=grpc:../ product.proto
命令会直接生成proto_service目录和product.pb.go文件
3. 服务端
product.go
package main
import (
"context"
"log"
"rpc/proto_service"
)
// 建一个实例
var ProductService = &productService{
}
type productService struct {
}
// 服务端实现接口业务内容
func (p productService) GetProductStock(ctx context.Context, request *proto_service.ProductRequest) (*proto_service.ProductResponse, error) {
log.Println("request: ", request)
return &proto_service.ProductResponse{
ProdStock: request.ProdId*1000 + 996}, nil
}
main.go
package main
import (
"google.golang.org/grpc"
"log"
"net"
"rpc/proto_service"
)
const addr = "127.0.0.1:8001"
func main() {
rpcServer := grpc.NewServer()
proto_service.RegisterProdServiceServer(rpcServer, ProductService)
listener, err := net.Listen("tcp", addr)
if err != nil {
log.Fatal("启动监听出错", err)
}
err = rpcServer.Serve(listener)
if err != nil {
log.Fatal("启动服务出错", err)
}
}
开启服务
go run main.go
4. 客户端代码
client/main.go
package main
import (
"context"
"fmt"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
"log"
"rpc/proto_service"
"time"
)
const addr = "127.0.0.1:8001"
func main() {
conn, err := grpc.Dial(addr,grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
log.Fatal("服务端出错,连接不上:", err)
}
defer conn.Close()
client := proto_service.NewProdServiceClient(conn)
for i := 0; i < 100; i