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 文件的作用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux 动态库建立,浅析linux下
- 下一篇: linux 批量下载图片,Python