Revert "Revert "V0.4.0 imporve error response""

This reverts commit 9744f45e86.
This commit is contained in:
yaziming
2019-09-04 20:41:37 +08:00
parent bb4ec17125
commit 6dc687192e
51 changed files with 1373 additions and 416 deletions

View File

@@ -1,6 +1,7 @@
package services
import (
"context"
"crawlab/constants"
"crawlab/database"
"crawlab/lib/cron"
@@ -10,6 +11,7 @@ import (
"fmt"
"github.com/apex/log"
"github.com/globalsign/mgo/bson"
"github.com/gomodule/redigo/redis"
"github.com/spf13/viper"
"runtime/debug"
"time"
@@ -73,23 +75,11 @@ func GetCurrentNode() (model.Node, error) {
if err != nil {
// 如果为主节点,表示为第一次注册,插入节点信息
if IsMaster() {
// 获取本机IP地址
ip, err := register.GetRegister().GetIp()
// 获取本机信息
ip, mac, key, err := model.GetNodeBaseInfo()
if err != nil {
debug.PrintStack()
return model.Node{}, err
}
mac, err := register.GetRegister().GetMac()
if err != nil {
debug.PrintStack()
return model.Node{}, err
}
key, err := register.GetRegister().GetKey()
if err != nil {
debug.PrintStack()
return model.Node{}, err
return node, err
}
// 生成节点
@@ -97,7 +87,7 @@ func GetCurrentNode() (model.Node, error) {
Key: key,
Id: bson.NewObjectId(),
Ip: ip,
Name: key,
Name: ip,
Mac: mac,
IsMaster: true,
}
@@ -124,6 +114,7 @@ func IsMaster() bool {
return viper.GetString("server.master") == Yes
}
// 所有调用IsMasterNode的方法都永远会在master节点执行所以GetCurrentNode方法返回永远是master节点
// 该ID的节点是否为主节点
func IsMasterNode(id string) bool {
curNode, _ := GetCurrentNode()
@@ -176,72 +167,54 @@ func UpdateNodeStatus() {
// 在Redis中删除该节点
if err := database.RedisClient.HDel("nodes", data.Key); err != nil {
log.Errorf(err.Error())
return
}
// 在MongoDB中该节点设置状态为离线
s, c := database.GetCol("nodes")
defer s.Close()
var node model.Node
if err := c.Find(bson.M{"key": key}).One(&node); err != nil {
log.Errorf(err.Error())
debug.PrintStack()
return
}
node.Status = constants.StatusOffline
if err := node.Save(); err != nil {
log.Errorf(err.Error())
return
}
continue
}
// 更新节点信息到数据库
s, c := database.GetCol("nodes")
defer s.Close()
var node model.Node
if err := c.Find(bson.M{"key": key}).One(&node); err != nil {
// 数据库不存在该节点
node = model.Node{
Key: key,
Name: key,
Ip: data.Ip,
Port: "8000",
Mac: data.Mac,
Status: constants.StatusOnline,
IsMaster: data.Master,
}
if err := node.Add(); err != nil {
log.Errorf(err.Error())
return
}
} else {
// 数据库存在该节点
node.Status = constants.StatusOnline
if err := node.Save(); err != nil {
log.Errorf(err.Error())
return
}
// 处理node信息
handleNodeInfo(key, data)
}
// 重置不在redis的key为offline
model.ResetNodeStatusToOffline(list)
}
func handleNodeInfo(key string, data Data) {
// 更新节点信息到数据库
s, c := database.GetCol("nodes")
defer s.Close()
// 同个key可能因为并发被注册多次
var nodes []model.Node
_ = c.Find(bson.M{"key": key}).All(&nodes)
if nodes != nil && len(nodes) > 1 {
for _, node := range nodes {
_ = c.RemoveId(node.Id)
}
}
// 遍历数据库中的节点列表
nodes, err := model.GetNodeList(nil)
for _, node := range nodes {
hasNode := false
for _, key := range list {
if key == node.Key {
hasNode = true
break
}
var node model.Node
if err := c.Find(bson.M{"key": key}).One(&node); err != nil {
// 数据库不存在该节点
node = model.Node{
Key: key,
Name: data.Ip,
Ip: data.Ip,
Port: "8000",
Mac: data.Mac,
Status: constants.StatusOnline,
IsMaster: data.Master,
}
if !hasNode {
node.Status = constants.StatusOffline
if err := node.Save(); err != nil {
log.Errorf(err.Error())
return
}
continue
if err := node.Add(); err != nil {
log.Errorf(err.Error())
return
}
} else {
// 数据库存在该节点
node.Status = constants.StatusOnline
if err := node.Save(); err != nil {
log.Errorf(err.Error())
return
}
}
}
@@ -287,13 +260,12 @@ func UpdateNodeData() {
}
}
func MasterNodeCallback(channel string, msgStr string) {
func MasterNodeCallback(message redis.Message) (err error) {
// 反序列化
var msg NodeMessage
if err := json.Unmarshal([]byte(msgStr), &msg); err != nil {
log.Errorf(err.Error())
debug.PrintStack()
return
if err := json.Unmarshal(message.Data, &msg); err != nil {
return err
}
if msg.Type == constants.MsgTypeGetLog {
@@ -310,16 +282,15 @@ func MasterNodeCallback(channel string, msgStr string) {
sysInfoBytes, _ := json.Marshal(&msg.SysInfo)
ch <- string(sysInfoBytes)
}
return nil
}
func WorkerNodeCallback(channel string, msgStr string) {
func WorkerNodeCallback(message redis.Message) (err error) {
// 反序列化
msg := NodeMessage{}
fmt.Println(msgStr)
if err := json.Unmarshal([]byte(msgStr), &msg); err != nil {
log.Errorf(err.Error())
debug.PrintStack()
return
if err := json.Unmarshal(message.Data, &msg); err != nil {
return err
}
if msg.Type == constants.MsgTypeGetLog {
@@ -333,26 +304,27 @@ func WorkerNodeCallback(channel string, msgStr string) {
// 获取本地日志
logStr, err := GetLocalLog(msg.LogPath)
log.Info(string(logStr))
if err != nil {
log.Errorf(err.Error())
debug.PrintStack()
msgSd.Error = err.Error()
msgSd.Log = err.Error()
} else {
msgSd.Log = string(logStr)
}
msgSd.Log = string(logStr)
// 序列化
msgSdBytes, err := json.Marshal(&msgSd)
if err != nil {
log.Errorf(err.Error())
debug.PrintStack()
return
return err
}
// 发布消息给主节点
fmt.Println(msgSd)
if err := database.Publish("nodes:master", string(msgSdBytes)); err != nil {
log.Errorf(err.Error())
return
log.Info("publish get log msg to master")
if _, err := database.RedisClient.Publish("nodes:master", string(msgSdBytes)); err != nil {
return err
}
} else if msg.Type == constants.MsgTypeCancelTask {
// 取消任务
@@ -362,8 +334,7 @@ func WorkerNodeCallback(channel string, msgStr string) {
// 获取环境信息
sysInfo, err := GetLocalSystemInfo()
if err != nil {
log.Errorf(err.Error())
return
return err
}
msgSd := NodeMessage{
Type: constants.MsgTypeGetSystemInfo,
@@ -374,14 +345,14 @@ func WorkerNodeCallback(channel string, msgStr string) {
if err != nil {
log.Errorf(err.Error())
debug.PrintStack()
return
return err
}
fmt.Println(msgSd)
if err := database.Publish("nodes:master", string(msgSdBytes)); err != nil {
if _, err := database.RedisClient.Publish("nodes:master", string(msgSdBytes)); err != nil {
log.Errorf(err.Error())
return
return err
}
}
return
}
// 初始化节点服务
@@ -399,25 +370,27 @@ func InitNodeService() error {
// 首次更新节点数据注册到Redis
UpdateNodeData()
// 消息订阅
var sub database.Subscriber
sub.Connect()
// 获取当前节点
node, err := GetCurrentNode()
if err != nil {
log.Errorf(err.Error())
return err
}
ctx := context.Background()
if IsMaster() {
// 如果为主节点,订阅主节点通信频道
channel := "nodes:master"
sub.Subscribe(channel, MasterNodeCallback)
err := database.RedisClient.Subscribe(ctx, MasterNodeCallback, channel)
if err != nil {
return err
}
} else {
// 若为工作节点,订阅单独指定通信频道
channel := "nodes:" + node.Id.Hex()
sub.Subscribe(channel, WorkerNodeCallback)
err := database.RedisClient.Subscribe(ctx, WorkerNodeCallback, channel)
if err != nil {
return err
}
}
// 如果为主节点每30秒刷新所有节点信息