日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

linux kill pid文件,从一次事故谈谈 pid 文件的作用

發布時間:2024/9/30 linux 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux kill pid文件,从一次事故谈谈 pid 文件的作用 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

title: 從一次事故談談 pid 文件的作用

tags:

pid

categories:

Tech

comments: true

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

很多程序在啟動后會在 /var/run 目錄下創建一個文件 xxx.pid 文件,用以保存這個進程的進程號。之前一直以為這個文件僅僅是用來控制進程的啟動和關閉,直到最近遇到的一個慘痛的教訓...

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

最近手頭的一個工作是分析全站的鏡像流量,流程大概是抓取網卡的所有幀逐層解析,最終是在應用層實現重組 http 會話,將重組后的數據發送到 kafka 供后端分析。(程序的代碼在 http-capture)

程序的細節這里不談,直接進入事故...

一開始這個程序是直接跑在后臺的,為了保證程序的可靠性,準備托管給 supervisor。于是巴拉巴拉把 supervisor 的配置文件寫好,然后 supervisorctl update,把程序跑起來了。

嗯,supervisorctl status 看一下,http-capture 狀態變成 running,沒毛病,非常穩!再 ps 查看一下進程的大概情況,我了個去有兩個 http-capture 進程在工作,原來之前運行在后臺的進程忘記關掉了!

由于是使用 ansible 批量操作的,所以全部的12臺設備都是啟動了兩個進程,也就是說每臺設備同時輸出了兩份相同的數據!再一看kafka 那邊的入隊情況,果然 double 了。oh,my god!

事故整個復盤就是這么簡答,后續的處理、恢復工作就先不談了。

事后分析

整個事故直接原因總結起來很簡單,就是操作人員大意,誤操作導致的。但是深究背后的程序是否存在問題呢,當然存在很多問題的。

首先,我在操作過程中測試成功后直接使用 ansible 全量上線。更合適的方式應該是先ansible 操作1~2臺設備上線,然后待觀察穩定后全量上線。

其次,就是程序本身存在問題,邏輯不夠嚴謹,這種要保證一臺服務器上只能唯一啟動的進程,在程序啟動邏輯中就應該驗證這個條件。

另外,就是問題的發現過程,是偶然的通過 ps 命令查看進程此發現的此問題,缺少統一的監控、告警工具。

最后,發現問題后,沒有快速的回滾機制,只能通過命令依次全部 kill 掉后,但是此時有大量的數據走入后端了,容錯能力不足。

總體說在,就是在程序啟動、運行、關閉的過程中缺少必要的檢測、容錯和恢復手段。其他的不談,這里重點說說第二點,程序自身的問題,如何實現程序自身的啟動檢測。

Pid 文件的作用

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

/var/run 目錄下的 pid 文件

這些文件只有一行,它記錄的是相應進程的 pid,即進程號。所以通過 pid 文件可以很方便的得到一個進程的 pid,然后做相應的操作,比如檢測、關閉。

那 pid 文件是不是只是存儲呢?當然不是!它還有另一個更重要的作用,那就是防止進程啟動多個副本。通過文件鎖,可以保證一時間內只有一個進程能持有這個文件的寫權限,所以在程序啟動的檢測邏輯中加入獲取pid 文件鎖并寫pid文件的邏輯就可以防止重復啟動進程的多個副本了。

下面是實現這個邏輯的一段 c 代碼,在程序的啟動檢測邏輯中調用這個函數即可保證程序唯一啟動。

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);

}

/* 鎖定文件,如果失敗則說明文件已被鎖,存在一個正在運行的進程,程序直接退出 */

if (lockf(pidfile, F_TLOCK, 0) < 0) {

fprintf(stderr, "File locked ! Can not Open Pid File: %s", szPidFile);

exit(0);

}

/* 鎖定文件成功后,會一直持有這把鎖,知道進程退出,或者手動 close 文件

然后將進程的進程號寫入到 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);

}

}

參考文檔

總結

以上是生活随笔為你收集整理的linux kill pid文件,从一次事故谈谈 pid 文件的作用的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。