111
This commit is contained in:
1 parent
5134ece73b
commit
dcf9eb6f23
13 files changed
+972
-30
No files matched your search
@@ -56,3 +56,4 @@ echo ========================================
|
||||
pause
|
||||
|
||||
|
||||
|
||||
@@ -149,3 +149,4 @@ if __name__ == '__main__':
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,158 @@
|
||||
import os,shutil
|
||||
import redis
|
||||
import oss2,time,sys
|
||||
import requests
|
||||
import argparse,json
|
||||
from utils.funcs import requestApiToUpdateSliceStatus
|
||||
|
||||
# 将当前脚本所在目录添加到 Python 路径,以便导入 utils 模块
|
||||
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
# from download_print_out import download_transform_save_by_json
|
||||
from utils.oss_redis import redisClient
|
||||
from utils.funcs import downloadJsonAndJpgFileAndMoveToCorrectDir, downloadDataByOssAndTransformSave
|
||||
# 默认使用脚本所在目录
|
||||
currentDir = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
ENV = 'prod'
|
||||
url = 'https://mp.api.suwa3d.com'
|
||||
if ENV == 'dev':
|
||||
url = 'http://mp.api.dev.com'
|
||||
elif ENV == 'prod':
|
||||
url = 'https://mp.api.suwa3d.com'
|
||||
|
||||
|
||||
#判断是否上传了 JSON 文件
|
||||
def step1(versionId):
|
||||
|
||||
# 下载json 文件 和 图片
|
||||
dirName,machineInfo = downloadJsonAndJpgFileAndMoveToCorrectDir(versionId,currentDir)
|
||||
if not dirName:
|
||||
return False
|
||||
|
||||
#判断是否是小机台
|
||||
isSmallMachine = False
|
||||
if str(machineInfo["machine_type"]) == '1':
|
||||
isSmallMachine = True
|
||||
|
||||
|
||||
#下载数据,转换数据
|
||||
res = downloadDataByOssAndTransformSave(dirName,isSmallMachine)
|
||||
if not res:
|
||||
return False
|
||||
|
||||
#判断下载的obj文件数量和json里的是否一致,排除arrange文件夹
|
||||
objFilePath = os.path.join(dirName, 'data')
|
||||
objCounts = 0
|
||||
for file in os.listdir(objFilePath):
|
||||
if file == 'arrange':
|
||||
continue
|
||||
if file.endswith('.obj'):
|
||||
objCounts += 1
|
||||
|
||||
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} 下载处理完成的obj文件数量: {objCounts}')
|
||||
# requestApiToUpdateSliceStatus(versionId,objCounts)
|
||||
|
||||
|
||||
|
||||
# 读取 队列中一个数据出来
|
||||
def main(work_dir=None, batch_id=None):
|
||||
|
||||
global currentDir
|
||||
# 如果指定了工作目录,使用指定的目录
|
||||
if work_dir:
|
||||
work_dir = os.path.abspath(work_dir)
|
||||
if not os.path.exists(work_dir):
|
||||
print(f'指定的工作目录不存在: {work_dir},将创建该目录')
|
||||
os.makedirs(work_dir, exist_ok=True)
|
||||
currentDir = work_dir
|
||||
print(f'使用指定的工作目录: {currentDir}')
|
||||
else:
|
||||
print(f'没有指定工作目录,退出')
|
||||
exit(0)
|
||||
|
||||
|
||||
versionId = str(batch_id)
|
||||
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} 正在处理版次ID={versionId}')
|
||||
res = step1(versionId)
|
||||
if res == False:
|
||||
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} JSON文件下载数据失败,等待10秒')
|
||||
# time.sleep(10)
|
||||
# continue
|
||||
# 循环处理,直到队列为空
|
||||
# try:
|
||||
# while True:
|
||||
# try:
|
||||
# r = redisClient()
|
||||
# #检测队列是否有值
|
||||
# if r.scard('pb:sliceing') == 0:
|
||||
# print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} 队列为空,等待10秒')
|
||||
# time.sleep(10)
|
||||
# continue
|
||||
# #获取队列中的值
|
||||
# data = r.spop('pb:sliceing')
|
||||
# if data is None:
|
||||
# print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} 取出的数据为空,等待10秒')
|
||||
# time.sleep(10)
|
||||
# continue
|
||||
# data = data.decode('utf-8')
|
||||
# #判断是否是数字
|
||||
# if not data.isdigit():
|
||||
# print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} 取出的数据不是数字,等待10秒')
|
||||
# time.sleep(10)
|
||||
# continue
|
||||
|
||||
# versionId = str(data)
|
||||
# print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} 正在处理版次ID={versionId}')
|
||||
# res = step1(versionId)
|
||||
# if res == False:
|
||||
# print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} JSON文件下载数据失败,等待10秒')
|
||||
# time.sleep(10)
|
||||
# continue
|
||||
|
||||
|
||||
|
||||
|
||||
# # 在长时间操作后,确保 Redis 连接仍然有效
|
||||
# # 通过重新获取客户端来触发连接检查
|
||||
# try:
|
||||
# r = redisClient()
|
||||
# r.ping() # 测试连接
|
||||
# except Exception as e:
|
||||
# print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} Redis连接检查失败: {str(e)},将在下次循环时自动重连')
|
||||
|
||||
# #time.sleep(10)
|
||||
# except KeyboardInterrupt:
|
||||
# # 在循环内部捕获 KeyboardInterrupt,允许在 sleep 或操作中被中断
|
||||
# raise # 重新抛出,让外层捕获
|
||||
# except KeyboardInterrupt:
|
||||
# print(f'\n{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} 收到中断信号,正在优雅退出...')
|
||||
# print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} 程序已停止')
|
||||
# sys.exit(0)
|
||||
|
||||
|
||||
def testMain():
|
||||
global currentDir
|
||||
currentDir = "/Users/dcx/code/make2/script/factory_sliceing_v2/tempData"
|
||||
versionId = '10153' #'10153 10158'
|
||||
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} 正在处理版次ID={versionId}')
|
||||
res = step1(versionId)
|
||||
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} 处理完成,res={res}')
|
||||
|
||||
if __name__ == '__main__':
|
||||
#testMain() 新增参数 batchId
|
||||
parser = argparse.ArgumentParser(description='排版打印订单处理程序')
|
||||
parser.add_argument(
|
||||
'--work-dir',
|
||||
type=str,
|
||||
default=None,
|
||||
help='指定工作目录(磁盘路径),例如: D:/work 或 /Users/username/work。如果不指定,则使用脚本所在目录'
|
||||
)
|
||||
parser.add_argument(
|
||||
'--batch—id',
|
||||
type=str,
|
||||
default=None,
|
||||
help='指定批次ID'
|
||||
)
|
||||
args = parser.parse_args()
|
||||
main(work_dir=args.work_dir, batch_id=args.batch_id)
|
||||
@@ -4,3 +4,4 @@ requests>=2.28.0
|
||||
pyinstaller>=5.0.0
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
import oss2,redis
|
||||
import time
|
||||
import logging
|
||||
|
||||
# 配置日志
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# 连接oss - 单例模式
|
||||
class OSSClientSingleton:
|
||||
@@ -29,47 +35,87 @@ class RedisClientSingleton:
|
||||
_instance = None
|
||||
_client = None
|
||||
|
||||
# Redis连接配置
|
||||
REDIS_CONFIG = {
|
||||
'host': 'mp.api.suwa3d.com',
|
||||
'password': 'kcV2000',
|
||||
'port': 6379,
|
||||
'db': 6,
|
||||
'socket_timeout': 30, # 操作超时30秒
|
||||
'socket_connect_timeout': 10, # 连接超时10秒
|
||||
'socket_keepalive': True, # 启用 TCP keepalive
|
||||
'socket_keepalive_options': {}, # keepalive 选项
|
||||
'health_check_interval': 30 # 健康检查间隔30秒
|
||||
}
|
||||
|
||||
# 重试配置
|
||||
RETRY_INTERVAL = 5 # 重试间隔(秒)
|
||||
MAX_RETRY_INTERVAL = 60 # 最大重试间隔(秒),用于指数退避
|
||||
|
||||
def __new__(cls):
|
||||
if cls._instance is None:
|
||||
cls._instance = super(RedisClientSingleton, cls).__new__(cls)
|
||||
return cls._instance
|
||||
|
||||
def _create_redis_client(self):
|
||||
"""创建Redis客户端"""
|
||||
return redis.Redis(**self.REDIS_CONFIG)
|
||||
|
||||
def _connect_with_retry(self, max_retries=None, retry_interval=None):
|
||||
"""
|
||||
带重试机制的Redis连接方法
|
||||
:param max_retries: 最大重试次数,None表示无限重试
|
||||
:param retry_interval: 重试间隔(秒),None表示使用默认值,支持指数退避
|
||||
:return: Redis客户端实例
|
||||
"""
|
||||
if retry_interval is None:
|
||||
retry_interval = self.RETRY_INTERVAL
|
||||
|
||||
retry_count = 0
|
||||
current_interval = retry_interval
|
||||
|
||||
while True:
|
||||
try:
|
||||
logger.info(f"尝试连接Redis (第 {retry_count + 1} 次)...")
|
||||
client = self._create_redis_client()
|
||||
# 测试连接
|
||||
client.ping()
|
||||
logger.info("Redis连接成功!")
|
||||
return client
|
||||
except (redis.ConnectionError, redis.TimeoutError, AttributeError, Exception) as e:
|
||||
retry_count += 1
|
||||
error_msg = str(e)
|
||||
logger.warning(f"Redis连接失败 (第 {retry_count} 次): {error_msg}")
|
||||
|
||||
# 如果设置了最大重试次数且已达到,则抛出异常
|
||||
if max_retries is not None and retry_count >= max_retries:
|
||||
logger.error(f"达到最大重试次数 {max_retries},停止重试")
|
||||
raise
|
||||
|
||||
# 指数退避:每次重试间隔逐渐增加,但不超过最大值
|
||||
logger.info(f"等待 {current_interval} 秒后重试...")
|
||||
time.sleep(current_interval)
|
||||
current_interval = min(current_interval * 1.5, self.MAX_RETRY_INTERVAL)
|
||||
|
||||
def get_client(self):
|
||||
"""
|
||||
获取Redis客户端,如果连接断开则自动重连(带重试机制)
|
||||
:return: Redis客户端实例
|
||||
"""
|
||||
if self._client is None:
|
||||
# 添加超时参数,防止连接超时
|
||||
# socket_timeout: 每次操作的超时时间(秒)
|
||||
# socket_connect_timeout: 连接超时时间(秒)
|
||||
# socket_keepalive: 启用 TCP keepalive
|
||||
# socket_keepalive_options: keepalive 选项
|
||||
self._client = redis.Redis(
|
||||
host='mp.api.suwa3d.com',
|
||||
password='kcV2000',
|
||||
port=6379,
|
||||
db=6,
|
||||
socket_timeout=30, # 操作超时30秒
|
||||
socket_connect_timeout=10, # 连接超时10秒
|
||||
socket_keepalive=True, # 启用 TCP keepalive
|
||||
socket_keepalive_options={}, # keepalive 选项
|
||||
health_check_interval=30 # 健康检查间隔30秒
|
||||
)
|
||||
# 首次连接,使用无限重试直到成功
|
||||
logger.info("初始化Redis连接...")
|
||||
self._client = self._connect_with_retry(max_retries=None)
|
||||
else:
|
||||
# 检查连接是否有效,如果断开则重新连接
|
||||
# 检查连接是否有效,如果断开则重新连接(带重试)
|
||||
try:
|
||||
self._client.ping()
|
||||
except (redis.ConnectionError, redis.TimeoutError, AttributeError):
|
||||
# 连接断开,重新创建连接
|
||||
except (redis.ConnectionError, redis.TimeoutError, AttributeError) as e:
|
||||
# 连接断开,重新创建连接(使用无限重试直到成功)
|
||||
logger.warning(f"Redis连接已断开: {str(e)},开始重新连接...")
|
||||
self._client = None
|
||||
self._client = redis.Redis(
|
||||
host='mp.api.suwa3d.com',
|
||||
password='kcV2000',
|
||||
port=6379,
|
||||
db=6,
|
||||
socket_timeout=30,
|
||||
socket_connect_timeout=10,
|
||||
socket_keepalive=True,
|
||||
socket_keepalive_options={},
|
||||
health_check_interval=30
|
||||
)
|
||||
self._client = self._connect_with_retry(max_retries=None)
|
||||
|
||||
return self._client
|
||||
|
||||
|
||||
|
||||
Reference in new issue
Block a user