亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

詳解Gotorch多機定時任務管理系統(tǒng)

 更新時間:2021年05月27日 09:07:21   作者:枕邊書  
遵循著“學一門語言最好的方式是使用它”的理念,想著用Go來實現(xiàn)些什么,剛好有一個比較讓我煩惱的問題,于是用Go解決一下,即使不在生產(chǎn)環(huán)境使用,也可以作為Go語言學習的一種方式。

前言

先介紹下問題:

組內有十來臺機器,上面用 cron 分別定時執(zhí)行著一些腳本和 shell 命令,一開始任務少的時候,大家都記得哪臺機器執(zhí)行著什么,隨著時間推移,人員幾經(jīng)變動,任務也越來越多,再也沒人能記得清哪些任務在哪些機器上執(zhí)行了,排查和解決后臺腳本的問題也越來越麻煩。

解決這個問題也不是沒有辦法:

  • 維護一個 wiki,一旦任務有變動就更新 wiki,但一旦忘記更新 wiki,任務就會變成孤兒,什么時候出了問題更不好查。
  • 布置一臺機器,定時拉取各機器的 cron 配置文件,進行對比統(tǒng)計,再將結果匯總展示,但命令的寫法各式各樣,對比命令也是個沒頭腦的事。
  • 使用開源分布式任務調度任務,比較重型,而且一般要布置數(shù)據(jù)庫、后臺,比較麻煩。

除此之外,任務的修改也非常不方便,如果想給在 crontab 里修改某一項任務,還需要找運維操作。雖然解決這個問題也有辦法,使用 crontab cronfile.txt 直接讓 crontab 加載文件,但引入新的問題:任務文件加載的實時性不好控制。

為了解決以上問題,我結合 cron 和任務管理,每天下班后花一點時間,實現(xiàn)一個小功能,最后完成了 gotorch 的可用版??粗?GitHub 的 commit 統(tǒng)計,還挺有成就感的~

這里放上 GitHub 鏈接地址: GitHub-zhenbianshu-gotorch ,歡迎 star/fork/issue。

介紹一下特色功能:

  • cron+,秒級定時,使任務執(zhí)行更加靈活;
  • 任務列表文件路徑可以自定義,建議使用版本控制系統(tǒng);
  • 內置日志和監(jiān)控系統(tǒng),方便各位同學任意擴展;
  • 平滑重加載配置文件,一旦配置文件有變動,在不影響正在執(zhí)行的任務的前提下,平滑加載;
  • IP、最大執(zhí)行數(shù)、任務類型配置,支持更靈活的任務配置;

下面說一下功能實現(xiàn)的技術要點:

文章歡迎轉載,但請帶上本文源地址:http://www.cnblogs.com/zhenbianshu/p/7905678.html,謝謝。

cron+

在實現(xiàn)類似 cron 的功能之前,我簡單地看了一下 cron 的源碼,源碼在 https://busybox.net/downloads/ 可以下載,解壓后文件在miscutils > crond.c。

cron 的實現(xiàn)設計得很巧妙的,大概如下:

數(shù)據(jù)結構:

1.cron 擁有一個全局結構體 global ,保存著各個用戶的任務列表;

2.每一個任務列表是一個結構體 CronFile, 保存著用戶名和任務鏈表等;

3.每一個任務 CronLine 有 shell 命令、執(zhí)行 pid、執(zhí)行時間數(shù)組 cl_Time 等屬性;

4.執(zhí)行時間數(shù)組的最大長度根據(jù) “分時日月周” 的最大值確定,將可執(zhí)行時間點的值置為 true,例如 在每天的 3 點執(zhí)行則 cl_Hrs[3]=true;

執(zhí)行方式:

1.cron是一個 while(true) 式的長循環(huán),每次 sleep 到下一分鐘的開始。

2.cron 在每分鐘的開始會依次遍歷檢查用戶 cron 配置文件,將更新后的配置文件解析成任務存入全局結構體,同時它也定期檢查配置文件是否被修改。

3.然后 cron 會將當前時間解析為 第 n 分/時/日/月/周,并判斷 cal_Time[n] 全為 true 則執(zhí)行任務。

4.執(zhí)行任務時將 pid 寫入防止重復執(zhí)行;

5.后續(xù) cron 還會進行一些異常檢測和錯誤處理操作。

明白了 cron 的執(zhí)行方式后,感覺每個時間單位都遍歷任務進行判斷于性能有損耗,而且我實現(xiàn)的是秒級執(zhí)行,遍歷判斷的性能損耗更大,于是考慮優(yōu)化成:

