supervisor提供的兩種管理方式,supervisorctl和web其實都是通過xml_rpc來實現的。
xml_rpc其實就是本地可以去調用遠端的函數方法,然后函數方法經過一番處理后,把結果返回給我們。
xml_rpc不懂的同學建議去百度百度它的原理機制。這個比較簡單,樓主也是上午剛搞懂。
在python里面實現xml_rpc就更加的簡單,用SimpleXMLRPCServer和xmlrpclib這兩個模塊就可以分別實現服務端和客戶端了。
調用supervisor的xml_rpc接口,其實很簡單。先做好下面這兩步
1
2
|
import
xmlrpclib
p
=
xmlrpclib.Server(
'http://localhost:9001/RPC2'
)
|
注意xmlrpclib.Server()里面的url和咱們supervisor.conf里的配置是相關的
做完上面的步驟,我們就可以得到一個叫做p的對象。p這個對象,有很多存放在服務端的方法。
supervisor默認的xml_rpc方法定義在下面這個路徑里面
1
|
/usr/local/lib/python2
.7
/dist-packages/supervisor-3
.1.0-py2.7.egg
/supervisor/rpcinterface
.py
|
我們可以使用system.listMethods()的方法,來查看服務端都有哪些方法可供調用?
1
2
|
>>>server.system.listMethods()
[
'supervisor.addProcessGroup'
,
'supervisor.clearAllProcessLogs'
,
'supervisor.clearLog'
,
'supervisor.clearProcessLog'
,
'supervisor.clearProcessLogs'
,
'supervisor.getAPIVersion'
,
'supervisor.getAllConfigInfo'
,
'supervisor.getAllProcessInfo'
,
'supervisor.getIdentification'
,
'supervisor.getPID'
,
'supervisor.getProcessInfo'
,
'supervisor.getState'
,
'supervisor.getSupervisorVersion'
,
'supervisor.getVersion'
,
'supervisor.readLog'
,
'supervisor.readMainLog'
,
'supervisor.readProcessLog'
,
'supervisor.readProcessStderrLog'
,
'supervisor.readProcessStdoutLog'
,
'supervisor.reloadConfig'
,
'supervisor.removeProcessGroup'
,
'supervisor.restart'
,
'supervisor.sendProcessStdin'
,
'supervisor.sendRemoteCommEvent'
,
'supervisor.shutdown'
,
'supervisor.startAllProcesses'
,
'supervisor.startProcess'
,
'supervisor.startProcessGroup'
,
'supervisor.stopAllProcesses'
,
'supervisor.stopProcess'
,
'supervisor.stopProcessGroup'
,
'supervisor.tailProcessLog'
,
'supervisor.tailProcessStderrLog'
,
'supervisor.tailProcessStdoutLog'
,
'system.listMethods'
,
'system.methodHelp'
,
'system.methodSignature'
,
'system.multicall'
]
|
看到了吧,有這么多的方法,我們如果想知道某一個方法怎么用,可以用system.methodHelp(name)去查看,例如:
1
|
server.system.methodHelp(
'supervisor.startProcess'
)
|
這么查看其實還是有點麻煩的,直接去官網看吧,官網上列舉了常用方法的用法。其實supervisor本身提供的xml_rpc的方法有很多很多,包括查看進程狀態,啟動/停止/重啟進程,查看日志,發送event等等。
有了這些方法,我們就可以向遠處執行相應的操作。或者獲取想要的數據,OK,后續數據怎么處理,怎么用,就可以根據大伙的實際需求去發揮了。
還有上面的每個方法都是supervisor.x的形式,前面的supervisor其實是,我們定義在
[rpcinterface:supervisor],rpc接口的名稱。
既然有,rpc接口需要名稱,那么顯然名稱是為了區分rpc接口。在supervisor里面,如果我們覺得supervisor自帶的rpc接口函數不夠用,那么我們就可以定義自己的rpc接口函數。自己定義的函數可以直接寫進rpcinterface.py里面去。不過為了不污染人家原有的東西,最好別這么干。
supervisord中rpc接口函數定義的方法,除了需要在supervisord.conf中加上一塊配置外,還需要一個函數簽名。
先看看supervisord.conf中怎么定義吧。配置文件中找個地方,放入下面這么段東西。里面具體的接口名稱,路徑,及簽名函數的名稱,大伙可以自己去指定了。我的形式是這個樣子的
1
2
3
|
[rpcinterface:myrpc]
supervisor.rpcinterface_factory = myrpc.rpc:my_rpc
args = 1
|
注意,第二行的args = 1。表示傳入my_rpc這個簽名函數的參數。supervisor中,簽名函數的第一個參數必須為"supervisord",后面可以沒有別的參數,以key/value的形式傳入。
其他參數如同args = 1的形式,放在[rpcinterface:myrpc]的塊里面
OK,我們就用上面的配置,來舉個小例子,來看看自定義rpc接口的完整實現。
先看看,myrpc.rpc,rpc.py這個自定義模塊里面是什么?
1
2
3
4
5
6
7
8
9
10
11
12
|
#!/usr/bin/env python
class
Rpc(
object
):
def
__init__(
self
,supervisord,args):
self
.supervisord
=
supervisord
self
.args
=
args
def
walk_args(
self
):
return
self
.walk
def
my_rpc(supervisord,
*
*
args):
return
Rpc(supervisord,args)
|
啟動supervisord之后,進行下面的操作
OK,舉了個小例子把流程走通了,沒啥實際用處,深入搞的話就看大伙的具體需求了。