修改Gunicorn的测试命令,调试中,未完成
This commit is contained in:
344
threads.py
344
threads.py
@@ -196,14 +196,15 @@ class DeleteDirectoryThread(QThread):
|
||||
class SetTimezoneAndRestartThread(QThread):
|
||||
result_ready = Signal(bool, str)
|
||||
|
||||
def __init__(self, ssh_client):
|
||||
def __init__(self, ssh_client, password):
|
||||
super().__init__()
|
||||
self.ssh_client = ssh_client
|
||||
self.password = password
|
||||
|
||||
def run(self):
|
||||
try:
|
||||
# 设置时区
|
||||
stdin, stdout, stderr = self.ssh_client.exec_command("sudo timedatectl set-timezone Asia/Shanghai")
|
||||
# 设置时区,使用-S选项从标准输入读取密码
|
||||
stdin, stdout, stderr = self.ssh_client.exec_command(f"echo '{self.password}' | sudo -S timedatectl set-timezone Asia/Shanghai")
|
||||
exit_status = stdout.channel.recv_exit_status()
|
||||
|
||||
if exit_status != 0:
|
||||
@@ -212,8 +213,8 @@ class SetTimezoneAndRestartThread(QThread):
|
||||
logger.error(f"设置时区失败: {error}")
|
||||
return
|
||||
|
||||
# 重启服务器
|
||||
stdin, stdout, stderr = self.ssh_client.exec_command("sudo reboot")
|
||||
# 重启服务器,使用-S选项从标准输入读取密码
|
||||
stdin, stdout, stderr = self.ssh_client.exec_command(f"echo '{self.password}' | sudo -S reboot")
|
||||
|
||||
self.result_ready.emit(True, "时区设置成功,服务器正在重启")
|
||||
logger.info("时区设置成功,服务器正在重启")
|
||||
@@ -227,14 +228,15 @@ class SetTimezoneAndRestartThread(QThread):
|
||||
class CheckFirewallThread(QThread):
|
||||
result_ready = Signal(bool, str)
|
||||
|
||||
def __init__(self, ssh_client):
|
||||
def __init__(self, ssh_client, password):
|
||||
super().__init__()
|
||||
self.ssh_client = ssh_client
|
||||
self.password = password
|
||||
|
||||
def run(self):
|
||||
try:
|
||||
# 检查UFW状态
|
||||
stdin, stdout, stderr = self.ssh_client.exec_command("sudo ufw status")
|
||||
# 检查UFW状态,使用-S选项从标准输入读取密码
|
||||
stdin, stdout, stderr = self.ssh_client.exec_command(f"echo '{self.password}' | sudo -S ufw status")
|
||||
exit_status = stdout.channel.recv_exit_status()
|
||||
|
||||
if exit_status == 0:
|
||||
@@ -255,20 +257,21 @@ class CheckFirewallThread(QThread):
|
||||
class OpenPortThread(QThread):
|
||||
result_ready = Signal(bool, str)
|
||||
|
||||
def __init__(self, ssh_client, port):
|
||||
def __init__(self, ssh_client, port, password):
|
||||
super().__init__()
|
||||
self.ssh_client = ssh_client
|
||||
self.port = port
|
||||
self.password = password
|
||||
|
||||
def run(self):
|
||||
try:
|
||||
# 开放端口
|
||||
stdin, stdout, stderr = self.ssh_client.exec_command(f"sudo ufw allow {self.port}")
|
||||
# 开放端口,使用-S选项从标准输入读取密码
|
||||
stdin, stdout, stderr = self.ssh_client.exec_command(f"echo '{self.password}' | sudo -S ufw allow {self.port}")
|
||||
exit_status = stdout.channel.recv_exit_status()
|
||||
|
||||
if exit_status == 0:
|
||||
# 重新加载防火墙
|
||||
stdin, stdout, stderr = self.ssh_client.exec_command("sudo ufw reload")
|
||||
# 重新加载防火墙,使用-S选项从标准输入读取密码
|
||||
stdin, stdout, stderr = self.ssh_client.exec_command(f"echo '{self.password}' | sudo -S ufw reload")
|
||||
|
||||
self.result_ready.emit(True, f"端口 {self.port} 开放成功")
|
||||
logger.info(f"端口 {self.port} 开放成功")
|
||||
@@ -287,9 +290,10 @@ class DjangoInstallThread(QThread):
|
||||
result_ready = Signal(bool, str)
|
||||
progress_updated = Signal(int)
|
||||
|
||||
def __init__(self, ssh_client):
|
||||
def __init__(self, ssh_client, password):
|
||||
super().__init__()
|
||||
self.ssh_client = ssh_client
|
||||
self.password = password
|
||||
|
||||
def run(self):
|
||||
try:
|
||||
@@ -320,8 +324,8 @@ class DjangoInstallThread(QThread):
|
||||
|
||||
self.progress_updated.emit(50)
|
||||
|
||||
# 如果pip安装失败,尝试使用apt安装
|
||||
stdin, stdout, stderr = self.ssh_client.exec_command("sudo apt update && sudo apt install -y python3-django")
|
||||
# 如果pip安装失败,尝试使用apt安装,使用-S选项从标准输入读取密码
|
||||
stdin, stdout, stderr = self.ssh_client.exec_command(f"echo '{self.password}' | sudo -S apt update && echo '{self.password}' | sudo -S apt install -y python3-django")
|
||||
exit_status = stdout.channel.recv_exit_status()
|
||||
|
||||
if exit_status == 0:
|
||||
@@ -392,9 +396,58 @@ class DjangoTestThread(QThread):
|
||||
output = stdout.read().decode()
|
||||
|
||||
if "manage.py runserver" in output:
|
||||
self.progress_updated.emit(100)
|
||||
self.result_ready.emit(True, "Django测试服务器启动成功")
|
||||
logger.info("Django测试服务器启动成功")
|
||||
self.progress_updated.emit(80)
|
||||
logger.info("Django测试服务器启动成功,开始检查端口访问情况")
|
||||
|
||||
# 检查8000端口是否真的在监听
|
||||
self.progress_updated.emit(85)
|
||||
stdin, stdout, stderr = self.ssh_client.exec_command("ss -tulnp | grep 8000")
|
||||
ss_output = stdout.read().decode()
|
||||
logger.info(f"ss命令检查端口8000结果: {ss_output}")
|
||||
|
||||
# 如果ss命令没有结果,尝试使用netstat
|
||||
if not ss_output:
|
||||
stdin, stdout, stderr = self.ssh_client.exec_command("netstat -tulnp | grep 8000")
|
||||
netstat_output = stdout.read().decode()
|
||||
logger.info(f"netstat命令检查端口8000结果: {netstat_output}")
|
||||
port_check_output = netstat_output
|
||||
else:
|
||||
port_check_output = ss_output
|
||||
|
||||
# 检查端口是否在LISTEN状态
|
||||
if "LISTEN" in port_check_output and "8000" in port_check_output:
|
||||
self.progress_updated.emit(90)
|
||||
logger.info("端口8000处于LISTEN状态,开始本地请求测试")
|
||||
|
||||
# 本地发起请求测试
|
||||
stdin, stdout, stderr = self.ssh_client.exec_command("curl -s http://127.0.0.1:8000")
|
||||
curl_output = stdout.read().decode()
|
||||
curl_exit_status = stdout.channel.recv_exit_status()
|
||||
|
||||
logger.info(f"curl本地请求测试退出状态: {curl_exit_status}")
|
||||
logger.info(f"curl本地请求测试输出: {curl_output[:200]}..." if len(curl_output) > 200 else f"curl本地请求测试输出: {curl_output}")
|
||||
|
||||
if curl_exit_status == 0:
|
||||
self.progress_updated.emit(100)
|
||||
self.result_ready.emit(True, "Django测试服务器启动成功,端口访问正常")
|
||||
logger.info("Django测试服务器启动成功,端口访问正常")
|
||||
else:
|
||||
# 检查错误类型
|
||||
if "Failed to connect" in curl_output:
|
||||
error_msg = "Django测试服务器启动成功,但本地请求超时,Gunicorn进程可能未正常响应"
|
||||
elif "Bad Request (400)" in curl_output:
|
||||
error_msg = "Django测试服务器启动成功,但返回400错误,可能是ALLOWED_HOSTS配置问题"
|
||||
elif "500" in curl_output:
|
||||
error_msg = "Django测试服务器启动成功,但返回500错误,可能是应用内部错误"
|
||||
else:
|
||||
error_msg = f"Django测试服务器启动成功,但本地请求失败: {curl_output[:100]}"
|
||||
|
||||
self.result_ready.emit(False, error_msg)
|
||||
logger.error(error_msg)
|
||||
else:
|
||||
self.progress_updated.emit(100)
|
||||
self.result_ready.emit(False, "Django测试服务器启动成功,但端口8000未处于LISTEN状态")
|
||||
logger.error("Django测试服务器启动成功,但端口8000未处于LISTEN状态")
|
||||
else:
|
||||
self.result_ready.emit(False, "Django测试服务器启动失败")
|
||||
logger.error("Django测试服务器启动失败")
|
||||
@@ -776,24 +829,137 @@ class GunicornTestThread(QThread):
|
||||
|
||||
self.progress_updated.emit(50)
|
||||
|
||||
# 测试Gunicorn启动,使用构造函数中传入的端口参数
|
||||
test_command = f"cd {self.django_path} && timeout 10 gunicorn --workers 1 --bind 0.0.0.0:{self.port} {project_name}.wsgi:application --timeout 5"
|
||||
# 在启动Gunicorn前,先检查端口是否被占用
|
||||
logger.info(f"检查端口{self.port}是否被其他进程占用")
|
||||
stdin, stdout, stderr = self.ssh_client.exec_command(f"sudo lsof -i :{self.port}")
|
||||
lsof_output = stdout.read().decode()
|
||||
lsof_exit_status = stdout.channel.recv_exit_status()
|
||||
|
||||
if lsof_exit_status == 0 and lsof_output:
|
||||
logger.warning(f"端口{self.port}已被其他进程占用: {lsof_output}")
|
||||
# 尝试杀死占用端口的进程
|
||||
stdin, stdout, stderr = self.ssh_client.exec_command(f"sudo lsof -t -i :{self.port} | xargs sudo kill -9")
|
||||
time.sleep(1) # 等待进程被杀死
|
||||
logger.info(f"已尝试杀死占用端口{self.port}的进程")
|
||||
else:
|
||||
logger.info(f"端口{self.port}未被占用")
|
||||
|
||||
# 测试Gunicorn启动,使用构造函数中传入的端口参数,指定4个worker
|
||||
test_command = f"cd {self.django_path} && gunicorn --workers 4 --bind 0.0.0.0:{self.port} {project_name}.wsgi:application --timeout 5"
|
||||
logger.info(f"执行Gunicorn测试命令: {test_command}")
|
||||
stdin, stdout, stderr = self.ssh_client.exec_command(test_command)
|
||||
time.sleep(3) # 等待Gunicorn启动
|
||||
|
||||
# 检查Gunicorn是否运行
|
||||
# 检查Gunicorn进程状态
|
||||
stdin, stdout, stderr = self.ssh_client.exec_command("ps aux | grep gunicorn")
|
||||
output = stdout.read().decode()
|
||||
logger.info(f"Gunicorn进程检查结果: {output}")
|
||||
|
||||
# 检查Worker进程状态
|
||||
worker_count = output.count('gunicorn') - 1 # 减去grep进程本身
|
||||
logger.info(f"检测到Gunicorn Worker进程数量: {worker_count}")
|
||||
|
||||
# 详细分析进程结构
|
||||
lines = output.strip().split('\n')
|
||||
master_process = None
|
||||
worker_processes = []
|
||||
|
||||
for line in lines:
|
||||
if 'grep' not in line and 'gunicorn' in line:
|
||||
parts = line.split()
|
||||
if len(parts) >= 11:
|
||||
pid = parts[1]
|
||||
command = ' '.join(parts[10:])
|
||||
if 'master' in command or 'gunicorn: master' in command:
|
||||
master_process = (pid, command)
|
||||
elif 'worker' in command:
|
||||
worker_processes.append((pid, command))
|
||||
|
||||
if master_process:
|
||||
logger.info(f"检测到Gunicorn主进程 - PID: {master_process[0]}, 命令: {master_process[1]}")
|
||||
else:
|
||||
logger.warning(f"未检测到Gunicorn主进程")
|
||||
|
||||
if worker_processes:
|
||||
logger.info(f"检测到{len(worker_processes)}个Gunicorn Worker进程:")
|
||||
for pid, command in worker_processes:
|
||||
logger.info(f" - Worker PID: {pid}, 命令: {command}")
|
||||
else:
|
||||
logger.warning(f"未检测到Gunicorn Worker进程")
|
||||
|
||||
# 检查进程数量是否符合预期(1个主进程+4个worker进程)
|
||||
if master_process and len(worker_processes) == 4:
|
||||
logger.info(f"Gunicorn进程结构正常: 1个主进程 + 4个worker进程")
|
||||
elif master_process and len(worker_processes) > 0:
|
||||
logger.warning(f"Gunicorn进程结构部分正常: 1个主进程 + {len(worker_processes)}个worker进程(预期4个)")
|
||||
else:
|
||||
logger.error(f"Gunicorn进程结构异常: 未检测到完整的进程结构")
|
||||
|
||||
if worker_count < 1:
|
||||
logger.error(f"Gunicorn主进程存在但Worker进程未启动,可能是Django代码/配置错误")
|
||||
# 尝试手动启动Gunicorn并获取详细错误日志
|
||||
logger.info(f"尝试手动启动Gunicorn以获取详细错误日志")
|
||||
stdin, stdout, stderr = self.ssh_client.exec_command(f"cd {self.django_path} && gunicorn --workers 4 --bind 0.0.0.0:{self.port} {project_name}.wsgi:application --timeout 5 --error-logfile -")
|
||||
time.sleep(2)
|
||||
error_output = stderr.read().decode()
|
||||
logger.error(f"手动启动Gunicorn错误日志: {error_output}")
|
||||
|
||||
# 清理测试进程
|
||||
stdin, stdout, stderr = self.ssh_client.exec_command(f"pkill -f 'gunicorn.*{self.port}'")
|
||||
|
||||
if "gunicorn" in output and f":{self.port}" in output:
|
||||
self.progress_updated.emit(100)
|
||||
self.result_ready.emit(True, f"Gunicorn测试成功 - 项目: {project_name}, 端口: {self.port}")
|
||||
logger.info(f"Gunicorn测试成功 - 项目: {project_name}, 端口: {self.port}")
|
||||
self.progress_updated.emit(80)
|
||||
logger.info(f"Gunicorn进程运行正常,开始检查端口{self.port}访问情况")
|
||||
|
||||
# 检查端口是否真的在监听
|
||||
self.progress_updated.emit(85)
|
||||
stdin, stdout, stderr = self.ssh_client.exec_command(f"ss -tulnp | grep {self.port}")
|
||||
ss_output = stdout.read().decode()
|
||||
logger.info(f"ss命令检查端口{self.port}结果: {ss_output}")
|
||||
|
||||
# 如果ss命令没有结果,尝试使用netstat
|
||||
if not ss_output:
|
||||
stdin, stdout, stderr = self.ssh_client.exec_command(f"netstat -tulnp | grep {self.port}")
|
||||
netstat_output = stdout.read().decode()
|
||||
logger.info(f"netstat命令检查端口{self.port}结果: {netstat_output}")
|
||||
port_check_output = netstat_output
|
||||
else:
|
||||
port_check_output = ss_output
|
||||
|
||||
# 检查端口是否在LISTEN状态
|
||||
if "LISTEN" in port_check_output and f":{self.port}" in port_check_output:
|
||||
self.progress_updated.emit(90)
|
||||
logger.info(f"端口{self.port}处于LISTEN状态,开始本地请求测试")
|
||||
|
||||
# 本地发起请求测试
|
||||
stdin, stdout, stderr = self.ssh_client.exec_command(f"curl -s http://127.0.0.1:{self.port}")
|
||||
curl_output = stdout.read().decode()
|
||||
curl_exit_status = stdout.channel.recv_exit_status()
|
||||
|
||||
logger.info(f"curl本地请求测试退出状态: {curl_exit_status}")
|
||||
logger.info(f"curl本地请求测试输出: {curl_output[:200]}..." if len(curl_output) > 200 else f"curl本地请求测试输出: {curl_output}")
|
||||
|
||||
if curl_exit_status == 0:
|
||||
self.progress_updated.emit(100)
|
||||
self.result_ready.emit(True, f"Gunicorn测试成功 - 项目: {project_name}, 端口: {self.port}, 访问正常")
|
||||
logger.info(f"Gunicorn测试成功 - 项目: {project_name}, 端口: {self.port}, 访问正常")
|
||||
else:
|
||||
# 检查错误类型
|
||||
if "Failed to connect" in curl_output:
|
||||
error_msg = f"Gunicorn进程运行正常,但本地请求超时,端口{self.port}未响应"
|
||||
elif "Bad Request (400)" in curl_output:
|
||||
error_msg = f"Gunicorn进程运行正常,但返回400错误,可能是ALLOWED_HOSTS配置问题"
|
||||
elif "500" in curl_output:
|
||||
error_msg = f"Gunicorn进程运行正常,但返回500错误,可能是应用内部错误"
|
||||
else:
|
||||
error_msg = f"Gunicorn进程运行正常,但本地请求失败: {curl_output[:100]}"
|
||||
|
||||
self.result_ready.emit(False, error_msg)
|
||||
logger.error(error_msg)
|
||||
else:
|
||||
self.progress_updated.emit(100)
|
||||
self.result_ready.emit(False, f"Gunicorn进程运行正常,但端口{self.port}未处于LISTEN状态")
|
||||
logger.error(f"Gunicorn进程运行正常,但端口{self.port}未处于LISTEN状态")
|
||||
else:
|
||||
# 尝试更简单的测试方式
|
||||
self.progress_updated.emit(80)
|
||||
@@ -1040,9 +1206,131 @@ class ManageGunicornServiceThread(QThread):
|
||||
port = "8000" # 默认端口
|
||||
if hasattr(self, 'port') and self.port:
|
||||
port = self.port
|
||||
stdin, stdout, stderr = self.ssh_client.exec_command(f"sudo netstat -tlnp | grep :{port}")
|
||||
netstat_output = stdout.read().decode()
|
||||
logger.info(f"端口{port}监听状态: {netstat_output}")
|
||||
|
||||
# 在检查端口监听前,先检查端口占用情况
|
||||
logger.info(f"检查端口{port}占用情况")
|
||||
stdin, stdout, stderr = self.ssh_client.exec_command(f"sudo lsof -i :{port}")
|
||||
lsof_output = stdout.read().decode()
|
||||
lsof_exit_status = stdout.channel.recv_exit_status()
|
||||
|
||||
if lsof_exit_status == 0 and lsof_output:
|
||||
logger.warning(f"端口{port}被占用: {lsof_output}")
|
||||
else:
|
||||
logger.info(f"端口{port}未被占用")
|
||||
|
||||
# 检查Gunicorn进程状态
|
||||
stdin, stdout, stderr = self.ssh_client.exec_command("ps aux | grep gunicorn")
|
||||
ps_output = stdout.read().decode()
|
||||
logger.info(f"Gunicorn进程状态: {ps_output}")
|
||||
|
||||
# 详细分析进程结构
|
||||
lines = ps_output.strip().split('\n')
|
||||
master_process = None
|
||||
worker_processes = []
|
||||
|
||||
for line in lines:
|
||||
if 'grep' not in line and 'gunicorn' in line:
|
||||
parts = line.split()
|
||||
if len(parts) >= 11:
|
||||
pid = parts[1]
|
||||
command = ' '.join(parts[10:])
|
||||
if 'master' in command or 'gunicorn: master' in command:
|
||||
master_process = (pid, command)
|
||||
elif 'worker' in command:
|
||||
worker_processes.append((pid, command))
|
||||
|
||||
if master_process:
|
||||
logger.info(f"检测到Gunicorn主进程 - PID: {master_process[0]}, 命令: {master_process[1]}")
|
||||
else:
|
||||
logger.warning(f"未检测到Gunicorn主进程")
|
||||
|
||||
if worker_processes:
|
||||
logger.info(f"检测到{len(worker_processes)}个Gunicorn Worker进程:")
|
||||
for pid, command in worker_processes:
|
||||
logger.info(f" - Worker PID: {pid}, 命令: {command}")
|
||||
else:
|
||||
logger.warning(f"未检测到Gunicorn Worker进程")
|
||||
|
||||
# 检查进程数量是否符合预期(1个主进程+4个worker进程)
|
||||
if master_process and len(worker_processes) == 4:
|
||||
logger.info(f"Gunicorn进程结构正常: 1个主进程 + 4个worker进程")
|
||||
elif master_process and len(worker_processes) > 0:
|
||||
logger.warning(f"Gunicorn进程结构部分正常: 1个主进程 + {len(worker_processes)}个worker进程(预期4个)")
|
||||
else:
|
||||
logger.error(f"Gunicorn进程结构异常: 未检测到完整的进程结构")
|
||||
|
||||
# 检查Worker进程状态
|
||||
worker_count = ps_output.count('gunicorn') - 1 # 减去grep进程本身
|
||||
logger.info(f"检测到Gunicorn Worker进程数量: {worker_count}")
|
||||
|
||||
if worker_count < 1:
|
||||
logger.error(f"Gunicorn主进程存在但Worker进程未启动,可能是Django代码/配置错误")
|
||||
|
||||
# 使用ss命令检查端口监听状态
|
||||
stdin, stdout, stderr = self.ssh_client.exec_command(f"sudo ss -tulnp | grep :{port}")
|
||||
ss_output = stdout.read().decode()
|
||||
logger.info(f"ss命令检查端口{port}监听状态: {ss_output}")
|
||||
|
||||
# 如果ss命令没有结果,尝试使用netstat
|
||||
if not ss_output:
|
||||
stdin, stdout, stderr = self.ssh_client.exec_command(f"sudo netstat -tlnp | grep :{port}")
|
||||
netstat_output = stdout.read().decode()
|
||||
logger.info(f"netstat命令检查端口{port}监听状态: {netstat_output}")
|
||||
port_check_output = netstat_output
|
||||
else:
|
||||
port_check_output = ss_output
|
||||
|
||||
# 检查端口是否在LISTEN状态
|
||||
if "LISTEN" in port_check_output and f":{port}" in port_check_output:
|
||||
logger.info(f"端口{port}处于LISTEN状态,开始本地请求测试")
|
||||
|
||||
# 本地发起请求测试
|
||||
stdin, stdout, stderr = self.ssh_client.exec_command(f"curl -s http://127.0.0.1:{port}")
|
||||
curl_output = stdout.read().decode()
|
||||
curl_exit_status = stdout.channel.recv_exit_status()
|
||||
|
||||
logger.info(f"curl本地请求测试退出状态: {curl_exit_status}")
|
||||
logger.info(f"curl本地请求测试输出: {curl_output[:200]}..." if len(curl_output) > 200 else f"curl本地请求测试输出: {curl_output}")
|
||||
|
||||
if curl_exit_status == 0:
|
||||
logger.info(f"服务启动成功,端口{port}访问正常")
|
||||
else:
|
||||
# 检查错误类型
|
||||
if "Failed to connect" in curl_output:
|
||||
logger.warning(f"服务启动成功,但本地请求超时,端口{port}未响应")
|
||||
elif "Bad Request (400)" in curl_output:
|
||||
logger.warning(f"服务启动成功,但返回400错误,可能是ALLOWED_HOSTS配置问题")
|
||||
elif "500" in curl_output:
|
||||
logger.warning(f"服务启动成功,但返回500错误,可能是应用内部错误")
|
||||
else:
|
||||
logger.warning(f"服务启动成功,但本地请求失败: {curl_output[:100]}")
|
||||
else:
|
||||
logger.warning(f"服务启动成功,但端口{port}未处于LISTEN状态")
|
||||
|
||||
# 检查SELinux状态
|
||||
logger.info(f"检查SELinux状态")
|
||||
stdin, stdout, stderr = self.ssh_client.exec_command("getenforce")
|
||||
selinux_output = stdout.read().decode().strip()
|
||||
logger.info(f"SELinux状态: {selinux_output}")
|
||||
|
||||
if selinux_output == "Enforcing":
|
||||
logger.warning(f"SELinux处于Enforcing状态,可能限制了端口绑定")
|
||||
|
||||
# 检查项目目录权限
|
||||
logger.info(f"检查项目目录权限")
|
||||
stdin, stdout, stderr = self.ssh_client.exec_command("ls -ld /home/xiaji/")
|
||||
home_dir_output = stdout.read().decode().strip()
|
||||
logger.info(f"/home/xiaji/目录权限: {home_dir_output}")
|
||||
|
||||
# 尝试更换端口测试
|
||||
logger.info(f"尝试更换端口测试")
|
||||
test_port = "8001"
|
||||
stdin, stdout, stderr = self.ssh_client.exec_command(f"sudo ss -tulnp | grep :{test_port}")
|
||||
test_port_output = stdout.read().decode()
|
||||
|
||||
if not test_port_output:
|
||||
logger.info(f"端口{test_port}未被占用,尝试用该端口启动Gunicorn")
|
||||
# 这里只是记录日志,不实际更换端口
|
||||
else:
|
||||
logger.warning(f"服务启动后状态检查失败: {status_error}")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user