一,场景描述
服务A, 需要到机器 node1 上,去触发一个异步任务(即启动一个python 脚本,这个任务耗时很长),不阻塞服务A运行;如果异步任务参数异常,会在10秒内返回,服务A启动这个任务异常时,需要感知报警!
二,需求分析
1, 服务A,可以试用 subprocess 工具,跳转到 node1 机器上,然后到指定目录下启动这个脚本。
2, 可以通过 一个helper.py 脚本,启动这个异步任务;异步任务启动完成后,helper.py 正常退出,并告知远程服务A,我触发异步任务成功了。
3, helper.py 脚本,发起异步任务时,需要判断异步任务是否在10秒内结束;如果在10秒内结束了,说明异步任务启动失败!
三,shell 命令或者代码实现
3.1 服务A到nodes 启动helper.py 的代码
'''
import subprocess
cmd = "ssh user@node1 cd ${target_dir} && python3 helper.py"
p = subprocess.run(cmd, shell=True, stdout=sp.PIPE)
print p.stdout
...
3.2 heler.py 脚本内容
# helper.py
import subprocess
import sys
def main():
arg1 = "Hello"
arg2 = "World"
# 将参数传递给 background_task.py 脚本
subprocess.Popen([sys.executable, "background_task.py", arg1, arg2])
try:
out, err = process.communicate(timeout=10) # 超时时间设为 3 秒
print(out.decode(encoding='utf-8').strip())
print(err.decode(encoding='utf-8').strip()) # 服务A,可以看到这个print
return True
except subprocess.TimeoutExpired: # 超时异常处理
# 注意,对于异步耗时较长的任务,超时才是正常逻辑;如果未超时,说明发起异步任务失败了!
print("The async task succ!")
return True
if __name__ == "__main__":
main()
3.3 异步任务脚本内容
# background_task.py
import sys
import time
def main(arg1, arg2):
for i in range(20):
print(f"Running background task, iteration: {i}, arg1: {arg1}, arg2: {arg2}")
time.sleep(1)
if i > 3 and arg2 == 'abnormal': # 如果是异常测试,超过3秒就返回!
break
print("Background task completed")
if __name__ == "__main__":
if len(sys.argv) == 3: # 检查命令行参数是否正确
main(sys.argv[1], sys.argv[2])
else:
print("Usage: background_task.py arg1 arg2")