python supervisor使用

發表於2016-09-16

Supervisor 是基於 Python 的程式管理工具,只能執行在 Unix-Like 的系統上,也就是無法執行在 Windows 上。Supervisor 官方版目前只能執行在 Python 2.4 以上版本,但是還無法執行在 Python 3 上,不過已經有一個 Python 3 的移植版 supervisor-py3k

什麼情況下我們需要程式管理呢?就是執行一些需要以守護程式方式執行的程式,比如一個後臺任務,我最常用的是用來啟動和管理基於 Tornado 寫的 Web 程式。

除此之外,Supervisor 還能很友好的管理程式在命令列上輸出的日誌,可以將日誌重定向到自定義的日誌檔案中,還能按檔案大小對日誌進行分割。

Supervisor 有兩個主要的組成部分:

  1. supervisord,執行 Supervisor 時會啟動一個程式 supervisord,它負責啟動所管理的程式,並將所管理的程式作為自己的子程式來啟動,而且可以在所管理的程式出現崩潰時自動重啟。
  2. supervisorctl,是命令列管理工具,可以用來執行 stop、start、restart 等命令,來對這些子程式進行管理。

安裝

建立配置檔案

如果出現沒有許可權的問題,可以使用這條命令

配置檔案說明

想要了解怎麼配置需要管理的程式,只要開啟 supervisord.conf 就可以了,裡面有很詳細的註釋資訊。

開啟配置檔案

預設的配置檔案是下面這樣的,但是這裡有個坑需要注意,supervisord.pid 以及 supervisor.sock 是放在 /tmp 目錄下,但是 /tmp 目錄是存放臨時檔案,裡面的檔案是會被 Linux 系統刪除的,一旦這些檔案丟失,就無法再通過 supervisorctl 來執行 restart 和 stop 命令了,將只會得到unix:///tmp/supervisor.sock 不存在的錯誤 。

預設情況下,程式的日誌檔案達到50MB時,將進行分割,最多保留10個檔案,當然這些配置也可以對每個程式單獨配置。

許可權問題

設定好配置檔案後,應先建立上述配置檔案中新增的資料夾。如果指定了啟動使用者 user,這裡以 oxygen 為例,那麼應注意相關檔案的許可權問題,包括日誌檔案,否則會出現沒有許可權的錯誤。例如設定了啟動使用者 oxygen,然後啟動 supervisord 出現錯誤

就是由於上面的配置檔案中 /var/run 資料夾,沒有授予啟動 supervisord 的使用者 oxygen 的寫許可權。/var/run 資料夾實際上是連結到 /run,因此我們修改 /run 的許可權。

這樣有點簡單粗暴,也可以考慮把上述配置檔案中 .sock.pid 等檔案修改到其他資料夾中,並確保有相應的許可權即可。一般情況下,我們可以用 root 使用者啟動 supervisord 程式,然後在其所管理的程式中,再具體指定需要以那個使用者啟動這些程式。

使用瀏覽器來管理

supervisor 同時提供了通過瀏覽器來管理程式的方法,只需要註釋掉如下幾行就可以了。

http_supervisorctl

使用 include

在配置檔案的最後,有一個 [include] 的配置項,跟 Nginx 一樣,可以 include 某個資料夾下的所有配置檔案,這樣我們就可以為每個程式或相關的幾個程式的配置單獨寫成一個檔案。

程式的配置樣例

一個簡單的例子如下

設定日誌級別

loglevel 指定了日誌的級別,用 Python 的 print 語句輸出的日誌是不會被記錄到日誌檔案中的,需要搭配 Python 的 logging 模組來輸出有指定級別的日誌。

多個程式

按照官方文件的定義,一個 [program:x] 實際上是表示一組相同特徵或同類的程式組,也就是說一個 [program:x] 可以啟動多個程式。這組程式的成員是通過 numprocs 和 process_name 這兩個引數來確定的,這句話什麼意思呢,我們來看這個例子。

上面這個例子會啟動兩個程式,process_name 分別為 foo:foo_01 和 foo:foo_02。通過這樣一種方式,就可以用一個 [program:x] 配置項,來啟動一組非常類似的程式。

再介紹兩個配置項 stopasgroup 和 killasgroup

更詳細的配置例子,可以參考如下,官方文件在這裡

將多個程式按組管理

Supervisor 同時還提供了另外一種程式組的管理方式,通過這種方式,可以使用 supervisorctl 命令來管理一組程式。跟 [program:x] 的程式組不同的是,這裡的程式是一個個的 [program:x] 。

當新增了上述配置後,progname1 和 progname2 的程式名就會變成thegroupname:progname1 和 thegroupname:progname2 以後就要用這個名字來管理程式了,而不是之前的 progname1

以後執行 supervisorctl stop thegroupname: 就能同時結束 progname1 和 progname2,執行 supervisorctl stop thegroupname:progname1 就能結束 progname1。supervisorctl 的命令我們稍後介紹。

啟動 supervisord

執行 supervisord 命令,將會啟動 supervisord 程式,同時我們在配置檔案中設定的程式也會相應啟動。

更多引數請參考文件

supervisorctl 命令介紹

注意:顯示用 stop 停止掉的程式,用 reload 或者 update 都不會自動重啟。也可以參考這裡

開機自動啟動 Supervisord

Supervisord 預設情況下並沒有被安裝成服務,它本身也是一個程式。官方已經給出了指令碼可以將 Supervisord 安裝成服務,可以參考這裡檢視各種作業系統的安裝指令碼,但是我用官方這裡給的 Ubuntu 指令碼卻無法執行。

安裝方法可以參考 serverfault 上的回答。

比如我是 Ubuntu 系統,可以這麼安裝,這裡選擇了另外一個指令碼

注意:這個指令碼下載下來後,還需檢查一下與我們的配置是否相符合,比如預設的配置檔案路徑,pid 檔案路徑等,如果存在不同則需要進行一些修改。

其實還有一個簡單的方法,因為 Linux 在啟動的時候會執行 /etc/rc.local 裡面的指令碼,所以只要在這裡新增執行命令就可以

在新增前,先在終端測試一下命令是否能正常執行,如果找不到 supervisord,可以用如下命令找到以上內容需要新增在 exit 命令前,而且由於在執行 rc.local 指令碼時,PATH 環境變數未全部初始化,因此命令需要使用絕對路徑。

相關文章