Go 语言微服务框架 Kratos 服务注册与发现

开发 前端
Go 语言微服务框架 Kratos 服务注册与发现,支持多种注册中心,本文我们以 Consul 为例,介绍 Kratos 项目怎么实现服务注册与发现。

1.介绍

Go 语言微服务框架 Kratos 服务注册与发现,支持多种注册中心,本文我们以 Consul 为例,介绍 Kratos 项目怎么实现服务注册与发现。

以 blog 项目作为 RPC 服务端,我们再创建一个 blog-client 项目作为 RPC 客户端。

2.服务注册

我们通过改造 blog 项目的代码,将 blog 服务作为 RPC 服务端,注册到 Consul 中。

创建 Consul 注册中心

在 blog/internal 目录中,创建 registry 目录,并创建 consul.go 和 registry.go 文件。

编写 blog/internal/registry/consul.go 文件。

func NewConsulRegistry(c *conf.Registry) *consul.Registry {
 client, err := api.NewClient(&api.Config{
  Address: c.Consul.Addr,
  Scheme:  c.Consul.Schema,
 })
 if err != nil {
  panic(err)
 }
 return consul.New(client)
}

编写 blog/internal/registry/registry.go 文件。

var ProviderSet = wire.NewSet(NewConsulRegistry)

编写 blog/cmd/blog/wire.go 文件。

func wireApp(*conf.Server, *conf.Data, *conf.Registry, log.Logger) (*kratos.App, func(), error) {
 panic(wire.Build(server.ProviderSet, data.ProviderSet, biz.ProviderSet, service.ProviderSet, registry.ProviderSet, newApp))
}

wire 生成文件

cd /root/go/src/blog/cmd/blog
wire

编写 blog/cmd/blog/main.go 文件。

func newApp(conf *conf.Server, logger log.Logger, gs *grpc.Server, hs *http.Server, registry *consul.Registry) *kratos.App {
 return kratos.New(
  kratos.ID(id),
  kratos.Name(conf.Name),
  kratos.Version(conf.Version),
  kratos.Metadata(map[string]string{}),
  kratos.Logger(logger),
  kratos.Server(
   gs,
   hs,
  ),
  kratos.Registrar(registry),
 )
}

运行项目

cd /root/go/src/blog/cmd/blog
kratos run

访问 consul UI

在浏览器中访问 http://IP:8500/ui/dc1/services,检查 blog 服务的注册状态。

3.服务发现

使用 kratos 创建一个客户端项目 blog-client。

创建 Consul 注册中心

在 blog-client/internal 目录中,创建 registry 目录,并创建 consul.go 和 registry.go 文件。

编写 blog-client/internal/registry/consul.go 文件。

func NewConsulRegistry(c *conf.Registry) *consul.Registry {
 client, err := api.NewClient(&api.Config{
  Address: c.Consul.Addr,
  Scheme:  c.Consul.Schema,
 })
 if err != nil {
  panic(err)
 }
 return consul.New(client)
}

编写 blog-client/internal/registry/registry.go 文件。

var ProviderSet = wire.NewSet(NewConsulRegistry)

创建 RPC 客户端

在 blog-client/internal 目录中,创建 client 目录,并创建 blog_client.go 和 client.go 文件。

编写 blog-client/internal/client/blog_client.go 文件。

func NewBlogClient(registry *consul.Registry, logger log.Logger) (v1.UserClient, error) {
 conn, err := grpc.DialInsecure(
  context.Background(),
  grpc.WithEndpoint("discovery:///blog"),
  grpc.WithDiscovery(registry),
  grpc.WithMiddleware(
   recovery.Recovery(),
  ),
  grpc.WithNodeFilter(
   filter.Version("1.0.0")),
 )
 if err != nil {
  log.NewHelper(logger).WithContext(context.Background()).Errorw("err", err)
  return nil, err
 }
 return v1.NewUserClient(conn), nil
}

