[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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章