如何通过Python脚本启动运行多个服务端程序(含Java、C++、Wiremock等)
问题原因
你用到的os.system和subprocess.call都属于同步阻塞调用,执行这两个方法时,Python主进程会一直等待你启动的子进程完全退出后,才会继续执行后续代码。
你启动的wiremock是常驻运行的后端服务,除非主动终止进程,否则会一直保持运行状态,因此代码会一直卡在启动服务的步骤,不会执行后续的print和配置逻辑。你之前尝试的多线程写法没有生效,大概率是你在线程执行函数内部依然调用了上述阻塞方法,线程会被阻塞在启动服务的步骤,没有办法继续执行其他逻辑。
实现方案
核心是使用非阻塞的方式创建子进程,Python的subprocess.Popen就是专门用于异步启动子进程的接口,调用后会立即返回子进程对象,不会等待子进程退出,主进程可以继续执行后续逻辑。
基础使用示例
import subprocess import time # 异步启动wiremock服务 # 优先用列表形式传命令参数,避免shell注入风险,不需要加shell=True wiremock_proc = subprocess.Popen( ["java", "-jar", "替换为你的wiremock文件名.jar"], # 可选配置:不需要打印服务日志的话可以把输出重定向到空,避免干扰主程序输出 stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL ) # 必须预留服务启动时间,避免后续配置请求发送时服务还没完成初始化 time.sleep(5) # 此处可执行后续的服务配置逻辑,比如调用curl或者用requests库调用接口 print(5) # 示例:执行curl命令上传wiremock配置 subprocess.run(["curl", "-X", "POST", "http://localhost:8080/__admin/mappings", "-d", "@你的配置文件路径.json"]) # 后续如果需要停止服务,可以调用子进程对象的terminate方法 # wiremock_proc.terminate()
进阶优化建议
- 不要用固定时长的sleep等待服务启动,更可靠的方式是加健康检查逻辑:循环请求服务的健康接口,直到请求成功后再执行后续配置,避免服务启动慢导致配置失败,示例如下:
import requests import time max_retry_count = 10 check_interval = 1 for _ in range(max_retry_count): try: # 请求wiremock自带的健康检查接口 requests.get("http://localhost:8080/__admin/health", timeout=1) break except requests.exceptions.ConnectionError: time.sleep(check_interval) else: # 循环正常结束说明所有重试都失败,服务启动异常 raise RuntimeError("wiremock服务启动超时,请检查配置")
- 如果需要同时启动多个后端服务,每个服务单独创建一个
Popen对象即可,所有子进程会并行运行,互不影响主进程逻辑执行,你可以通过存储所有子进程对象的列表统一管理服务的启停。 - 如果需要收集服务的运行日志排查问题,把
stdout和stderr参数改为subprocess.PIPE,再单独开一个子线程读取日志即可,不要在主进程直接读取输出流,否则还是会造成阻塞。
内容的提问来源于stack exchange,提问作者Janith Priyankara
相关产品推荐
相关产品推荐

