這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
實現
主要利用redis的brpop阻塞讀和Golang的goroutine並發控制以及os/exec執行程式,實現隊列有資料就立即執行對應程式並把結果set任務key。
運行參數
設定brpop的逾時(-t)和同步調度時返回的結果ttl(-e)./dispatchdeploy Usage: -h 192.168.6.151 -p 6388 -t 300 -a /path/testfile.pl -e 1800 -a string start appname (default "/path/testfile.pl") -e int redis expire time sec (default 1800) -h string redis ip -p int redis port (default 6379) -t int redis brpop timeout (default 300)
待用資料
const ( maxthread = 2 //最大並發協程數 queueName = "qn_kt" //阻塞讀隊列 result_queueName = "rt_kt" //同步返回結果的key首碼 token = "##" //執行調度參數的指定分隔字元 sync_flag = "1" )
關鍵代碼
//阻塞讀,當有資料分割參數,使用channel控制並發協程數,在execCmd的cmd.wait正常後釋放channelfor { content, _ := redisdb.brpop(queueName, *timeout) if content != nil { args := strings.Split(string(content[1]), token) if len(args) != 4 { log.Printf("%v lack of para length %s\n", args, len(args)) } else { //控制並發數 sync_num <- 1 go execCmd(*appname, args, redisdb) log.Printf("%s %v Go\n", *appname, args) } } else { log.Printf("timeout %d get nil contenet , just go on", *timeout) } }
測試
lpush三個調度到隊列127.0.0.1:6888> lpush qn_kt "6234##ZYYC0001##20170620140000##0" "5234##ZYYC0001##20170620140000##1" "7234##ZYYC0001##20170620140000##1" (integer) 3//控制並發數為2,立即調度執行了兩個perl程式,等到返回結果執行第三個2017/06/20 16:45:21 Start listen qn_kt2017/06/20 16:45:25 testfile.pl [6234 ZYYC0001 20170620140000 0] Go2017/06/20 16:45:25 testfile.pl [5234 ZYYC0001 20170620140000 1] Go2017/06/20 16:45:30 testfile.pl [6234 ZYYC0001 20170620140000 0] finish2017/06/20 16:45:30 testfile.pl [7234 ZYYC0001 20170620140000 1] Go2017/06/20 16:45:30 testfile.pl [5234 ZYYC0001 20170620140000 S] finish2017/06/20 16:45:35 testfile.pl [7234 ZYYC0001 20170620140000 S] finish2017/06/20 16:45:51 timeout 20 get nil contenet , just go on2017/06/20 16:46:12 timeout 20 get nil contenet , just go on//同步調度任務執行完成後set對應任務號,由介面程式讀取,1800秒後redis回收127.0.0.1:6888> get rt_kt_7234_ZYYC0001"7234##ZYYC0001##20170620140000##1"127.0.0.1:6888> ttl rt_kt_7234_ZYYC0001(integer) 1791