給每個任務設置一個 next_time 的時間戳,在一次執(zhí)行后更新此時間戳,每個時間單位只需要判斷 task.next_time == current_time。

后來由于 “秒分時日月周” 的日期格式進位不規(guī)則,代碼太復雜,實現(xiàn)出來效率也不比原來好,終于放棄了這種想法。。采用了跟 cron 一樣的執(zhí)行思路。

此外,我添加了三種限制任務執(zhí)行的方式:

  • IP:在服務啟動時獲取本地內網(wǎng) IP,執(zhí)行前校驗是否在任務的 IP 列表中;
  • 任務類型:任務為 daemon 的,當任務沒有正在執(zhí)行時則中斷判斷直接啟動;
  • 最大執(zhí)行數(shù):在每個任務上設置一個執(zhí)行中任務的 pid 構成的 slice,每次執(zhí)行前校驗當前執(zhí)行數(shù)。

而任務啟動方式,則直接使用 goroutine 配合 exec 包,每次執(zhí)行任務都啟動一個新的 goroutine,保存 pid,同時進行錯誤處理。由于服務可能會在一秒內多次掃描任務,我給每個任務添加了一個進程上次執(zhí)行時間戳的屬性,待下次執(zhí)行時對比,防止任務在一秒內多次掃描執(zhí)行了多次。

守護進程

本服務是做成了一個類似 nginx 的服務,我將進程的 pid 保存在一個臨時文件中,對進程操作時通過命令行給進程發(fā)送信號,只需要注意下異常情況下及時清理 pid 文件就好了。

這里說一下 Go 守護進程的創(chuàng)建方式:

由于 Go 程序在啟動時 runtime 可能會創(chuàng)建多個線程(用于內存管理,垃圾回收,goroutine管理等),而 fork 與多線程環(huán)境并不能和諧共存,所以 Go 中沒有 Unix 系統(tǒng)中的 fork 方法;于是啟動守護進程我采用 exec 之后立即執(zhí)行,即 fork and exec 的方式,而 Go 的 exec 包則支持這種方式。

在進程最開始時獲取并判斷進程 ppid 是否為1 (守護進程的父進程退出,進程會被“過繼”給 init 進程,其進程號為1),在父進程的進程號不為1時,使用原進程的所有參數(shù) fork and exec 一個跟自己相同的進程,關閉新進程與終端的聯(lián)系,并退出原進程。

filePath, _ := filepath.Abs(os.Args[0]) // 獲取服務的命令路徑
cmd := exec.Command(filePath, os.Args[1:]...) // 使用自身的命令路徑、參數(shù)創(chuàng)建一個新的命令
cmd.Stdin = nil
cmd.Stdout = nil 
cmd.Stderr = nil // 關閉進程標準輸入、標準輸出、錯誤輸出
cmd.Start() // 新進程執(zhí)行
return // 父進程退出

信號處理

將進程制作為守護進程之后,進程與外界的通信就只好依靠信號了,Go 的 signal 包搭配 goroutine 可以方便地監(jiān)聽、處理信號。同時我們使用 syscall 包內的 Kill 方法來向進程發(fā)送信號。

我們監(jiān)聽 Kill 默認發(fā)送的信號SIGTERM,用來處理服務退出前的清理工作,另外我還使用了用戶自定義信號SIGUSR2 用來作為終端通知服務重啟的消息。

一個信號從監(jiān)聽到捕捉再到處理的完整流程如下:

1.首先我們使用創(chuàng)建一個類型為 os.Sygnal 的無緩沖channel,來存放信號。

2.使用 signal.Notify() 函數(shù)注冊要監(jiān)聽的信號,傳入剛創(chuàng)建的 channel,在捕捉到信號時接收信號。

3.創(chuàng)建一個 goroutine,在 channel 中沒有信號時 signal := <-channel 會阻塞。

4.Go 程序一旦捕捉到正在監(jiān)聽的信號,就會把信號通過 channel 傳遞過來,此時 goroutine 便不會繼續(xù)阻塞。

5.通過后面的代碼處理對應的信號。

對應的代碼如下:

c := make(chan os.Signal)
signal.Notify(c, syscall.SIGTERM, syscall.SIGUSR2) 

