[supervisor][xmlrpc]擴展supervisor的遠程調用api

出於某些目的,我們希望supervisor的xmlrpc可以執行我們自己寫的代碼,而supervisor官網的文檔對於擴展它的xmlrpc API這一部分的描述很模糊。這裏記錄一下我的使用過程。

官方文檔:http://www.supervisord.org/
GitHub:https://github.com/Supervisor/supervisor

關於supervisor的基本使用方法可以參考這篇文章,這裏我推薦使用pip進行安裝而不是yumapt等方式

https://blog.csdn.net/zou79189747/article/details/80403016

python3 -m pip install supervisorpip3 install supervisor

1. 準備工作

  1. 我的配置文件放置位置:/etc/supervisor/supervisord.conf
  2. 要進行遠程調用,需要將默認配置中的這一部分去掉註釋。注意,username和password的註釋也是去掉的,這樣會開啓basic認證
[inet_http_server]       ; inet (TCP) server disabled by default
port=0.0.0.0:9001        ; ip_address:port specifier, *:port for all iface
username=user            ; default is no username (open server)
password=abc098          ; default is no password (open server)
  1. 需要在配置文件中新增自定義xmlrpc API的描述
    先看看自帶API的描述部分
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
  • 第一行rpcinterface表示下面描述的是一個rpc接口,冒號後面的supervisor表示這個接口的名字,可用自己取名,這個名字在遠程調用的時候會用到
  • 第二行supervisor.rpcinterface_factory是固定寫法,這個鍵的值告訴supervisor到哪裏去找到這個接口工廠,supervisor.rpcinterface是python包名,make_main_rpcinterface是返回一個類對象的函數,這個類裏面裝的就是遠程調用函數,詳細寫法見下一節,supervisor會根據這個描述執行類似這樣的語句:
from supervisor.rpcinterface import make_main_rpcinterface
  • 因此如果想要讓supervisor成功導入我們自己寫的模塊,需要確保python的環境變量裏面包含我們的源代碼文件所在的路徑
  1. 添加自己的代碼
  • 比如我想寫這樣一個模塊
my_ext
  |---  __init__.py
  |---  ext.py
  • 直接放到{python安裝目錄}/site-packages/下,這樣就不用額外添加環境變量了

  • 配置文件中添加內容。這裏我把這個接口命名爲spvext,下面retries = 1我不加會報錯,不知道是幹什麼用的

[rpcinterface:spvext]
supervisor.rpcinterface_factory = my_ext.ext:myext
retries = 1

2. 代碼

  1. __init__.py留空即可,表示這是一個python包
  2. ext.py的內容
class Ext1:									# 需要定義一個類
    def __init__(self, supervisord):		# 這個類的構造函數至少要能接收一個參數供supervisor使用
        self.supervisord = supervisord

    def add(self, num1: int, num2: int):	# 然後隨便寫點自己的函數,這些函數可以被遠程調用
        return num1 + num2

    def hello(self):
        return 'hello'


def myext(supervisord, **config):			# 這是和上一節make_main_rpcinterface對應的函數,稱爲註冊函數
    #retries = int(config.get('retries', 0))#     參數固定這樣寫,supervisor會往裏面傳一些參數,即使我們不使用
    return Ext1(supervisord)				# 返回一個對象
  1. 重載supervisor,可以多重載幾次,有時候重載第一次顯示成功但是並沒有正常啓動,這種情況再重新加載會報錯
supervisorctl reload

3. 客戶端程序編寫

# 遠程連接supervisor的xmlrpc API

from xmlrpc.client import ServerProxy
from supervisor.xmlrpc import SupervisorTransport


if __name__ == '__main__':
    rpc_address = 'http://127.0.0.1:9001'
    username = 'user'
    password = 'password'
    # 用戶名和密碼需要用這個函數轉換爲ServerProxy函數可以識別的格式
    #     注意,剛纔我們在配置文件去掉了用戶名密碼的註釋,這時候supervisor是啓用了basic認證的,需要這樣來登錄,如果加上註釋,basic認證是不會生效的,也無需這一步
    transport = SupervisorTransport(username, password, rpc_address)
    # 建立連接
    server = ServerProxy(rpc_address, transport)


    # 獲取服務端的所有方法,返回一個列表
    response = server.system.listMethods()
    print(type(response))
    for func in response:
        print(func)

    # 顯示某個方法的幫助文檔 返回字符串
    response = server.system.methodHelp('supervisor.shutdown')
    print(type(response))
    print(response)

	# 調用我們自己寫的代碼
    response = server.spvext.hello()
    print(response)
  • 執行結果
<class 'list'>
spvext.add
spvext.hello
spvext.ls
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.h
supervisor.readLog
supervisor.readMainLog
supervisor.readProcessLog
supervisor.readProcessStderrLog
supervisor.readProcessStdoutLog
supervisor.reloadConfig
supervisor.removeProcessGroup
supervisor.restart
supervisor.sendProcessStdin
supervisor.sendRemoteCommEvent
supervisor.shutdown
supervisor.signalAllProcesses
supervisor.signalProcess
supervisor.signalProcessGroup
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
<class 'str'>
 Shut down the supervisor process

        @return boolean result always returns True unless error
        
hello
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章