目录
1. 设计说明:
- 终端设备(如树莓派)上实现数据采集、上报功能,作为守护程序,命令行支持 start /stop ting /restart
- 支持实时的日志记录
- 多线程支持, 分为:
- AppCommander 应用指挥官线程,负责接受命令,指挥动作
- EnvReporter 环境记者线程,负责收集并上报环境数据 - python3 环境
2. 守护进程 Daemon方案:
1. daemon-python, 比较通用的方式,但不支持 start/stop/restart,不灵活
#!/usr/bin/env python
from common.models.App import *
import daemon
import common.config as Config
from common.utils.Logger import Logger
# Press the green button in the gutter to run the script.
if __name__ == '__main__':
app = App()
# # 获取预留文件句柄给python daemon, 否则log会在daemon时被关闭
with daemon.DaemonContext(files_preserve=Logger.getPreserveFds()):
app.run()
2. Daemon.py (From "A simple unix/linux daemon in Python" by Sander Marechal )
能符合要求,choose it
#!/usr/bin/env python
import sys
import time
from common.models.App import *
if __name__ == '__main__':
daemon = App()
if len(sys.argv) > 1:
if 'start' == sys.argv[1]:
daemon.start()
elif 'stop' == sys.argv[1]:
daemon.stop()
elif 'restart' == sys.argv[1]:
daemon.restart()
else:
daemon.direct_run()
3. Linux 系统服务方式
编辑 te001c.service
[Unit]
Description=Te001 ClientApp Service
#After=multi-user.target
After=network.target
[Service]
Type=idle
ExecStart=/usr/bin/python /data0/Projects/te001_client/main.py
Restart = on-failure
RestartSec=5
TimeoutStartSec=infinity
[Install]
WantedBy=multi-user.target
步骤:
cp /data0/Projects/te001_client/te001c.service /lib/systemd/system/
systemctl daemon-reload
sudo systemctl enable te001c.service
3. Mqtt Client的Singleton单点模式
class MqttClient(object):
_instance = None
_lock = threading.Lock()
host = user = password = ''
def __new__(cls, *args, **kwargs):
if not cls._instance:
with cls._lock:
# another thread could have created the instance
# before we acquired the lock. So check that the
# instance is still nonexistent.
if not cls._instance:
cls._instance = super().__new__(cls, *args, **kwargs)
cls._instance.host = Config.MQTT_HOST
cls._instance.port = Config.MQTT_PORT
cls._instance.user = Config.MQTT_USER
cls._instance.password = Config.MQTT_PSW
cls._instance.client = mqtt.Client()
cls._instance.will_set(Config.TOPIC_DEVICE_STATUS, cls._instance.getLastWill())
cls._instance.connect()
return cls._instance
4. 调用方法
./main.py | 直接启动 无论pid有否) | |
./main.py start | 守护模式启动 | |
./main.py stop | 停止 | |
./main.py restart | 重启 |
未完待续...