采用go-micro,gin,etcd完成微服务开发

1.介绍

  • Go Micro 是一个分布式系统开发框架。Go Micro 提供了分布式系统开发的核心需求,包括 RPC 和事件驱动的通信。Gin 是一个用 Golang 编写的 web 框架。etcd 是一个开源的分布式键值存储系统,用于可靠地存储分布式系统中的关键数据。通过Gin作为微服务的网关,通过etcd服务注册,完成各个子组件的调用

2.环境准备

  • 安装 go1.20.4
  • 安装 protoc、protoc-gen-go 和 protoc-gen-micro
  • 安装 etcd并启动

3.编写proto文件

  • 采用protoc --micro_out=. --go_out=:. .proto命令生成.pb.go和*.pb.micro.go文件
syntax = "proto3";

package user;

option go_package = "../user";

service UserService {
  rpc GetUser (UserRequest) returns (Response) {}
}

message UserRequest{
   int64 page = 1;
   int64 size = 2;
}

message Response {
  int32 code = 1;
  bytes data = 2;
} 

4.完成RPC服务代码的编写

  • 编写UserServiceHandler的实现结构体,需要实现GetUser方法(备注:UserServiceHandler是通过protoc命令自动生成的)
  • 将rpc服务注册到etcd中并返回服务器实例
  • 调用RegisterUserServiceHandler函数将UserServiceHandler的实现结构体注册到服务器实例中
  • 调用服务器实例的Run函数完成服务的启动

handler.go

type User struct {
	dao dao.Dao //数据库实例
}

func NewUserHandler(d dao.Dao) *User {
	return &User{dao: d}
}

func (u User) GetUser(ctx context.Context, request *user.UserRequest, response *user.Response) error {
	return nil
}

main.go

package main

import (
	"github.com/go-micro/plugins/v4/registry/etcd"
	"go-micro.dev/v4"
	"go-micro.dev/v4/registry"
	"study/go_micro_test/proto/user"
	"study/go_micro_test/user-srv/handler"
)

func main() {
	userHandler := handler.NewUserHandler(daoAll)

	// 使用etcd作为默认注册中心
	etcdRegistry := etcd.NewRegistry(func(opt *registry.Options) {
		opt.Addrs = []string{"etcd服务地址+端口号"}
	})

	// 创建服务,除了服务名,其它选项可加可不加,比如Version版本号、Metadata元数据等
	srv := micro.NewService(
		micro.Name("user"),
		micro.Version("latest"),
		micro.Registry(etcdRegistry), // 使用etcd注册中心
	)
	err := user.RegisterUserServiceHandler(srv.Server(), userHandler)
	if err != nil {
		return
	}
	err = srv.Run()
	if err != nil {
		return
	}

}

1.编写网关服务

  • 实例化gin服务
  • 实例化所有路由
  • 创建服务端实例并进行实例化
  • 初始化所有的rpc服务便于后续直接调用,这里采用的是go-micro.dev/v4/client
  • 将gin服务绑定到服务端实例中
  • 启动服务端实例

main.go

package main

import (
	"context"
	"github.com/gin-gonic/gin"
	"github.com/go-micro/plugins/v4/registry/etcd"
	"go-micro.dev/v4/registry"
	"go-micro.dev/v4/web"
	"study/go_micro_test/api-gateway/handler/api/user"
	"study/go_micro_test/api-gateway/router"
	"study/go_micro_test/api-gateway/rpc"
)

func Router(router gin.IRouter) {
	root := router.Group("/test")
	UserRouter(root)
}
func UserRouter(root *gin.RouterGroup) {
	local := root.Group("/user")

	local.GET("/getUser", GetUser)

}
func GetUser(ctx *gin.Context) {
	rpc.UserClient.GetUser(context.Background(), &user.UserRequest{Page: page, Size: size})
}

func main() {
	engine := gin.Default()
	Router(engine)
	etcdRegistry := etcd.NewRegistry(func(opt *registry.Options) {
		opt.Addrs = []string{"127.0.0.1:2379"}
	})

	webService := web.NewService(
		web.Name("web"),
		web.Address(":8080"),
		web.Registry(etcdRegistry),
	)
	err := webService.Init()
	if err != nil {
		return
	}
	rpc.InitClients()
	webService.Handle("/", engine)

	err = webService.Run()
	if err != nil {
		return
	}

}
client.go
package rpc

import (
	"go-micro.dev/v4/client"
	"study/go_micro_test/proto/user"
)

var UserClient user.UserService

func InitClients() {
	cl := client.DefaultClient
	UserClient = user.NewUserService("user", cl)
}
posted @ 2024-10-29 15:12  9912  阅读(15)  评论(0编辑  收藏  举报