From 2cd1af13bc4e7aec4c85b9fe88db2d294af6468f Mon Sep 17 00:00:00 2001 From: zhangzengfei <zhangzengfei@smartai.com> Date: 星期日, 08 十月 2023 11:24:37 +0800 Subject: [PATCH] 修复集群同步功能 --- system-service/models/defHeadPic.go | 23 +- sysinfo-service/main.go | 28 ++- system-service/controllers/cluster.go | 43 ++++++ system-service/service/clusterService.go | 57 ++++--- system-service/service/proc.go | 5 system-service/serf/dbLogger.go | 15 -- system-service/serf/handler.go | 21 ++ system-service/main.go | 8 system-service/models/db.go | 68 --------- system-service/serf/serf.go | 23 ++ system-service/models/cluster.go | 28 ++- system-service/service/SysService.go | 19 +- system-service/serf/sync.go | 25 +++ 13 files changed, 207 insertions(+), 156 deletions(-) diff --git a/sysinfo-service/main.go b/sysinfo-service/main.go index 23e3e25..7e56ff0 100644 --- a/sysinfo-service/main.go +++ b/sysinfo-service/main.go @@ -18,10 +18,10 @@ var ( procName = service.ProcName - proc = &bhomeclient.ProcInfo{ + proc = &bhomeclient.ProcInfo{ Name: procName, //杩涚▼鍚嶇О - ID: procName, //杩涚▼id - Info: "", //杩涚▼鐨勬弿杩颁俊鎭紝鐢ㄤ簬鍖哄垎鍚屼竴杩涚▼鍚嶇О涓嬪涓繘绋� + ID: procName, //杩涚▼id + Info: "", //杩涚▼鐨勬弿杩颁俊鎭紝鐢ㄤ簬鍖哄垎鍚屼竴杩涚▼鍚嶇О涓嬪涓繘绋� } env = flag.String("e", "pro", "") ) @@ -33,24 +33,24 @@ config.Init(*env) // 鏃ュ織鍒濆鍖� - var logFile = config.LogConf.Path + "vamicro-"+procName+".log" + var logFile = config.LogConf.Path + "vamicro-" + procName + ".log" logger.InitLogger(logFile, config.LogConf.Level, config.LogConf.MaxSize, config.LogConf.MaxBackups, config.LogConf.MaxAge) logger.Info("log init success !") } -func main(){ +func main() { // pprof 鐢ㄤ簬鍒嗘瀽鎬ц兘 //go func() { // logger.Info(http.ListenAndServe("0.0.0.0:6079", nil)) //}() - fm,pubTopics := initFuncMap() + fm, pubTopics := initFuncMap() ctx, cancel := context.WithCancel(context.Background()) - var reg = &bhomeclient.RegisterInfo { - Proc: *proc, - Channel: nil, - PubTopic: pubTopics, - SubTopic: []string{}, + var reg = &bhomeclient.RegisterInfo{ + Proc: *proc, + Channel: nil, + PubTopic: pubTopics, + SubTopic: []string{}, SubNetTopic: []string{}, } @@ -58,7 +58,7 @@ signal.Notify(q, os.Interrupt, os.Kill, syscall.SIGTERM) ms, err := bhomeclient.NewMicroNode(ctx, q, config.Server.AnalyServerId, reg, logger.Debug) - if err !=nil { + if err != nil { return } @@ -76,6 +76,7 @@ } const urlPrefix = "/data/api-v" + func initFuncMap() (map[string]bhomeclient.MicroFunc, []string) { funcMap := make(map[string]bhomeclient.MicroFunc) @@ -84,8 +85,9 @@ funcMap[urlPrefix+"/sysinfo/showProcesses"] = controllers.ShowVasystemProcesses var pubTopics []string - for key,_ := range funcMap { + for key, _ := range funcMap { pubTopics = append(pubTopics, key) } + return funcMap, pubTopics } diff --git a/system-service/controllers/cluster.go b/system-service/controllers/cluster.go index bcc88ec..eb8bddf 100644 --- a/system-service/controllers/cluster.go +++ b/system-service/controllers/cluster.go @@ -1,6 +1,7 @@ package controllers import ( + "vamicro/config" "vamicro/system-service/models" "vamicro/system-service/service" "vamicro/system-service/vo" @@ -13,6 +14,48 @@ type ClusterController struct { } +// @Summary 鏌ヨ褰撳墠闆嗙兢鐘舵�� +// @Description 鏌ヨ鏈湴闆嗙兢 +// @Produce json +// @Tags cluster +// @Success 200 {string} json "{"code":200, success:true, msg:"", data:""}" +// @Failure 500 {string} json "{"code":500, success:false, msg:"",data:""}" +// @Router /data/api-v/cluster/status [get] +func (cc ClusterController) GetClusterStat(h *bhomeclient.WrapperHandler, c *bhomeclient.Request) *bhomeclient.Reply { + var clusterE models.Cluster + var reply = bhomeclient.Reply{ + Success: false, + Msg: "leave", + Data: nil, + } + + arr, err := clusterE.FindAll() + if err == nil { + if arr != nil && len(arr) > 0 { + // 琛ㄧず宸插姞鍏ラ泦缇� + reply.Success = true + + var nodeE models.Node + nodes, _ := nodeE.FindNodesByClusterId(arr[0].ClusterId) + logger.Debug("鏌ヨ闆嗙兢鑺傜偣:", nodes) + for _, node := range nodes { + logger.Debug("鑺傜偣:", node.NodeId, " servceId:", config.Server.AnalyServerId, " stat:", node.DriftState) + if node.NodeId == config.Server.AnalyServerId { + if node.DriftState == "master" { + reply.Msg = "master" + + } else { + reply.Msg = "slave" + } + break + } + } + } + } + + return &reply +} + // @Summary 鏌ヨ鏈湴闆嗙兢 // @Description 鏌ヨ鏈湴闆嗙兢 // @Produce json diff --git a/system-service/main.go b/system-service/main.go index 168e931..8e6fd0a 100644 --- a/system-service/main.go +++ b/system-service/main.go @@ -3,6 +3,7 @@ import ( "context" "flag" + "fmt" _ "net/http/pprof" "os" "os/signal" @@ -60,7 +61,7 @@ Proc: *proc, Channel: nil, PubTopic: pubTopics, - SubTopic: []string{versionControlS.AuthorizationUpdateTopic}, + SubTopic: []string{versionControlS.AuthorizationUpdateTopic, "sync-proc-message-to-serf"}, SubNetTopic: []string{}, } @@ -74,7 +75,7 @@ bhomedbapi.InitGetNetNode(ms.GetLocalNetNodeByTopic) bhomedbapi.InitDoReq(ms.RequestOnly) - //bhomedbapi.InitLog(logger.Debug) + bhomedbapi.InitLog(logger.Debug) //util.AuthCheck(ctx) //鎺堟潈妫�鏌� @@ -178,6 +179,7 @@ funcMap[urlPrefix+"/cluster/updateClusterName"] = clusterController.UpdateClusterName funcMap[urlPrefix+"/cluster/leave"] = clusterController.Leave funcMap[urlPrefix+"/cluster/findIpByNode"] = clusterController.FindIpByNode + funcMap[urlPrefix+"/cluster/status"] = clusterController.GetClusterStat sysMenuC := new(controllers.SysMenuController) funcMap["/data/api-u/sysmenus/tree"] = sysMenuC.MenuTree @@ -271,11 +273,13 @@ for key, _ := range funcMap { pubTopics = append(pubTopics, key) } + return funcMap, pubTopics } // 娴嬭瘯鎺ユ敹鍏ㄧ綉娑堟伅 func dealSubMsg(ctx context.Context, ms *bhomeclient.MicroNode) { + fmt.Println("dealSubMsg") for { select { case <-ctx.Done(): diff --git a/system-service/models/cluster.go b/system-service/models/cluster.go index 9a69c53..781906d 100644 --- a/system-service/models/cluster.go +++ b/system-service/models/cluster.go @@ -1,6 +1,7 @@ package models import ( + "errors" "fmt" "strconv" "time" @@ -48,40 +49,45 @@ return result, nil } -func (c *Cluster) Create() bool { +func (c *Cluster) Create() error { var localConfig LocalConfig - e := localConfig.Select() - if e != nil { - return false + err := localConfig.Select() + if err != nil { + return err } + serverId := config.Server.AnalyServerId if serverId == "" { - return false + return errors.New("serverId 涓虹┖") } + serverIp, _, e := util.GetLocalIP(config.Server.NetworkAdapter) if e != nil { - return false + return e } - var err error + tx := db.Begin() defer func() { if err != nil && tx != nil { tx.Rollback() } }() + sql := "insert into cluster (cluster_id,cluster_name,password,virtual_ip) values ('" + c.ClusterId + "','" + c.ClusterName + "','" + c.Password + "','" + c.VirtualIp + "')" if err = tx.Exec(sql).Error; err != nil { - return false + return err } timeUnix := time.Now().Unix() fmtTimeStr := time.Unix(timeUnix, 0).Format("2006-01-02 15:04:05") //娣诲姞鏈韩鑺傜偣 - sql = "insert into cluster_node (id,cluster_id,node_name,node_id,node_ip,create_time,isDelete,device_type) values ('" + serverId + "','" + c.ClusterId + "','" + localConfig.ServerName + "','" + serverId + "','" + (serverIp + ":" + strconv.Itoa(syncdb.DefaultBindPort)) + "','" + fmtTimeStr + "',0,'" + config.Server.DeviceType + "')" + sql = "insert into cluster_node (id,cluster_id,node_name,node_id,node_ip,create_time,isDelete,device_type,drift_state) values ('" + serverId + "','" + c.ClusterId + "','" + localConfig.ServerName + "','" + serverId + "','" + (serverIp + ":" + strconv.Itoa(syncdb.DefaultBindPort)) + "','" + fmtTimeStr + "',0,'" + config.Server.DeviceType + "','master')" if err = tx.Exec(sql).Error; err != nil { - return false + return err } + tx.Commit() - return true + + return nil } func (c *Cluster) UpdateClusterName(clusterName string, virtualIp string) bool { diff --git a/system-service/models/db.go b/system-service/models/db.go index 2a02bdc..f51d0a5 100644 --- a/system-service/models/db.go +++ b/system-service/models/db.go @@ -4,7 +4,6 @@ "basic.com/valib/logger.git" "github.com/jinzhu/gorm" _ "github.com/jinzhu/gorm/dialects/sqlite" - "strings" "vamicro/config" ) @@ -42,17 +41,9 @@ &AuthConfig{}, &AuthDevice{}, ) + InitSysSettingData() InitDefHeadPicData() - - initDic() - - //娣诲姞浼犳劅鍣ㄥ瓧鍏搁厤缃� - addSensorDic() - //鍒濆鍖栦簨浠舵帹閫佸瓧鍏� - setDataPushDic() - //鍒濆鍖栦汉鑴歌窡韪殑瀛楀吀 - setFaceTrackDic() } // GetDB ... @@ -62,61 +53,4 @@ func CloseDB() { db.Close() -} - -func initDic() { - db.Exec("INSERT INTO dictionary SELECT 'dcf9a925-dd1d-4dc4-a30d-002f976366a4', '1', '鏄�', 'endRecord', '鏄�', 1, '0' where not exists (select 1 from dictionary where id='dcf9a925-dd1d-4dc4-a30d-002f976366a4')") - db.Exec("INSERT INTO dictionary SELECT 'ec3e1a20-c5fd-4d3c-a57b-2d10f114bb8f', '0', '鍚�', 'endRecord', '鍚�', 2, '0' where not exists (select 1 from dictionary where id='ec3e1a20-c5fd-4d3c-a57b-2d10f114bb8f')") - db.Exec("INSERT INTO dictionary SELECT '4a4a1f9c-1431-4c56-ac95-12792ff51fd1', '1', '鏄�', 'change', '鏄�', 1, '0' where not exists (select 1 from dictionary where id='4a4a1f9c-1431-4c56-ac95-12792ff51fd1')") - db.Exec("INSERT INTO dictionary SELECT '8c330403-c36d-440f-92a1-b4101abcc168', '0', '鍚�', 'change', '鍚�', 2, '0' where not exists (select 1 from dictionary where id='8c330403-c36d-440f-92a1-b4101abcc168')") - //娣诲姞榛樿鐨勯�氶亾璁剧疆 -} - -func addSensorDic() { - db.Exec("INSERT INTO dictionary SELECT 'edded040-f9a4-4bbb-9eb1-23a01eaf595b', 'FaceTemperature', '娓╁害浼犳劅鍣�', 'sensorType', '浜鸿劯娴嬫俯', 1, '0' where not exists (select 1 from dictionary where id='edded040-f9a4-4bbb-9eb1-23a01eaf595b')") -} - -func setDataPushDic() { - var sqls []string - //sqls = append(sqls, "delete from dictionary where type='EVENTRULETOPIC';") - sqls = append(sqls, "INSERT INTO dictionary(`id`,`value`,`name`,`type`,`description`,`sort`,`parent_id`) select 'B2C94522-9077-768C-595D-85502C6A315E', 'camera', '鎽勫儚鏈�', 'EVENTRULETOPIC', '涓婚-鎽勫儚鏈�', 1, '0' where not exists (select 1 from dictionary where id='B2C94522-9077-768C-595D-85502C6A315E');") - sqls = append(sqls, "INSERT INTO dictionary(`id`,`value`,`name`,`type`,`description`,`sort`,`parent_id`) select 'E945DFFC-CD7D-AEED-3F0B-7C88FCD9134E', 'dbtable', '搴曞簱', 'EVENTRULETOPIC', '涓婚-搴曞簱', 2, '0' where not exists (select 1 from dictionary where id='E945DFFC-CD7D-AEED-3F0B-7C88FCD9134E');") - sqls = append(sqls, "INSERT INTO dictionary(`id`,`value`,`name`,`type`,`description`,`sort`,`parent_id`) select '213E9B4A-4E5F-8E56-8279-6C9045621068', 'task', '鍦烘櫙', 'EVENTRULETOPIC', '涓婚-鍦烘櫙', 3, '0' where not exists (select 1 from dictionary where id='213E9B4A-4E5F-8E56-8279-6C9045621068');") - sqls = append(sqls, "INSERT INTO dictionary(`id`,`value`,`name`,`type`,`description`,`sort`,`parent_id`) select '83536D8B-83D2-59B1-655B-1636DBFD8201', 'alarmLevel', '浜嬩欢绛夌骇', 'EVENTRULETOPIC', '涓婚-鎶ヨ绛夌骇', 5, '0' where not exists (select 1 from dictionary where id='83536D8B-83D2-59B1-655B-1636DBFD8201');") - sqls = append(sqls, "INSERT INTO dictionary(`id`,`value`,`name`,`type`,`description`,`sort`,`parent_id`) select '0F082502-CEA8-AAA5-FB43-DD555F0BE7D7', 'cameraName', '璁惧鍚嶇О', 'EVENTRULETOPIC', 'custom,option', 1, 'B2C94522-9077-768C-595D-85502C6A315E' where not exists (select 1 from dictionary where id='0F082502-CEA8-AAA5-FB43-DD555F0BE7D7');") - sqls = append(sqls, "INSERT INTO dictionary(`id`,`value`,`name`,`type`,`description`,`sort`,`parent_id`) select '1DEC0839-850A-C600-9070-69C871654CE6', 'cameraAddr', '璁惧鍦板潃', 'EVENTRULETOPIC', 'custom,option', 2, 'B2C94522-9077-768C-595D-85502C6A315E' where not exists (select 1 from dictionary where id='1DEC0839-850A-C600-9070-69C871654CE6');") - sqls = append(sqls, "INSERT INTO dictionary(`id`,`value`,`name`,`type`,`description`,`sort`,`parent_id`) select '806E7B4A-9A42-4E79-8708-481BA748EEC8', 'alarmRules.#.alarmLevel', '绾у埆', 'EVENTRULETOPIC', 'option', 0, '83536D8B-83D2-59B1-655B-1636DBFD8201' where not exists (select 1 from dictionary where id='806E7B4A-9A42-4E79-8708-481BA748EEC8');") - sqls = append(sqls, "INSERT INTO dictionary(`id`,`value`,`name`,`type`,`description`,`sort`,`parent_id`) select '7BBDDF13-AF28-49B9-AFAF-78E535C7CDDB', 'baseInfo.#.tableName', '鍚嶇О', 'EVENTRULETOPIC', '搴曞簱鐨勫瓙閫夐」', 0, 'E945DFFC-CD7D-AEED-3F0B-7C88FCD9134E' where not exists (select 1 from dictionary where id='7BBDDF13-AF28-49B9-AFAF-78E535C7CDDB');") - sqls = append(sqls, "INSERT INTO dictionary(`id`,`value`,`name`,`type`,`description`,`sort`,`parent_id`) select '1C9392CD-9FC4-4A23-8DCD-AE2B8E53AF49', 'baseInfo.#.targetName', '浜哄憳濮撳悕', 'EVENTRULETOPIC', '搴曞簱鐨勫瓙閫夐」', 1, 'E945DFFC-CD7D-AEED-3F0B-7C88FCD9134E' where not exists (select 1 from dictionary where id='1C9392CD-9FC4-4A23-8DCD-AE2B8E53AF49');") - sqls = append(sqls, "INSERT INTO dictionary(`id`,`value`,`name`,`type`,`description`,`sort`,`parent_id`) select '7455827A-43A6-4A9D-9D6F-F2D030E3C7D9', 'baseInfo.#.monitorLevel', '浜哄憳绛夌骇', 'EVENTRULETOPIC', '搴曞簱鐨勫瓙閫夐」', 2, 'E945DFFC-CD7D-AEED-3F0B-7C88FCD9134E' where not exists (select 1 from dictionary where id='7455827A-43A6-4A9D-9D6F-F2D030E3C7D9');") - sqls = append(sqls, "INSERT INTO dictionary(`id`,`value`,`name`,`type`,`description`,`sort`,`parent_id`) select '950DA518-8D94-4293-A686-D85E8F94BD0B', 'baseInfo.#.labels.idCard', '韬唤璇佸彿', 'EVENTRULETOPIC', '搴曞簱鐨勫瓙閫夐」', 3, 'E945DFFC-CD7D-AEED-3F0B-7C88FCD9134E' where not exists (select 1 from dictionary where id='950DA518-8D94-4293-A686-D85E8F94BD0B');") - sqls = append(sqls, "INSERT INTO dictionary(`id`,`value`,`name`,`type`,`description`,`sort`,`parent_id`) select '7B72769F-CAFE-458B-8589-B792B4BF123C', 'baseInfo.#.labels.phone', '鎵嬫満鍙�', 'EVENTRULETOPIC', '搴曞簱鐨勫瓙閫夐」', 4, 'E945DFFC-CD7D-AEED-3F0B-7C88FCD9134E' where not exists (select 1 from dictionary where id='7B72769F-CAFE-458B-8589-B792B4BF123C');") - sqls = append(sqls, "INSERT INTO dictionary(`id`,`value`,`name`,`type`,`description`,`sort`,`parent_id`) select '58B67911-CF9F-4468-9B46-3DB9F7765816', 'baseInfo.#.labels.plate', '杞︾墝鍙�', 'EVENTRULETOPIC', '搴曞簱鐨勫瓙閫夐」', 5, 'E945DFFC-CD7D-AEED-3F0B-7C88FCD9134E' where not exists (select 1 from dictionary where id='58B67911-CF9F-4468-9B46-3DB9F7765816');") - sqls = append(sqls, "INSERT INTO dictionary(`id`,`value`,`name`,`type`,`description`,`sort`,`parent_id`) select '1EC955EA-E6A5-4CA6-AD9A-4769D3CE96D6', 'taskName', '鍚嶇О', 'EVENTRULETOPIC', '鍦烘櫙鐨勫瓙閫夐」', 5, '213E9B4A-4E5F-8E56-8279-6C9045621068' where not exists (select 1 from dictionary where id='1EC955EA-E6A5-4CA6-AD9A-4769D3CE96D6');") - //sqls = append(sqls, "update dictionary set value='alarmRules.#.alarmLevel' where id='806E7B4A-9A42-4E79-8708-481BA748EEC8';") - db.Exec(strings.Join(sqls, "")) -} - -// 娣诲姞涓�浜涙槸鍚︾殑瀛楀吀鍊� -func setFaceTrackDic() { - var sqls []string - sqls = append(sqls, "INSERT INTO dictionary(`id`,`value`,`name`,`type`,`description`,`sort`,`parent_id`) select '51739a24-20bd-4440-8ef5-47fe93200536', '1', '鏄�', 'bForceSend', '鏄�', 1, '0' where not exists (select 1 from dictionary where id='51739a24-20bd-4440-8ef5-47fe93200536');") - sqls = append(sqls, "INSERT INTO dictionary(`id`,`value`,`name`,`type`,`description`,`sort`,`parent_id`) select 'fd8f9b4b-679b-4504-a295-7bb64fcd9ec5', '0', '鍚�', 'bForceSend', '鍚�', 2, '0' where not exists (select 1 from dictionary where id='fd8f9b4b-679b-4504-a295-7bb64fcd9ec5');") - sqls = append(sqls, "INSERT INTO dictionary(`id`,`value`,`name`,`type`,`description`,`sort`,`parent_id`) select 'a25055c1-50be-4ed8-ab29-da670958fbd4', '1', '鏄�', 'bForcePush', '鏄�', 1, '0' where not exists (select 1 from dictionary where id='a25055c1-50be-4ed8-ab29-da670958fbd4');") - sqls = append(sqls, "INSERT INTO dictionary(`id`,`value`,`name`,`type`,`description`,`sort`,`parent_id`) select '3c68a1fa-ae57-4e36-b418-719ef28db71e', '0', '鍚�', 'bForcePush', '鍚�', 2, '0' where not exists (select 1 from dictionary where id='3c68a1fa-ae57-4e36-b418-719ef28db71e');") - sqls = append(sqls, "INSERT INTO dictionary(`id`,`value`,`name`,`type`,`description`,`sort`,`parent_id`) select '93d0d77a-ba85-47c7-867c-34f7fe1be553', '1', '鏄�', 'bForceSave', '鏄�', 1, '0' where not exists (select 1 from dictionary where id='93d0d77a-ba85-47c7-867c-34f7fe1be553');") - sqls = append(sqls, "INSERT INTO dictionary(`id`,`value`,`name`,`type`,`description`,`sort`,`parent_id`) select '23dc5d8b-7894-4692-9042-2fa0aaf13375', '0', '鍚�', 'bForceSave', '鍚�', 2, '0' where not exists (select 1 from dictionary where id='23dc5d8b-7894-4692-9042-2fa0aaf13375');") - sqls = append(sqls, "INSERT INTO dictionary(`id`,`value`,`name`,`type`,`description`,`sort`,`parent_id`) select 'e1677c52-844a-4f03-afcd-391b477de87b', '1', '鏄�', 'bReid', '鏄�', 1, '0' where not exists (select 1 from dictionary where id='e1677c52-844a-4f03-afcd-391b477de87b');") - - // 杩涘嚭鍏ョ粺璁�, 鏂瑰悜 - sqls = append(sqls, "INSERT INTO dictionary(`id`,`value`,`name`,`type`,`description`,`sort`,`parent_id`) select 'f6e4104a-cb6b-41bc-b368-69c8a104466b', 'up', '涓�', 'inside', '涓�', 1, '0' where not exists (select 1 from dictionary where id='f6e4104a-cb6b-41bc-b368-69c8a104466b');") - sqls = append(sqls, "INSERT INTO dictionary(`id`,`value`,`name`,`type`,`description`,`sort`,`parent_id`) select '7f588975-ab59-4ab5-9c9e-af92f64d5353', 'down', '涓�', 'inside', '涓�', 2, '0' where not exists (select 1 from dictionary where id='7f588975-ab59-4ab5-9c9e-af92f64d5353');") - sqls = append(sqls, "INSERT INTO dictionary(`id`,`value`,`name`,`type`,`description`,`sort`,`parent_id`) select 'b24196de-c891-42b2-bf4a-dabfb2870397', 'right', '宸�', 'inside', '宸�', 3, '0' where not exists (select 1 from dictionary where id='b24196de-c891-42b2-bf4a-dabfb2870397');") - sqls = append(sqls, "INSERT INTO dictionary(`id`,`value`,`name`,`type`,`description`,`sort`,`parent_id`) select 'b4535930-e1a9-41b1-a4e5-2b3831f37748', 'left', '鍙�', 'inside', '鍙�', 4, '0' where not exists (select 1 from dictionary where id='b4535930-e1a9-41b1-a4e5-2b3831f37748');") - sqls = append(sqls, "INSERT INTO dictionary(`id`,`value`,`name`,`type`,`description`,`sort`,`parent_id`) select '1a691da7-989f-4492-958a-7e1f4a49b374', 'up', '涓�', 'outside', '涓�', 1, '0' where not exists (select 1 from dictionary where id='1a691da7-989f-4492-958a-7e1f4a49b374');") - sqls = append(sqls, "INSERT INTO dictionary(`id`,`value`,`name`,`type`,`description`,`sort`,`parent_id`) select '34aadb9b-3132-4e60-a73f-dc4b6f67a619', 'down', '涓�', 'outside', '涓�', 2, '0' where not exists (select 1 from dictionary where id='34aadb9b-3132-4e60-a73f-dc4b6f67a619');") - sqls = append(sqls, "INSERT INTO dictionary(`id`,`value`,`name`,`type`,`description`,`sort`,`parent_id`) select '04d56fa3-2285-470c-be42-a15d7ac4273f', 'right', '宸�', 'outside', '宸�', 3, '0' where not exists (select 1 from dictionary where id='04d56fa3-2285-470c-be42-a15d7ac4273f');") - sqls = append(sqls, "INSERT INTO dictionary(`id`,`value`,`name`,`type`,`description`,`sort`,`parent_id`) select '5c7a68f2-dd0f-4c28-b703-f9626e0d19a2', 'left', '鍙�', 'outside', '鍙�', 4, '0' where not exists (select 1 from dictionary where id='5c7a68f2-dd0f-4c28-b703-f9626e0d19a2');") - - db.Exec(strings.Join(sqls, "")) } diff --git a/system-service/models/defHeadPic.go b/system-service/models/defHeadPic.go index 6552019..7b0a75a 100644 --- a/system-service/models/defHeadPic.go +++ b/system-service/models/defHeadPic.go @@ -1,6 +1,7 @@ package models import "errors" + func InitDefHeadPicData() { var defHeadPic DefHeadPic defHeadPic.Id = "1.jpg" @@ -34,18 +35,19 @@ defHeadPic.Path = "/9j/4QAYRXhpZgAASUkqAAgAAAAAAAAAAAAAAP/sABFEdWNreQABAAQAAAA8AAD/4QMaaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLwA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/PiA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJBZG9iZSBYTVAgQ29yZSA1LjYtYzE0OCA3OS4xNjQwMzYsIDIwMTkvMDgvMTMtMDE6MDY6NTcgICAgICAgICI+IDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+IDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdFJlZj0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOkJEMTJEQ0REREU1MjExRUJCQUIzQ0RGOTc1M0ZBRkVGIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOkJEMTJEQ0RDREU1MjExRUJCQUIzQ0RGOTc1M0ZBRkVGIiB4bXA6Q3JlYXRvclRvb2w9IkFkb2JlIFBob3Rvc2hvcCAyMDIwIFdpbmRvd3MiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0iREY3RDc0MUY4MTA4MkI2MjQ3OEEyQjBCODFCQzE2RTEiIHN0UmVmOmRvY3VtZW50SUQ9IkRGN0Q3NDFGODEwODJCNjI0NzhBMkIwQjgxQkMxNkUxIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoKDBAMDAwMDAwQ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" defHeadPic.Insert() } -//鎶ヨ澹伴煶琛� + +// 鎶ヨ澹伴煶琛� type DefHeadPic struct { - Id string `gorm:"column:id;primary_key;type:varchar(100);unique;" json:"id"` - Path string `gorm:"column:path" json:"path"` + Id string `gorm:"column:id;primary_key;type:varchar(100);unique;" json:"id"` + Path string `gorm:"column:path" json:"path"` } func (DefHeadPic) TableName() string { return "def_head_pic" } -func (v *DefHeadPic) Insert() (bool,error) { - var tmp Voice +func (v *DefHeadPic) Insert() (bool, error) { + var tmp DefHeadPic if tmp.Exist(v.Id) { return false, errors.New("鏂囦欢涓嶅厑璁搁噸鍚�") } @@ -59,9 +61,9 @@ return false, errors.New("鏂板澶辫触") } -func (v *DefHeadPic) Exist(name string) bool { - dbSelect := db.Table(v.TableName()).Where("name=?", name).First(&v) - if dbSelect.Error != nil || dbSelect.RowsAffected ==0 { +func (v *DefHeadPic) Exist(id string) bool { + dbSelect := db.Table(v.TableName()).Where("id=?", id).First(&v) + if dbSelect.Error != nil || dbSelect.RowsAffected == 0 { return false } return true @@ -70,8 +72,7 @@ func (v *DefHeadPic) FindAll() (list []DefHeadPic, err error) { err = db.Table(v.TableName()).Find(&list).Order("id asc").Error if err != nil { - return nil,err + return nil, err } - return list,nil + return list, nil } - diff --git a/system-service/serf/dbLogger.go b/system-service/serf/dbLogger.go index 12317e6..0517be8 100644 --- a/system-service/serf/dbLogger.go +++ b/system-service/serf/dbLogger.go @@ -13,28 +13,15 @@ } var SyncTables = []string{ - //"area", - //"camera_area", - //"cameras", - //"gb28181_config", - //"dbtablepersons", - //"dbtables", - "cluster", "cluster_node", - "dictionary", - - "auth_config", //璁惧绠$悊鎺堟潈閰嶇疆 - - "t_device", //璁惧淇℃伅琛� - "t_device_app", //璁惧瀹夎鐨刟pp - "t_device_sdk", //璁惧瀹夎鐨剆dk } func (dbLogger *DbLogger) Print(values ...interface{}) { var ( level = values[0] ) + if level == "sql" { msgArr := gorm.LogFormatter(values...) sql := msgArr[3].(string) diff --git a/system-service/serf/handler.go b/system-service/serf/handler.go index a6fc49b..c5546db 100644 --- a/system-service/serf/handler.go +++ b/system-service/serf/handler.go @@ -77,8 +77,25 @@ logger.Info("LTime:", ev.LTime, " Recevie virtualIp change") SyncVirtualIpChan <- ev.Payload } +func HandleUserEventSyncMessage(ev serf.UserEvent) { + logger.Info("receive a UserEventSyncMessage event") + var procMsg ProcMessageEvent + err := json.Unmarshal(ev.Payload, &procMsg) + if err != nil { + logger.Error("sqlUe unmarshal err:", err) + return + } -//鏀跺埌鍏跺畠鑺傜偣涓诲姩灏嗘敞鍐屼腑蹇冪殑鎵�鏈塼opic閫氱煡鍒伴泦缇や腑 + // 鑷繁鍙戦�佺殑娑堟伅涓嶅鐞� + if procMsg.Owner != config.Server.AnalyServerId { + // 鍒ゆ柇鏄惁鏈夋寚瀹氱殑鎺ユ敹鐩爣 + if procMsg.Target == "" || procMsg.Target == config.Server.AnalyServerId { + SyncProcMessageChan <- ev.Payload + } + } +} + +// 鏀跺埌鍏跺畠鑺傜偣涓诲姩灏嗘敞鍐屼腑蹇冪殑鎵�鏈塼opic閫氱煡鍒伴泦缇や腑 func HandleSyncRegisterInfo(ev serf.UserEvent) { logger.Debug("HandleSyncRegisterInfo") var si bhome_msg_dev.MsgDevRegisterInfo @@ -167,7 +184,7 @@ } } -//澶勭悊鍏朵粬鐨勪竴浜泀uery璇锋眰 +// 澶勭悊鍏朵粬鐨勪竴浜泀uery璇锋眰 func HandleOtherQuery(ev *serf.Query) { var reqBody RequestSerfTopicMsg var ret []byte diff --git a/system-service/serf/serf.go b/system-service/serf/serf.go index 55ecb72..0a14a19 100644 --- a/system-service/serf/serf.go +++ b/system-service/serf/serf.go @@ -23,11 +23,15 @@ UserEventSyncVirtualIp = "SyncVirtualIp" //婕傜Щip淇敼 UserEventSyncRegisterInfo = "SyncRegisterInfo" //鍚屾娉ㄥ唽淇℃伅 DataSystemSerfSubscribe = "data-system-serf-subscribe" //鍚刟pp浠巗erf璁㈤槄娑堟伅 + UserEventSyncMessage = "SyncMessageForProc" // 涓哄叾浠栬繘绋嬪悓姝ユ秷鎭� TcpTransportPort = 30194 //tcp浼犺緭澶ф暟鎹噺鎺ュ彛 + + SUserEventSyncMessage ) var SyncDbTablePersonCacheChan = make(chan []byte, 512) var SyncVirtualIpChan = make(chan []byte, 512) +var SyncProcMessageChan = make(chan []byte, 512) func HandleSerfEvent(event serf.Event) { switch ev := event.(type) { @@ -42,6 +46,9 @@ HandleSyncRegisterInfo(ev) } else if ev.Name == DataSystemSerfSubscribe { HandleDataSystemSerfSub(ev) + } else if ev.Name == UserEventSyncMessage { + logger.Debug("鎺ユ敹鍒癝yncMessageForProc") + HandleUserEventSyncMessage(ev) } case *serf.Query: if ev.Name == QueryEventUpdateDBData { @@ -100,6 +107,14 @@ type SqlUserEvent struct { Owner string `json:"owner"` Sql []string `json:"sql"` +} + +type ProcMessageEvent struct { + Owner string `json:"owner"` // 鍙戦�佽�� + Target string `json:"target"` // 鎸囧畾鎺ユ敹鑰� + Proc string `json:"procName"` // 杩涚▼鍚� + Topic string `json:"topic"` // 涓婚 + Payload []byte `json:"payload"` // 娑堟伅浣�,鑷瑙f瀽 } type TableDesc struct { @@ -193,7 +208,7 @@ mbs := a.GroupMembers(clusterId) var specmembername string for _, m := range mbs { - logger.Info("m", m) + logger.Info("member", m) if m.Name != config.Server.AnalyServerId { //鍓嶇紑锛欴SVAD:鍒嗘瀽鏈嶅姟鍣� DSPAD:杩涘嚭鍏ad if strings.HasPrefix(config.Server.AnalyServerId, "DSVAD") { if strings.HasPrefix(m.Name, "DSVAD") { @@ -206,7 +221,7 @@ } } } - logger.Info("mbs:", mbs, "specmembername:", specmembername) + logger.Info("members:", mbs, "specmembername:", specmembername) if specmembername == "" { //濡傛灉鏈壘鍒扮洰鏍囪妭鐐癸紝璇存槑褰撳墠闆嗙兢鍐呴櫎浜嗘湰鑺傜偣锛屾病鏈夊叾浠栧彲鐢ㄨ妭鐐� return nil, errors.New("specmembername not found") } @@ -245,8 +260,8 @@ logger.Info("Query response's len:", len(msg)) err := json.Unmarshal(msg, &dumpSqls) if err == nil { - logger.Error("dumpSql:", dumpSqls) - logger.Error("data dump success") + //logger.Error("dumpSql:", dumpSqls) + logger.Debug("data dump success") } return } diff --git a/system-service/serf/sync.go b/system-service/serf/sync.go index ed1089c..c5710da 100644 --- a/system-service/serf/sync.go +++ b/system-service/serf/sync.go @@ -6,6 +6,7 @@ "basic.com/valib/bhomeclient.git" "basic.com/valib/logger.git" "context" + "encoding/json" "github.com/gogo/protobuf/proto" "nanomsg.org/go-mangos" "nanomsg.org/go-mangos/protocol/req" @@ -112,6 +113,30 @@ select { case <-ctx.Done(): return + case b := <-SyncProcMessageChan: + { + var procMsg ProcMessageEvent + err := json.Unmarshal(b, &procMsg) + if err != nil { + logger.Error("Unmarshal ProcMessageEvent ", err.Error()) + } else { + err = hms.Publish(procMsg.Topic, procMsg.Payload) + if err != nil { + logger.Error("hms.Publish error ", err.Error()) + } + } + + } + default: + time.Sleep(50 * time.Millisecond) + } + } + }() + go func() { + for { + select { + case <-ctx.Done(): + return case b := <-syncSdkCompareCacheChan: { logger.Debug("SyncSdkCompareCache in,len(b):", len(b)) diff --git a/system-service/service/SysService.go b/system-service/service/SysService.go index 779b65e..5a95364 100644 --- a/system-service/service/SysService.go +++ b/system-service/service/SysService.go @@ -165,7 +165,7 @@ return true, isComplete, "" } -//upgrade +// upgrade func (sv SysService) Upgrade(identifier string, filename string) (bool, error) { if !bakBeforeUpgrade() { return false, errors.New("鏇存柊鍓嶅浠藉け璐�") @@ -226,7 +226,7 @@ return true } -//鏇存柊绯荤粺绋嬪簭 +// 鏇存柊绯荤粺绋嬪簭 func updatePatch(identifier string, ext string) bool { configPatchPath := "" if config.Server.PatchPath != "" { @@ -349,7 +349,7 @@ return cmd.Output() } -//涓婁紶澹伴煶鏂囦欢 +// 涓婁紶澹伴煶鏂囦欢 func (sv SysService) UploadVoice(fileBytes []byte, filename string) (string, error) { fileExt := path.Ext(filename) fileExt = strings.ToLower(fileExt) @@ -382,18 +382,18 @@ return weedFilePath, err } -//鑾峰彇鎵�鏈夐厤缃� +// 鑾峰彇鎵�鏈夐厤缃� func (sv SysService) GetAllSetting() (settings []models.SysSetting, err error) { settingModel := models.SysSetting{} return settingModel.GetAllSetting() } -//鏇存柊閰嶇疆 +// 鏇存柊閰嶇疆 func (sv SysService) SaveSetting(setting models.SysSetting) (err error) { return setting.SaveSetting(true) } -//鑾峰彇纭洏鍓╀綑绌洪棿 +// 鑾峰彇纭洏鍓╀綑绌洪棿 func (sv SysService) DiskInfo(dev string) (uint64, uint64) { var stat syscall.Statfs_t err := syscall.Statfs(dev, &stat) @@ -406,13 +406,18 @@ return All, Free } -//鍚屾鏇存柊璁剧疆 +// 鍚屾鏇存柊璁剧疆 func PersistentWrapper(topic string, payloads []byte) { if versionControlS.AuthorizationUpdateTopic == topic { if err := json.Unmarshal(payloads, &AuthInfo); nil != err { logger.Error("handleSubMsg failed to persistent:", topic, string(payloads)) } } + + if "sync-proc-message-to-serf" == topic { + logger.Debug("handleSubMsg sync-proc-message-to-serf") + ClusterSyncProcMessage(payloads) + } } // 鑾峰彇鎺堟潈鏂瑰紡鍜屾巿鏉冨瘑鐮� diff --git a/system-service/service/clusterService.go b/system-service/service/clusterService.go index afe172b..2f978ef 100644 --- a/system-service/service/clusterService.go +++ b/system-service/service/clusterService.go @@ -112,19 +112,21 @@ arr, err := clusterE.FindAll() if err == nil && (arr == nil || len(arr) == 0) { - b := clusterE.Create() - if b { + err = clusterE.Create() + if err == nil { serf.InitAgent(context.Background()) chMsg := protomsg.DbChangeMessage{ Id: clusterE.ClusterId, Table: protomsg.TableChanged_T_Cluster, Action: protomsg.DbAction_Insert, - Info: "", + Info: "create", } s.AddDbMessage(&chMsg) return true, clusterId + } else { + logger.Error("鍒濆鍖栭泦缇ゆ暟鎹簱淇℃伅澶辫触. ", err.Error()) } } else { if s.UpdateClusterName(clusterName, virtualIp) { @@ -201,22 +203,21 @@ agent, err := dbSync.Init(joinArg.ClusterId, joinArg.Password, config.Server.AnalyServerId, joinIps, config.ClusterSet.SerfSnapShotPath, conf) if err == nil && agent != nil { //鍔犲叆鎴愬姛 logger.Debug("AddCluster dbSync.Init success") + agent.RegisterHandleEventFunc(serf.HandleSerfEvent) serf.Agent = agent t := time.Now() syncTableDataFromCluster(joinArg) logger.Debugf("AddCluster time=%v", time.Since(t)) //if syncB { - // //闇�瑕侀噸鏂板垵濮嬪寲鏈湴姣斿杩涚▼ - // go serf.ReInitDbPersonCompareData() - // chMsg := protomsg.DbChangeMessage{ - // Id: joinArg.ClusterId, - // Table: protomsg.TableChanged_T_Cluster, - // Action: protomsg.DbAction_Insert, - // Info: "", - // } - // - // s.AddDbMessage(&chMsg) + chMsg := protomsg.DbChangeMessage{ + Id: joinArg.ClusterId, + Table: protomsg.TableChanged_T_Cluster, + Action: protomsg.DbAction_Insert, + Info: "join", + } + + s.AddDbMessage(&chMsg) logger.Debugf("AddCluster 鍔犲叆闆嗙兢鎴愬姛 time=%v", time.Since(start)) return true, nil //} else { @@ -332,7 +333,7 @@ Id: "", Table: protomsg.TableChanged_T_Cluster, Action: protomsg.DbAction_Delete, - Info: "", + Info: "leave", } logger.Debugf("Leave delete db time=%v", time.Since(t)) tm := time.Now() @@ -341,6 +342,7 @@ } logger.Debugf("Leave success time=%v", time.Since(start)) + return true, nil } @@ -374,6 +376,7 @@ db := models.GetDB() db.LogMode(false) defer db.LogMode(true) + tx := db.Begin() defer func() { if err != nil && tx != nil { @@ -385,16 +388,12 @@ tx.Exec("PRAGMA foreign_keys=OFF") //1.鍒犻櫎鏈湴鐨勫悓姝ュ簱鏁版嵁 for _, t := range serf.SyncTables { - delSql := "" - if t == "dbtables" { - delSql = "delete from " + t + " where (analyServerId='' or analyServerId=NULL)" - } else if t == "dbtablepersons" { - delSql = "delete from " + t + " where tableId in (select id from dbtables where (analyServerId='' or analyServerId=NULL))" - } else { - delSql = "delete from " + t + "" - } + delSql := "delete from " + t + "" + err = tx.Exec(delSql).Error if err != nil { + logger.Error("鍒犻櫎鏈湴鐨勫悓姝ュ簱鏁版嵁澶辫触,", err.Error()) + logger.Error("sql:", delSql) return false } } @@ -404,8 +403,9 @@ dumpSqls, err = serf.GetTableDataFromCluster(serf.Agent, joinArg.ClusterId, serf.SyncTables, 20*time.Second) if dumpSqls != nil && len(*dumpSqls) > 0 { for _, sqlStr := range *dumpSqls { - logger.Debug("gorm exec dumpSql:", sqlStr) + //logger.Debug("gorm exec dumpSql:", sqlStr) if err = tx.Exec(sqlStr).Error; err != nil { + logger.Error("gorm exec dumpSql:", sqlStr, " error:", err.Error()) return false } } @@ -457,3 +457,14 @@ var lc models.Node return lc.FindIpByNode(nodeId) } + +func ClusterSyncProcMessage(payload []byte) { + if serf.Agent == nil { + logger.Error("鏈姞鍏ラ泦缇�") + } + + err := serf.Agent.UserEvent(serf.UserEventSyncMessage, payload, false) + if err != nil { + logger.Error("UserEventSyncMessage err:", err) + } +} diff --git a/system-service/service/proc.go b/system-service/service/proc.go index 98437af..f0d7d4e 100644 --- a/system-service/service/proc.go +++ b/system-service/service/proc.go @@ -1,4 +1,5 @@ package service - -const ProcName = "system-service" +const ( + ProcName = "system-service" +) -- Gitblit v1.8.0