您现在的位置是:首页 >技术杂谈 >docker版jxTMS使用指南:python服务之pyService网站首页技术杂谈

docker版jxTMS使用指南:python服务之pyService

jxandrew 2024-07-16 18:01:02
简介docker版jxTMS使用指南:python服务之pyService

本文讲解4.0版jxTMS中python服务的pyService,整个系列的文章请查看:docker版jxTMS使用指南:4.0版升级内容

docker版本的使用,请参考:docker版jxTMS使用指南

4.0版jxTMS中示例的python服务是一个采集前端数据的接口机。所以针对该应用需求,特意定制了pyService作为接口机的python服务。该服务包括三部分:

1、系统初始化

这部分工作在文件开头,配合导包,导入需要的包就执行相应部分的初始化。分为三部分:

a 首先要加载localStore

from jx.jxLocalStore import localStore
#导入基础包之后,就要加载之前所保存的本地数据,否则其它用到本地存储的包就可能导入失败了
localStore.load()

b 加载本地的资源权限配置

from jx.auth import resource
#加载资源配置
resource.init()

from jx.auth import user
#加载用户配置
user.init()

from jx.auth import right
#加载权限配置
right.init()

c 初始化钉钉设置

from jx.dingding import dingtalk
dingtalk.init()

这部分的初始化工作,应该是所有服务都需要执行的,当然,如果不需要通过钉钉发送设备失联告警或其它告警信息的,可以不初始化钉钉。

注:上述的初始化其实就是从本地存储中读取相关信息放入内部的相关数据结构中,方便以后的使用,并不涉及功能性的加载、设置等。所以不加载只是没有相关数据,后面无法发送、无法授权

2、服务相关的初始化

这部分工作主要是在pyService的对象初始化函数中完成的,包括:

a 设置主服务

mainService.set(self)

b 启动mqtt连接

如果未给出mqttServerIP参数,则不启动

c 加载站点,由于存在动态加载模块的可能,所以在jxGoBaseService的对象初始化函数中就已经加载了所有的动态模块

site.init()

3、接口机的管理接口函数

这些管理接口函数都是以pyService的对象函数的形式实现的。下面的讲解就不是以函数签名的形式来进行了,而是前端访问这些接口的形式。前端访问主要在代码目录下的demo2空间下。

demo2.main模块的capa.py中访问这些接口的方法为:

#python服务的名字:服务类型.服务名
pyServiceName = 'pyService.demo1'

#capa的对象函数
def _callpyService_xxxx(self, devName):
    ps = jxJson.getObjectNode()
    ps.set('devName',devName)
    #向python扩展发送命令,并送入参数ps
    rs = catalogService.call(pyServiceName,'xxxx',ps)

注:服务名已经从此前的【{服务类型}.{服务所在主机名}.{服务名}】调整为:{服务类型}.{服务名}

调用self._callpyService_xxxx函数,就会向pyService.demo1发送一个【xxxx】的请求,jxTMS会将其转为调用python服务类中的xxxx对象函数,该函数如果返回一个dict,jxTMS就将其转换为json返回给rs。

如果该函数没有返回,或xxxx函数未定义,则rs为:{‘jT’:‘info’,‘msg’:‘404’}。如果python服务失联,则catalogService.call会阻塞30秒左右然后返回给rs一个None,此时用户页面将长达30秒没有任何响应,而且一般会在30秒后得到一个Null警告。

解决此问题有两种办法:

  • 在call之前,先请求catalogService询问一下该服务isLive,但请求方只能中断请求。由于服务器失联属于极小概率事件,所以此种方案效率不高

  • 在多台服务器上同时启动该服务,catalogService只会批准第一个申请注册的服务注册,而要求其它同类型同服务名的服务等待;所以等已经注册的服务失联而被catalogService从目录中删除后,新的服务就会注册成功。而jxTMS将rabbitMQ的消息TTL配置为了100秒,所以该请求就会被发送给新的服务来处理

上述数据被配置的都比较大的原因是笔者担心如果服务数量比较多、用户数量也比较多的情况下,catalogService的压力如果太大会影响整个平台的可靠性,所以将阻塞、保活、消息TTL等时间因子都放的比较大。

下面是pyService中实现的管理接口,其中的返回是指函数执行正确的返回,如果由于种种问题导致函数执行失败,会返回:

{'jT':'err','msg':错误点堆栈}

addMQTTUser

添加一个MQTT用户

参数:
	 userName:MQTT用户名
	 password:密码
返回:
	{'ty':'response','cmd':'addMQTTUser','rc':'ok'}
说明:
	MQTT用户信息位于/etc/mosquitto/pwfile中

readData

读取设备实时数据

参数:
	 devName:设备名
返回:
	无此设备:{'ty':'response','cmd':'readData','rc':'none'}
	有此设备:{'ty':'response','cmd':'readData','rc':'ok','data':设备数据}

readLog

