從一次事故談?wù)?pid 文件的作用


title: 從一次事故談?wù)?pid 文件的作用

tags:

  • pid

categories:

  • Tech

comments: true
date: 2017-05-26 20:00:00


很多程序在啟動(dòng)后會(huì)在 /var/run 目錄下創(chuàng)建一個(gè)文件 xxx.pid 文件欢搜,用以保存這個(gè)進(jìn)程的進(jìn)程號(hào)辨绊。之前一直以為這個(gè)文件僅僅是用來控制進(jìn)程的啟動(dòng)和關(guān)閉,直到最近遇到的一個(gè)慘痛的教訓(xùn)...

先講個(gè)故事(也是個(gè)事故...)

最近手頭的一個(gè)工作是分析全站的鏡像流量祈秕,流程大概是抓取網(wǎng)卡的所有幀逐層解析,最終是在應(yīng)用層實(shí)現(xiàn)重組 http 會(huì)話翅溺,將重組后的數(shù)據(jù)發(fā)送到 kafka 供后端分析奢啥。(程序的代碼在 http-capture

程序的細(xì)節(jié)這里不談,直接進(jìn)入事故...

一開始這個(gè)程序是直接跑在后臺(tái)的满钟,為了保證程序的可靠性胜榔,準(zhǔn)備托管給 supervisor。于是巴拉巴拉把 supervisor 的配置文件寫好湃番,然后 supervisorctl update夭织,把程序跑起來了。

嗯吠撮,supervisorctl status 看一下尊惰,http-capture 狀態(tài)變成 running,沒毛病,非常穩(wěn)弄屡!再 ps 查看一下進(jìn)程的大概情況题禀,我了個(gè)去有兩個(gè) http-capture 進(jìn)程在工作,原來之前運(yùn)行在后臺(tái)的進(jìn)程忘記關(guān)掉了琢岩!

由于是使用 ansible 批量操作的投剥,所以全部的12臺(tái)設(shè)備都是啟動(dòng)了兩個(gè)進(jìn)程,也就是說每臺(tái)設(shè)備同時(shí)輸出了兩份相同的數(shù)據(jù)担孔!再一看kafka 那邊的入隊(duì)情況江锨,果然 double 了。oh糕篇,my god啄育!

事故整個(gè)復(fù)盤就是這么簡(jiǎn)答,后續(xù)的處理拌消、恢復(fù)工作就先不談了挑豌。

事后分析

整個(gè)事故直接原因總結(jié)起來很簡(jiǎn)單,就是操作人員大意墩崩,誤操作導(dǎo)致的氓英。但是深究背后的程序是否存在問題呢,當(dāng)然存在很多問題的鹦筹。

  • 首先铝阐,我在操作過程中測(cè)試成功后直接使用 ansible 全量上線。更合適的方式應(yīng)該是先ansible 操作1~2臺(tái)設(shè)備上線铐拐,然后待觀察穩(wěn)定后全量上線徘键。

  • 其次,就是程序本身存在問題遍蟋,邏輯不夠嚴(yán)謹(jǐn)吹害,這種要保證一臺(tái)服務(wù)器上只能唯一啟動(dòng)的進(jìn)程,在程序啟動(dòng)邏輯中就應(yīng)該驗(yàn)證這個(gè)條件虚青。

  • 另外它呀,就是問題的發(fā)現(xiàn)過程,是偶然的通過 ps 命令查看進(jìn)程此發(fā)現(xiàn)的此問題挟憔,缺少統(tǒng)一的監(jiān)控钟些、告警工具。

  • 最后绊谭,發(fā)現(xiàn)問題后政恍,沒有快速的回滾機(jī)制,只能通過命令依次全部 kill 掉后达传,但是此時(shí)有大量的數(shù)據(jù)走入后端了篙耗,容錯(cuò)能力不足迫筑。

總體說在,就是在程序啟動(dòng)宗弯、運(yùn)行脯燃、關(guān)閉的過程中缺少必要的檢測(cè)、容錯(cuò)和恢復(fù)手段蒙保。其他的不談辕棚,這里重點(diǎn)說說第二點(diǎn),程序自身的問題邓厕,如何實(shí)現(xiàn)程序自身的啟動(dòng)檢測(cè)逝嚎。

Pid 文件的作用

pid 文件是什么呢?打開系統(tǒng)(Linux) 的 "/var/run/" 目錄可以看到有很多已 ".pid" 為結(jié)尾的文件详恼,如下:


/var/run 目錄下的 pid 文件

這些文件只有一行补君,它記錄的是相應(yīng)進(jìn)程的 pid,即進(jìn)程號(hào)昧互。所以通過 pid 文件可以很方便的得到一個(gè)進(jìn)程的 pid挽铁,然后做相應(yīng)的操作,比如檢測(cè)敞掘、關(guān)閉叽掘。

那 pid 文件是不是只是存儲(chǔ)呢?當(dāng)然不是玖雁!它還有另一個(gè)更重要的作用够掠,那就是防止進(jìn)程啟動(dòng)多個(gè)副本。通過文件鎖茄菊,可以保證一時(shí)間內(nèi)只有一個(gè)進(jìn)程能持有這個(gè)文件的寫權(quán)限,所以在程序啟動(dòng)的檢測(cè)邏輯中加入獲取pid 文件鎖并寫pid文件的邏輯就可以防止重復(fù)啟動(dòng)進(jìn)程的多個(gè)副本了赊堪。

下面是實(shí)現(xiàn)這個(gè)邏輯的一段 c 代碼面殖,在程序的啟動(dòng)檢測(cè)邏輯中調(diào)用這個(gè)函數(shù)即可保證程序唯一啟動(dòng)。

void writePidFile(const char *szPidFile)
{
    /* 獲取文件描述符 */
    char str[32];
    int pidfile = open(szPidFile, O_WRONLY|O_CREAT|O_TRUNC, 0600);
    if (pidfile < 0) {
        printf("pidfile is %d", pidfile);
        exit(1);
    }
   
    /* 鎖定文件哭廉,如果失敗則說明文件已被鎖脊僚,存在一個(gè)正在運(yùn)行的進(jìn)程,程序直接退出 */
    if (lockf(pidfile, F_TLOCK, 0) < 0) {
        fprintf(stderr, "File locked ! Can not Open Pid File: %s", szPidFile);
        exit(0);
    }

    /* 鎖定文件成功后遵绰,會(huì)一直持有這把鎖辽幌,知道進(jìn)程退出,或者手動(dòng) close 文件
       然后將進(jìn)程的進(jìn)程號(hào)寫入到 pid 文件*/
    sprintf(str, "%d\n", getpid()); // \n is a symbol.
    ssize_t len = strlen(str);
    ssize_t ret = write(pidfile, str, len);
    if (ret != len ) {
        fprintf(stderr, "Can't Write Pid File: %s", szPidFile);
        exit(0);
    }
}

參考文檔

https://unix.stackexchange.com/questions/12815/what-are-pid-and-lock-files-for
https://www.zhihu.com/question/20289583
https://stackoverflow.com/a/13651761/5126723
http://www.man7.org/tlpi/code/online/dist/filelock/create_pid_file.c.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末椿访,一起剝皮案震驚了整個(gè)濱河市乌企,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌成玫,老刑警劉巖加酵,帶你破解...
    沈念sama閱讀 217,657評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件拳喻,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡猪腕,警方通過查閱死者的電腦和手機(jī)冗澈,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來陋葡,“玉大人亚亲,你說我怎么就攤上這事「停” “怎么了捌归?”我有些...
    開封第一講書人閱讀 164,057評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)柴梆。 經(jīng)常有香客問我陨溅,道長(zhǎng),這世上最難降的妖魔是什么绍在? 我笑而不...
    開封第一講書人閱讀 58,509評(píng)論 1 293
  • 正文 為了忘掉前任门扇,我火速辦了婚禮,結(jié)果婚禮上偿渡,老公的妹妹穿的比我還像新娘臼寄。我一直安慰自己,他們只是感情好溜宽,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,562評(píng)論 6 392
  • 文/花漫 我一把揭開白布吉拳。 她就那樣靜靜地躺著,像睡著了一般适揉。 火紅的嫁衣襯著肌膚如雪留攒。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,443評(píng)論 1 302
  • 那天嫉嘀,我揣著相機(jī)與錄音炼邀,去河邊找鬼。 笑死剪侮,一個(gè)胖子當(dāng)著我的面吹牛拭宁,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播瓣俯,決...
    沈念sama閱讀 40,251評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼杰标,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了彩匕?” 一聲冷哼從身側(cè)響起腔剂,我...
    開封第一講書人閱讀 39,129評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎驼仪,沒想到半個(gè)月后桶蝎,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體驻仅,經(jīng)...
    沈念sama閱讀 45,561評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,779評(píng)論 3 335
  • 正文 我和宋清朗相戀三年登渣,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了噪服。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,902評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡胜茧,死狀恐怖粘优,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情呻顽,我是刑警寧澤雹顺,帶...
    沈念sama閱讀 35,621評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站廊遍,受9級(jí)特大地震影響嬉愧,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜喉前,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,220評(píng)論 3 328
  • 文/蒙蒙 一没酣、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧卵迂,春花似錦裕便、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至改览,卻和暖如春下翎,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背宝当。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工漏设, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人今妄。 一個(gè)月前我還...
    沈念sama閱讀 48,025評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像鸳碧,于是被迫代替她去往敵國(guó)和親盾鳞。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,843評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容