这是我参与「第五届青训营 」伴学笔记创作活动的第 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进行处理 另外,在开发中,每个服务编写健康监测函数。在发现服务后,再调用一遍健康检测函数来确保服务端是出于正常运行的状态。