微服务gRPC学习笔记(二)| 青训营笔记

840 阅读2分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 9 天

我们使用微服务架构来使用完成这次简单的抖音功能实现,我的任务主要是实现用户注册以及登录功能。 所以我主要的技术也是在用户登录或者注册这里,所以我们通过用户登录和注册功能来熟悉一下微服务框架以及gRPC框架的使用

用户信息

我们的用户信息微服务结构如下

--center

center主要是用来存consul.go文件

consul用来注册服务以及健康检查

func init() {
  var err error
  config := consul.DefaultConfig()
  config.Address = addr
  client, err = consul.NewClient(config)
  if err != nil {
     log.Fatalf("failed to init consul: %v", err)
  }
}

--cmd

cmd目录主要是存放main文件,用来启动rpc服务器

func main() {
  flag.Parse()
  lis, err := net.Listen("tcp", fmt.Sprintf(":%d", *port))
  if err != nil {
     log.Fatalf("failed to listen: %v", err)
  }
  s := grpc.NewServer()
  service.RegisterUserServer(s, &server.UserSrv{})
  // 健康检查
  grpc_health_v1.RegisterHealthServer(s, &server.HealthImpl{})

  // 服务注册
  err = center.Register(consul.AgentServiceRegistration{
     ID:      "user-1", // 服务节点的名称
     Name:    "user",   // 服务名称
     Port:    *port,    // 服务端口
     Address: *addr,    // 服务 IP
     Check: &consul.AgentServiceCheck{ // 健康检查
        Interval:                       "5s", // 健康检查间隔
        GRPC:                           fmt.Sprintf("%v:%v/%v", *addr, *port, "health"),
        DeregisterCriticalServiceAfter: "10s", // 注销时间,相当于过期时间
     },
  })
  if err != nil {
     log.Fatalf("failed to register service: %v", err)
  }

  log.Printf("server listening at %v", lis.Addr())
  if err := s.Serve(lis); err != nil {
     log.Fatalf("failed to serve: %v", err)
  }
}

--config

config用来存放配置文件,主要的功能就是配置manger管理器,用来进行服务管理。

func (m *Manager) ReadConfig(c Config) error {
 log.Println("[CONFIG] READING", c.Key())
 config, err := center.GetValue(c.Key())
 if err != nil {
    return err
 }

 err = json.Unmarshal(config, &c)
 if err != nil {
    return err
 }
 return nil
}

--internal

internal下面存有三个包

server用来进行业务处理

service用来进行grpc协议转换

store用来进行缓存以及储存

--pkg

储存工具类

--go.mod

gomod依赖管理

然后今天写代码遇到一个错误

go微服务调用报错:last resolver error: produced zero addresses

原因很奇怪,grpc服务器如果启动过久,网关调用会出现这个报错,也就是调用失败。这个bug错误真的很奇怪,所以我探索了一下。

情况一

服务端的配置文件中,ip地址设置成了0.0.0.0。然后注册到consul后,客户端发现的服务ip自然是0.0.0.0。此时当然调用不了服务端。 参考方案: 只需要检查配置文件,把ip改为正确地址就行了。

情况二

向consul注册中心发现服务时,consul匹配不到相同的服务,导致返回的地址为0.0.0.0。 参考方案: 此时通过consul检查服务端的健康状况,有问题及时纠正。 另外检查在配置文件中,检查consul的host和port是否配置正确。

总结

在发现服务后,需要对error进行处理 另外,在开发中,每个服务编写健康监测函数。在发现服务后,再调用一遍健康检测函数来确保服务端是出于正常运行的状态。