编写 blog-client/internal/client/client.go 文件。

var ProviderSet = wire.NewSet(NewBlogClient)

拷贝 pb 文件

拷贝 /root/go/src/blog/api/user 目录,粘帖到 /root/go/src/blog-client/api 目录。

创建 domain 和 usecase 层

创建 blog-client/internal/biz/user.go 文件。

type User struct {
 Id       int64 `xorm:"autoincr"`
 Name     string
 Email    string
 Password string
 Created  int64 `xorm:"created"`
 Updated  int64 `xorm:"updated"`
}

type UserUsecase struct {
 rpcClient v1.UserClient
}

func NewUserUsecase(client v1.UserClient) *UserUsecase {
 return &UserUsecase{
  rpcClient: client,
 }
}

func (u *UserUsecase) GetUser(ctx context.Context, user *User) (reply *v1.GetUserReply, err error) {
 req := &v1.GetUserRequest{
  Id: user.Id,
 }
 reply, err = u.rpcClient.GetUser(ctx, req)
 if err != nil {
  return nil, err
 }
 return
}

编写 blog-client/internal/biz/biz.go 文件。

var ProviderSet = wire.NewSet(NewUserUsecase)

生成 server 源码

cd /root/go/src/blog-client
kratos proto server api/user/v1/user.proto

编写生成文件 internal/service/user.go。

func (s *UserService) GetUser(ctx context.Context, req *v1.GetUserRequest) (*v1.GetUserReply, error) {
 user := &biz.User{
  Id: req.Id,
 }
 reply, err := s.userUcase.GetUser(ctx, user)
 if err != nil {
  return nil, err
 }
 return &v1.GetUserReply{
  Name: reply.Name,
 }, nil
}

编写 blog-client/internal/service/service.go 文件。

var ProviderSet = wire.NewSet(NewUserService)

添加 wire 提供者

编写 blog-client/cmd/blog-client/wire.go 文件。

func wireApp(*conf.Server, *conf.Data, *conf.Registry, log.Logger) (*kratos.App, func(), error) {
 panic(wire.Build(server.ProviderSet, biz.ProviderSet, registry.ProviderSet, service.ProviderSet, client.ProviderSet, newApp))
}

wire 生成文件

cd /root/go/src/blog-client/cmd/blog-client
wire

运行项目

cd /root/go/src/blog-client/cmd/blog
kratos run

curl 请求示例

curl -H "Content-Type: application/json" -X GET http://192.168.110.209:8001/user/get/1
{"name":"frank"}

4.总结

本文我们通过示例代码,介绍 Kratos 项目怎么实现服务注册与发现。

需要注意的是,RPC 服务端和 RPC 客户端的端口不能相同。

责任编辑:武晓燕 来源: Golang语言开发栈
相关推荐

2014-03-14 10:17:11

2014技术编程

2018-09-06 11:20:24

CDNDDoS网站

2024-04-11 08:09:44

云原生技术栈云计算

2022-06-16 15:54:32

前端

2015-03-10 11:21:44

JavaScript组JavaScript

2024-03-14 09:07:05

刷数任务维度后端

2022-10-17 10:28:05

Web 组件代码

2024-05-28 07:06:44

2022-04-27 07:15:36

中台产品微服务

2019-05-15 09:26:50

后台技术栈系统

2014-03-12 10:00:26

移动开发跨平台

2024-04-01 11:52:46

2017-07-26 13:51:19

前端JavaScriptTypeScript

2017-08-07 18:45:51

前端JavaScript技术栈

2011-07-15 16:45:23

技术人员

2022-09-28 13:57:41

鸿蒙开源

2015-07-28 10:39:34

程序员知识

2021-09-08 15:43:03

在线写作协作文档办公软件

2024-05-20 01:10:00

Promise变量

2018-12-28 10:21:03

Ceph构件组件
点赞
收藏

51CTO技术栈公众号