golang 学习之 etcd protobuffer grpc 服务注册发现 go-micro

发布时间 2023-06-03 12:23:14作者: 李皇皓

1.etcd使用步骤

1)下载:https://github.com/etcd-io/etcd/releases/

2)配置环境变量

3)编辑local-cluster-profile文件:(利用goreman 启动方式,生产环境参考官方文档)

etcd1: etcd --name infra1 --listen-client-urls http://127.0.0.1:2379 --advertise-client-urls http://127.0.0.1:2379 --listen-peer-urls http://127.0.0.1:2380 --initial-advertise-peer-urls http://127.0.0.1:2380 --initial-cluster-token etcd-cluster-1 --initial-cluster infra1=http://127.0.0.1:2380,infra2=http://127.0.0.1:3380,infra3=http://127.0.0.1:4380 --initial-cluster-state new --enable-pprof --logger=zap --log-outputs=stderr
etcd2: etcd --name infra2 --listen-client-urls http://127.0.0.1:3379 --advertise-client-urls http://127.0.0.1:3379 --listen-peer-urls http://127.0.0.1:3380 --initial-advertise-peer-urls http://127.0.0.1:3380 --initial-cluster-token etcd-cluster-1 --initial-cluster infra1=http://127.0.0.1:2380,infra2=http://127.0.0.1:3380,infra3=http://127.0.0.1:4380 --initial-cluster-state new --enable-pprof --logger=zap --log-outputs=stderr
etcd3: etcd --name infra3 --listen-client-urls http://127.0.0.1:4379 --advertise-client-urls http://127.0.0.1:4379 --listen-peer-urls http://127.0.0.1:4380 --initial-advertise-peer-urls http://127.0.0.1:4380 --initial-cluster-token etcd-cluster-1 --initial-cluster infra1=http://127.0.0.1:2380,infra2=http://127.0.0.1:3380,infra3=http://127.0.0.1:4380 --initial-cluster-state new --enable-pprof --logger=zap --log-outputs=stderr

4)启动etcd集群:goreman -f local-cluster-profile start

2.protobuffer 使用步骤:

1)下载 https://github.com/protocolbuffers/protobuf/releases

2)配置环境变量

3)安装protoc-gen-go: go install github.com/golang/protobuf/protoc-gen-go@latest

4)新建项目proto,目录结构如下:

	proto/
		proto/
			userinfo.proto
		main.go

5)编辑userinfo.proto(代码如下):

// 注意;号
syntax = "proto3";
option go_package = "./userService;";
message userinfo{
    string username = 1;
    int32 age = 2;
    repeated string hobby = 3;
}

// 编译命令 cd proto && protoc --go_out=./ *.proto

6)回到项目根目录并且执行命令:go mod init proto && go mod tidy //自动安装上一步生成的pb.go中的依赖

7)编辑main.go (代码如下):

package main

import (
	"fmt"
	"proto/proto/userService"

	"google.golang.org/protobuf/proto"
)

func main() {
	u := &userService.Userinfo{
		Username: "lihh",
		Age:      31,
		Hobby:    []string{"a", "b", "c"},
	}
	fmt.Println(u)

	// proto 序列化
	data, _ := proto.Marshal(u)
	fmt.Println(data)

	// proto 反序列化
	user := userService.Userinfo{}
	proto.Unmarshal(data, &user)
	fmt.Println(&user, user.GetUsername())
}

附)生成grpc服务所需proto(示例代码如下,注意编译命令与上面不同):

syntax = "proto3";

option go_package = "./goodsService;";

// 定义rpc服务
service GoodsService {
    rpc AddGoods(AddGoodsReq) returns (AddGoodsRes);
    rpc GetGoods(GetGoodsReq) returns (GetGoodsRes);
}

message GoodsMode {
    string title = 1; 
    double price = 2;
    string content = 3;
}

// AddGoods 相关参数
message AddGoodsReq {
    GoodsMode params = 1;
}

message AddGoodsRes {
    string message = 1; 
    bool success = 2;
}

// GetGoods 相关参数
message GetGoodsReq {
    int32 id = 1;
}
message GetGoodsRes {
    repeated GoodsMode result = 1;
}

// 编译命令 protoc --go_out=plugins=grpc:./ *.proto

3.grpc

1)安装:go get -u -v google.golang.org/grpc

2)创建proto目录,生成proto:

目录结构:
	proto/
		greeter/
			greeter.pb.go
		greeter.proto
greeter.proto代码如下:

syntax = "proto3";
option go_package="./greeter";

service Greeter {
    rpc SayHello(HelloReq) returns (HelloRes);
}

message HelloReq {
    string name = 1;
}

message HelloRes {
    string message = 1;
}
// 编译命令 protoc --go_out=plugins=grpc:./ *.proto

3)server代码:

目录结构:
	greeter/
		proto/ (第2步构建的proto文件夹)
		main.go
main.go代码如下:

package main

import (
	"context"
	"fmt"
	"greeter/proto/greeter"
	"net"

	"google.golang.org/grpc"
)

// 1.定义远程调用的结构体喝方法 实现GreeterServer接口 interface
type Hello struct {
}

func (this *Hello) SayHello(c context.Context, req *greeter.HelloReq) (*greeter.HelloRes, error) {
	fmt.Println(req)

	return &greeter.HelloRes{
		Message: req.Name + ", hello",
	}, nil
}

func main() {
	// 1. 初始化 grpc对象
	grpcServer := grpc.NewServer()

	// 2. 注册服务
	greeter.RegisterGreeterServer(grpcServer, &Hello{})

	// 3. 监听端口
	listenner, err := net.Listen("tcp", "0.0.0.0:8001")
	if err != nil {
		fmt.Println(err)
	}

	// 4. 启动服务
	grpcServer.Serve(listenner)
}

执行命令:go mod init greeter && go mod tidy && go run main.go

4)client代码:

目录结构:
	greeter/
		proto/ (第2步构建的proto文件夹)
		main.go
main.go代码如下:

package main

import (
	"greeter/proto/greeter"
	"context"
	"fmt"

	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials/insecure"
)

func main() {
	// 1. 建立连接
	/*
		credentials.NewClientTLSFromFile:从输入的证书文件中为客户端构造TLS凭证
		grpc.WithTransportCredentials:配置连接级别的安全凭证(例如,TLS/SSL),返回一个DialOption,用于连接服务器
	*/
	grpcClient, err := grpc.Dial("0.0.0.0:8001", grpc.WithTransportCredentials(insecure.NewCredentials()))
	if err != nil {
		fmt.Println(err)
	}

	// 2. 注册客户端
	client := greeter.NewGreeterClient(grpcClient)
	res, err := client.SayHello(context.Background(), &greeter.HelloReq{
		Name: "lihh",
	})
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println(res, res.GetMessage())

}

执行命令:go mod init greeter && go mod tidy && go run main.go

4.服务注册发现(学习中)

5.go-micro(学习中)