// 開啟一個goroutine異步處理信號
go func() {
    s := <-c
    if s == syscall.SIGTERM {
        task.End()
        logger.Debug("bootstrap", "action: end", "pid "+strconv.Itoa(os.Getpid()), "signal "+fmt.Sprintf("%d", s))
        os.Exit(0)
    } else if s == syscall.SIGUSR2 {
        task.End()
        bootStrap(true)
    }
}()

小結

gotorch 的開發(fā)共花了三個月,每天半小時左右,1~3 個 commits,經(jīng)歷了三次大的重構,特別是在代碼格式上改得比較頻繁。 不過使用 Go 開發(fā)確實是挺舒心的,Go 的代碼很簡潔, gofmt 用著非常方便。另外 Go 的學習曲線也挺平滑,熟悉各個常用標準包后就能進行簡單的開發(fā)了。 簡單易學、高效快捷,難怪 Go 火熱得這么快了。

以上就是詳解Gotorch多機定時任務管理系統(tǒng)的詳細內容,更多關于Gotorch多機定時任務管理系統(tǒng)的資料請關注腳本之家其它相關文章!

相關文章

  • 使用Lumberjack+zap進行日志切割歸檔操作

    使用Lumberjack+zap進行日志切割歸檔操作

    這篇文章主要介紹了使用Lumberjack+zap進行日志切割歸檔操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • GO語言對數(shù)組切片去重的實現(xiàn)

    GO語言對數(shù)組切片去重的實現(xiàn)

    本文主要介紹了GO語言對數(shù)組切片去重的實現(xiàn),主要介紹了幾種方法,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-04-04
  • Golang實現(xiàn)DFA算法對敏感詞過濾功能

    Golang實現(xiàn)DFA算法對敏感詞過濾功能

    DFA算法是確定性有限自動機,其特征是,有一個有限狀態(tài)集合和一些從一個狀態(tài)通向另一個狀態(tài)的邊,每條邊上標記有一個符號,通俗的講DFA算法就是把你要匹配的做成一顆字典樹,然后對你輸入的內容進行匹配的過程,本文將利用DFA算法實現(xiàn)敏感詞過濾,需要的可以參考一下
    2023-10-10
  • VSCode必裝Go語言以下插件的思路詳解

    VSCode必裝Go語言以下插件的思路詳解

    這篇文章主要介紹了VSCode必裝Go語言以下插件的思路詳解,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-04-04
  • 詳解golang碎片整理之 fmt.Scan

    詳解golang碎片整理之 fmt.Scan

    本文介紹了從golang語言中fmt包從標準輸入獲取數(shù)據(jù)的Scan系列函數(shù)、從io.Reader中獲取數(shù)據(jù)的Fscan系列函數(shù)以及從字符串中獲取數(shù)據(jù)的Sscan系列函數(shù)的用法,感興趣的小伙伴們可以參考一下
    2019-05-05
  • Go指針數(shù)組和數(shù)組指針的具體使用

    Go指針數(shù)組和數(shù)組指針的具體使用

    go語言跟c語言一樣,指針數(shù)組和數(shù)組指針概念容易搞混,本文主要介紹了Go指針數(shù)組和數(shù)組指針的具體使用,具有一定的參考價值,感興趣的可以了解一下
    2024-03-03
  • 一鍵定位Golang線上服務內存泄露的秘籍

    一鍵定位Golang線上服務內存泄露的秘籍

    內存泄露?別讓它拖垮你的Golang線上服務!快速掌握Go語言服務內存泄漏排查秘籍,從此問題無處遁形,一文讀懂如何精準定位與有效解決Golang應用中的內存問題,立即閱讀,讓性能飛升!
    2024-01-01
  • Go語言讀取文本文件的三種方式總結

    Go語言讀取文本文件的三種方式總結

    工作中時不時需要讀取文本,文本文件是最常見的文件類型。本文將利用Go語言從逐行、逐個單詞和逐個字符三個方法讀取文件,感興趣的可以了解一下
    2023-01-01
  • Go語言實現(xiàn)ssh&scp的方法詳解

    Go語言實現(xiàn)ssh&scp的方法詳解

    這篇文章主要為大家詳細介紹了如何利用Go語言實現(xiàn)ssh&scp,文中的示例代碼講解詳細,具有一定的參考價值,感興趣的小伙伴可以了解一下
    2022-10-10
  • Go語言包管理工具Godep的用法

    Go語言包管理工具Godep的用法

    這篇文章介紹了Go語言包管理工具Godep的用法,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-07-07

最新評論