读取设备实时日志

参数:
	 devName:设备名
返回:
	无此设备:{'ty':'response','cmd':'readLog','rc':'none'}
	有此设备:{'ty':'response','cmd':'readLog','rc':'ok','data':设备状态}

addDingdingGroup

设置一个钉钉组的发送信息

参数:
	 name:钉钉组名,是本系统指定的该组的识别名,而不是钉钉中的群名
	 token:钉钉群的token
	 secret:钉钉群的secret
返回:
	{'ty':'response','cmd':'addDingdingGroup','rc':'ok'}
说明:
	目前,给钉钉发送消息采取的是webhook方式。当需要向某个钉钉群发送信息时,就使用addDingdingGroup中的name所指定的组名

deleteDingdingGroup

设置一个钉钉组的发送信息

参数:
	 name:钉钉组名,是本系统指定的该组的识别名,而不是钉钉中的群名
返回:
	{'ty':'response','cmd':'deleteDingdingGroup','rc':'ok'}
说明:
	目前,给钉钉发送消息采取的是webhook方式

setWarnType

设置某站点的告警方式。当告警方式不是test时,设备告警时会发送告警信息;反之则只是在日志中打印一个warn信息。这主要是考虑到一个正常的维护班组都会只通过一两个群来接收告警信息;而新设备、故障设备都有一个开通调试的过程,其间可能会产生大量的告警信息,如果直接发送到告警策略,可能会导致维护人员接收到大量的告警信息而心烦意乱,更大的威胁就是可能会漏过其它设备的告警信息,延误故障的排除

参数:
	 siteName:站点名
	 warnType:告警方式,ok或test
返回:
	{'ty':'response','cmd':'setWarnType','rc':'ok'}
说明:
	设备初始告警方式为test,所以在设备调试完毕投运后,需要在jxTMS平台上手动设置该站点告警方式ok。手段设置某站点的告警方式后,会保存到本地并在站点初始时设置

subscribe

手动订阅一个MQTT主题

参数:
	 topic:主题
返回:
	{'ty':'response','cmd':'subscribe','rc':'ok'}
说明:
	添加站点时,jxTMS会自动订阅该站点名的主题,所以原则上是不需要手工订阅主题的

unsubscribe

手动取消订阅一个MQTT主题

参数:
	 topic:主题
返回:
	{'ty':'response','cmd':'unsubscribe','rc':'ok'}
说明:
	subscribe和unsubscribe更多的是用于调试的便利

setDeviceParam

设置设备的一个参数

参数:
	 deviceName:设备名
	 paramName:参数名
	 paramValue:参数值
返回:
	未指定设备名:{'ty':'response','cmd':'setDeviceParam','rc':'未指定:deviceName'}
	未指定参数名:{'ty':'response','cmd':'setDeviceParam','rc':'未指定:paramName'}
	无此设备:{'ty':'response','cmd':'setDeviceParam','rc':设备[{设备名}]不存在}
	正常:{'ty':'response','cmd':'setDeviceParam','rc':'ok'}
说明:
	不同的设备可能需要设置各种参数,此处为单一设置

setAllDeviceParam

设置设备的多个参数

参数:
	 deviceName:设备名
	 params:参数数组,数组成员是一个个json对象
		 paramName:参数名
		 paramValue:参数值
返回:
	未指定设备名:{'ty':'response','cmd':'setAllDeviceParam','rc':'未指定:deviceName'}
	未指定参数表:{'ty':'response','cmd':'setAllDeviceParam','rc':'未指定:params'}
	无此设备:{'ty':'response','cmd':'setAllDeviceParam','rc':设备[{设备名}]不存在}
	正常:{'ty':'response','cmd':'setAllDeviceParam','rc':'ok'}
说明:
	不同的设备可能需要设置各种参数,此处为单一设置

openSite

开通站点

参数:
	 站点配置,jxTMS平台做好站点数据后开通
返回:
	{'ty':'response','cmd':'openSite','rc':'ok'}

closeSite

关闭站点

参数:
	 siteName:站点名
返回:
	{'ty':'response','cmd':'closeSite','rc':'ok'}

traceUser

是否跟踪用户行为。当通过user.access执行用户操作时,如果设置了跟踪用户,则会对用户的授权过程、执行等记录到日志中。如果关闭跟踪,则不记录。

参数:
	 userName:用户名
	 trace:True,跟踪;False,关闭跟踪
返回:
	{'ty':'response','cmd':'traceUser','rc':'ok'}

另有资源、用户、权限的管理,这部分内容应通过jxTMS进行配置后下发给python服务,所以详见权限管理章节。

参考资料:

jxTMS设计思想

jxTMS编程手册

下面的系列文章讲述了如何用jxTMS开发一个实用的业务功能:

如何用jxTMS开发一个功能

下面的系列文章讲述了jxTMS的一些基本开发能力:

jxTMS的HelloWorld

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。