分布式任务监控体系构建:从核心维度到Celery+Prometheus实战
1. 项目概述为什么分布式任务监控是系统稳定的生命线最近在梳理团队的技术债发现一个老生常谈但又总被轻视的问题任务监控。尤其是在微服务和分布式架构成为标配的今天一个业务请求可能横跨十几个服务背后触发几十个异步任务。当用户反馈“我的订单状态怎么没更新”或者“报表怎么还没生成好”时如果还靠“登录服务器看日志”这种原始手段排查起来简直就是大海捞针运维同学和开发同学互相“踢皮球”的戏码天天上演。分布式任务监控听起来像是运维的专属领域但实际上它是任何一位负责后端系统稳定性的工程师都必须掌握的“生存技能”。它要解决的远不止“任务是否完成”这么简单而是贯穿于任务生命周期的全链路可观测性问题。简单来说一个健壮的分布式任务监控体系需要回答以下几个核心问题任务在哪里运行定位问题节点、任务当前什么状态运行中、成功、失败、重试中、任务执行了多久性能瓶颈、如果失败了为什么失败根因分析以及失败后如何处理容错与自愈。这不仅仅是技术选型更是一种工程思维和团队协作方式的体现。一个清晰的监控视图能让开发快速定位代码BUG让运维高效处理线上告警最终提升整个系统的可维护性和用户体验。接下来我就结合这几年在复杂业务系统里趟过的坑拆解一下构建这套监控体系的核心思路、技术选型与实操细节。2. 监控体系的核心维度与设计思路在设计监控方案前最忌讳的就是一上来就讨论用Prometheus还是ELK。工具是为目标服务的。我们必须先明确对于一个分布式任务我们需要从哪些维度去观测它。我通常将其归纳为四个核心维度状态、性能、链路和资源。这四个维度相互关联共同构成了任务健康度的完整画像。2.1 状态监控任务的生命体征状态监控是最基本也最直观的。它回答“任务是否还活着结果如何”。关键状态枚举一个任务的生命周期通常包括PENDING等待调度、RUNNING执行中、SUCCESS成功、FAILURE失败、RETRYING重试中、REVOKED被终止等。监控系统必须能准确捕获并持久化这些状态变迁。状态持久化与查询状态信息不能只存在于内存或短暂的消息队列中。必须有一个可靠的存储后端如Redis、MySQL、PostgreSQL来记录每次状态变化的时间戳和上下文。这样我们才能查询历史任务、分析失败规律。失败归因FAILURE状态本身信息量很低。监控的关键在于捕获并关联失败时的异常信息Exception Traceback、错误码、以及触发失败的任务参数。这需要任务框架在捕获异常后将完整的错误堆栈和上下文序列化并存储。实操心得不要只存一个简单的错误消息字符串。一定要存储完整的序列化异常对象或堆栈跟踪。我们曾遇到一个任务随机失败日志里只有“连接超时”但通过查询存储的详细堆栈发现是底层一个数据库连接池在特定参数下存在的竞争条件问题光看简单错误描述根本无法定位。2.2 性能监控发现瓶颈与优化点性能监控关注“任务执行得怎么样快还是慢”。这对于识别系统瓶颈、进行容量规划至关重要。核心指标任务耗时Duration从开始执行到结束的总时间。这是最直接的性能指标。排队时间Latency从任务被创建到真正开始执行的时间。过长的排队时间通常意味着消费者Worker不足或任务队列积压。吞吐量Throughput单位时间内成功处理的任务数量。执行时间分布通过直方图或分位数如p50, p95, p99来观察避免平均数带来的误导。比如大部分任务在100ms内完成但p99达到10秒说明存在一些“长尾任务”严重拖慢整体体验。指标采集点需要在任务执行的关键节点埋点并记录时间戳例如enqueue_time入队时间、start_time开始执行时间、end_time结束时间。通过计算差值得到排队时间和执行耗时。2.3 链路监控构建任务执行的“故事线”在分布式环境下一个用户请求可能触发一个主任务该主任务又会派生出多个子任务这些子任务可能在不同的服务或队列中执行。链路监控Trace就是为了还原这个完整的“调用树”。TraceID 贯穿为每个用户请求或初始任务生成一个唯一的TraceID并确保该ID在所有衍生的子任务、RPC调用、消息传递中都能被传递下去。Span 记录每个任务或一个任务内部的关键阶段如“调用外部API”、“写入数据库”都是一个Span。记录Span的开始、结束时间、标签如服务名、任务名、参数摘要和父子关系。价值当某个环节出错时可以通过TraceID快速检索到整个任务链路的执行情况一眼看清是哪个子任务失败以及失败前后都发生了什么。这对于调试复杂业务流程不可或缺。2.4 资源监控任务执行的环境健康度任务跑在具体的Worker进程或容器中。Worker本身的健康度直接影响任务执行。监控对象Worker进程CPU、内存使用率是否发生OOM内存溢出。队列Broker消息积压数量Backlog、入队/出队速率。Redis或RabbitMQ的队列长度是核心预警指标。存储后端连接数、读写延迟、存储空间如Redis的used_memory。关联分析当发现任务大量失败或超时时应第一时间查看对应Worker和队列的资源指标。可能是Worker所在宿主机资源不足也可能是队列积压导致任务饿死。3. 主流技术栈选型与组合实践明确了监控维度接下来就是工具选型。没有银弹最佳实践通常是多个工具的组合。下面这张表对比了不同场景下的常见选择监控维度常用工具/方案核心作用适用场景与备注状态/元数据存储Redis, PostgreSQL, MySQL存储任务ID、状态、参数、结果、错误信息Redis性能好适合状态频繁更新但可能丢失PG/MySQL可靠性高适合审计和复杂查询。Celery默认用Redis/Broker存结果但建议用数据库做持久化。指标与性能收集Prometheus Grafana采集和存储耗时、吞吐量等指标并可视化Prometheus拉模式适合服务化暴露metrics需要任务框架支持或自行埋点暴露指标如使用prometheus_client。日志集中与检索ELK Stack (Elasticsearch, Logstash, Kibana) 或 Loki收集、索引和搜索所有Worker和任务的日志必须为每条日志关联上task_id和trace_id否则日志就是孤岛。Loki轻量但对查询能力有损。分布式链路追踪Jaeger, Zipkin, SkyWalking收集、存储和展示跨服务的调用链路Trace需要业务代码和任务框架进行埋点Instrumentation。Jaeger与OpenTracing/OpenTelemetry标准结合较好。实时告警Prometheus Alertmanager, Grafana Alerts基于指标阈值如失败率5%触发告警告警规则要精细避免告警风暴。例如按任务类型、业务线分别设置告警。可视化与DashboardGrafana将以上所有数据源Prometheus, Loki, Jaeger整合到一个面板创建面向不同角色开发、运维、产品的Dashboard。开发关心失败任务详情运维关心队列积压。组合实践案例我们目前的生产环境采用以下组合任务框架Celery使用Redis作为Broker但使用PostgreSQL作为“结果后端”Result Backend进行状态持久化。指标在每个Celery Worker中集成prometheus_client暴露tasks_total,tasks_failed,task_duration_seconds等自定义指标。Prometheus定时抓取。日志所有应用和Worker日志通过Filebeat发送到Elasticsearch日志格式强制包含task_id和trace_id。链路使用OpenTelemetry SDK进行手动埋点将Celery任务执行作为一个Span发送到Jaeger。告警与可视化在Grafana中创建Dashboard数据源分别连接Prometheus看指标、Elasticsearch查日志、Jaeger看链路。关键告警如某类任务失败率连续5分钟超过1%通过Alertmanager配置发送至钉钉/企业微信。这个组合确保了从宏观指标到微观日志链路的全覆盖。4. 基于Celery与Prometheus的监控实现详解理论说再多不如一行代码。我们以最常用的Python分布式任务队列Celery和监控事实标准Prometheus为例拆解如何一步步实现深度监控。4.1 基础监控搭建事件与指标暴露Celery本身提供了丰富的事件Events我们可以监听这些事件来生成监控指标。首先安装必要的库pip install celery prometheus-client然后可以创建一个Prometheus的指标收集器文件例如celery_metrics.pyfrom prometheus_client import Counter, Histogram, Gauge, start_http_server import time # 定义指标 TASKS_STARTED Counter(celery_tasks_started_total, Total number of tasks started, [worker, task]) TASKS_SUCCEEDED Counter(celery_tasks_succeeded_total, Total number of tasks succeeded, [worker, task]) TASKS_FAILED Counter(celery_tasks_failed_total, Total number of tasks failed, [worker, task]) TASKS_RETRIED Counter(celery_tasks_retried_total, Total number of tasks retried, [worker, task]) TASK_DURATION Histogram(celery_task_duration_seconds, Task execution duration in seconds, [worker, task], buckets(0.1, 0.5, 1.0, 2.0, 5.0, 10.0, 30.0, 60.0, float(inf))) TASKS_ACTIVE Gauge(celery_tasks_active, Number of currently executing tasks, [worker]) class PrometheusMetrics: def __init__(self): self.task_start_time {} def handle_task_started(self, event): 处理任务开始事件 worker event[hostname] task event[name] uuid event[uuid] self.task_start_time[uuid] time.time() TASKS_STARTED.labels(workerworker, tasktask).inc() TASKS_ACTIVE.labels(workerworker).inc() def handle_task_succeeded(self, event): 处理任务成功事件 worker event[hostname] task event[name] uuid event[uuid] TASKS_SUCCEEDED.labels(workerworker, tasktask).inc() TASKS_ACTIVE.labels(workerworker).dec() self._record_duration(uuid, worker, task) def handle_task_failed(self, event): 处理任务失败事件 worker event[hostname] task event[name] uuid event[uuid] TASKS_FAILED.labels(workerworker, tasktask).inc() TASKS_ACTIVE.labels(workerworker).dec() self._record_duration(uuid, worker, task) def handle_task_retried(self, event): 处理任务重试事件 worker event[hostname] task event[name] TASKS_RETRIED.labels(workerworker, tasktask).inc() def _record_duration(self, task_uuid, worker, task): 记录任务耗时 start_time self.task_start_time.pop(task_uuid, None) if start_time: duration time.time() - start_time TASK_DURATION.labels(workerworker, tasktask).observe(duration) # 启动一个HTTP服务供Prometheus拉取指标 start_http_server(8000)在你的Celery应用初始化后启动事件监听并注册这个处理器from celery import Celery from celery.events import EventReceiver import threading from your_module.celery_metrics import PrometheusMetrics app Celery(myapp, brokerredis://localhost:6379/0) def start_event_listener(): metrics PrometheusMetrics() with app.connection() as connection: recv EventReceiver(connection, handlers{ task-started: metrics.handle_task_started, task-succeeded: metrics.handle_task_succeeded, task-failed: metrics.handle_task_failed, task-retried: metrics.handle_task_retried, }) recv.capture(limitNone, timeoutNone, wakeupTrue) # 在新线程中启动监听器避免阻塞主线程 thread threading.Thread(targetstart_event_listener, daemonTrue) thread.start()现在访问http://your-worker-host:8000/metrics就能看到Celery任务相关的所有指标了。在Prometheus的配置文件中添加这个目标的抓取配置即可。4.2 链路追踪集成为任务加上“身份证”仅有指标和日志还不够我们需要链路。这里使用OpenTelemetryOTel来演示它是OpenTracing和OpenCensus的融合标准。安装OpenTelemetry库pip install opentelemetry-api opentelemetry-sdk opentelemetry-instrumentation-celery opentelemetry-exporter-jaeger在Celery Worker启动脚本中进行初始化from opentelemetry import trace from opentelemetry.sdk.trace import TracerProvider from opentelemetry.sdk.trace.export import BatchSpanProcessor from opentelemetry.exporter.jaeger.thrift import JaegerExporter from opentelemetry.instrumentation.celery import CeleryInstrumentor # 设置全局的TracerProvider trace.set_tracer_provider(TracerProvider()) # 创建Jaeger导出器 jaeger_exporter JaegerExporter( agent_host_namelocalhost, agent_port6831, ) # 将导出器添加到Span处理器 span_processor BatchSpanProcessor(jaeger_exporter) trace.get_tracer_provider().add_span_processor(span_processor) # 自动检测InstrumentCelery应用 CeleryInstrumentor().instrument()这样Celery任务的执行会自动被创建为一个Span并携带一个唯一的TraceID。你需要在任务函数内部将重要的子操作如数据库查询、外部API调用也创建为子Span。同时确保在打印日志时将当前的TraceID记录到日志上下文中。4.3 日志规范化让每一条日志都可追踪日志是排查问题的最终武器但杂乱的日志等于没有日志。我们需要结构化日志并与链路关联。使用structlog或python-json-logger这样的库来输出JSON格式的日志并自动注入上下文。import structlog from celery import current_task # 配置structlog structlog.configure( processors[ structlog.processors.add_log_level, structlog.processors.StackInfoRenderer(), structlog.processors.format_exc_info, structlog.processors.TimeStamper(fmtiso), structlog.processors.JSONRenderer() ], context_classdict, logger_factorystructlog.PrintLoggerFactory(), wrapper_classstructlog.BoundLogger, cache_logger_on_first_useTrue, ) def get_logger(): 获取一个绑定了任务上下文的logger # 尝试从当前任务中获取ID和TraceID task_id getattr(current_task, request, {}).get(id, no_task) # 假设我们从OpenTelemetry上下文中获取TraceID span trace.get_current_span() trace_id format(span.get_span_context().trace_id, 032x) if span else no_trace # 返回一个预绑定上下文的logger return structlog.get_logger(task_idtask_id, trace_idtrace_id) # 在任务中使用 app.task def process_order(order_id): logger get_logger() logger.info(start_processing_order, order_idorder_id) try: # ... 业务逻辑 ... logger.info(order_processed_successfully) except Exception as e: logger.error(order_processing_failed, exc_infoe, order_idorder_id) raise这样每一条日志都会自动包含task_id和trace_id字段。当日志被收集到ELK后你可以通过trace_id:xxx轻松过滤出整个任务链路的所有相关日志。5. 告警策略设计与故障排查实战监控数据只有转化为 actionable 的告警才有价值。告警不是越多越好而是要精准、有效避免疲劳。5.1 分层告警策略我们采用分层告警策略从紧急到日常P0 紧急告警需要立即介入规则某核心业务任务如支付回调失败率在5分钟内持续 5%。动作电话/短信通知值班人员。告警信息需包含任务名称、失败率、最近错误样例、相关TraceID链接。P1 重要告警需要当天处理规则任何类型任务队列积压数量超过1000且持续增长。动作企业微信/钉钉群通知。告警信息需包含队列名、积压数、增长速率、对应的Worker状态。P2 预警需要关注规则任务平均耗时p50相比上周同一时间增长超过50%。动作发送至监控看板或每日运维报告供定期复盘。在Prometheus Alertmanager中可以通过severity标签来区分级别并配置不同的接收器和路由规则。5.2 故障排查SOP标准作业程序当告警响起一个清晰的排查路径能节省大量时间。以下是我们内部的一个简易SOP确认告警查看告警详情确认是哪个指标触发的失败率耗时队列积压。查看Dashboard失败率告警立即在Grafana上查看该任务类型的失败率面板确认是全局性问题还是个别Worker问题。查看最近失败任务的错误信息从任务结果后端或日志中。队列积压告警查看队列长度变化图确认是突发流量还是持续增长。同时查看对应Worker的CPU/内存指标和日志看是否有Worker宕机或处理变慢。耗时告警查看该任务耗时的分位数图p95, p99确认是整体变慢还是长尾效应。关联查看同一时间段内数据库、外部API的响应时间。追踪具体任务从失败任务列表中选取一个最近的失败task_id。步骤A查任务详情通过管理界面或直接查询数据库Celery的taskmeta表或自定义结果表获取该任务的参数、完整错误堆栈。步骤B查日志链路用该任务的trace_id在Kibana或日志平台中搜索获取该任务在所有相关服务中的执行日志。步骤C查调用链路用trace_id在Jaeger UI中查看完整的分布式调用轨迹图可视化地定位失败发生在哪个环节。根因分析与解决结合错误堆栈、日志上下文和链路图定位代码BUG、配置错误、资源不足或依赖服务故障等根因并进行修复。复盘与改进故障解决后记录复盘文档。思考监控是否覆盖到了告警阈值是否合理排查工具链是否顺畅是否有预案可以避免或自动恢复5.3 常见问题与避坑指南问题一Worker失联但任务状态一直显示RUNNING原因Worker进程被强制杀死如OOM Killer未能向Broker发送任务失败的事件。解决方案启用Celery的task_acks_late和worker_prefetch_multiplier 1配置确保任务不会被预取且只在成功后才确认这样Worker崩溃后任务会重新分配给其他Worker。为Worker进程设置健康检查端点并结合外部监控如K8s Liveness Probe来重启不健康的Worker。实现一个定时清理任务扫描那些started时间过长如超过任务超时时间2倍但状态仍是RUNNING的任务将其标记为FAILURE并记录清理原因。问题二Prometheus指标丢失或不准原因事件监听器线程崩溃Worker重启导致内存中的计数器重置任务执行极快开始和结束事件几乎同时发生导致时序问题。解决方案加强事件监听器的异常处理记录其自身日志。对于计数器类指标尽量使用Prometheus的increase()或rate()函数来查询速率而不是直接使用瞬时值这可以容忍重启。在handle_task_started中记录开始时间时如果发现该task_uuid已存在可能由于事件重复则忽略或记录警告。问题三日志量巨大查询缓慢原因所有日志不分级别全量采集日志格式非结构化无法高效索引。解决方案在日志收集端如Filebeat或应用层进行过滤只采集WARNING及以上级别的日志INFO级日志按采样率采集如10%。坚定不移地推行结构化日志JSON并明确日志字段规范。Elasticsearch对结构化字段的索引和查询效率远高于对原始文本的全文检索。根据日志热度在Elasticsearch中设置不同的索引生命周期策略ILM比如最近3天的日志放在热节点3天到30天的日志移到温节点并减少副本数30天以上的移到冷节点或归档。构建一个高效的分布式任务监控体系是一个从工具搭建到流程规范再到文化建设的系统工程。它始于几个简单的指标暴露成长于一次次故障排查的锤炼最终成为团队研发效能和系统稳定性的坚实基石。

相关新闻

OpenClaw轻量级AI技能编排引擎部署与Kimi Free Tier实战指南

OpenClaw轻量级AI技能编排引擎部署与Kimi Free Tier实战指南

1. OpenClaw不是另一个“Dify平替”,它本质是面向工程化AI工作流的轻量级技能编排引擎OpenClaw(也常被社区称为Clawdbot)在2024年底开源后迅速引发关注,但大量初学者误把它当作“又一个低代码AI应用平台”——这是理解偏差的起点。…

2026/6/24 21:00:23阅读更多 →
高中生工程学奥赛冠军项目拆解:从字母识别到多学科融合的工程实践

高中生工程学奥赛冠军项目拆解:从字母识别到多学科融合的工程实践

1. 从“b”还是“d”的困惑到工程学奥赛冠军:一个高中生项目的深度拆解最近在翻看一些青少年科技创新项目时,一个标题特别吸引我:“Is it a ‘b’ or a ‘d’? See how a high school student went from having an idea to winning the Engi…

2026/6/24 21:00:23阅读更多 →
Simulink模块参数高效访问与管理:从手动调试到自动化工程实践

Simulink模块参数高效访问与管理:从手动调试到自动化工程实践

1. 项目概述:为什么我们需要“轻松访问”模块参数?在Simulink仿真建模的日常工作中,无论是调试一个复杂的电机控制算法,还是优化一个通信系统的滤波器参数,我们几乎无时无刻不在与模块参数打交道。你是否有过这样的经历…

2026/6/24 20:55:21阅读更多 →
MATLAB社区年度规划:从环境配置到专业仿真的全链路实践指南

MATLAB社区年度规划:从环境配置到专业仿真的全链路实践指南

1. 项目概述:MATLAB社区的新年问候与年度规划又到了一年伊始,对于像我们这样的MATLAB社区成员来说,这不仅仅是一个简单的问候。一句“今年也请多多关照”,背后承载的是对过去一年技术交流的回顾,以及对新一年共同成长的…

2026/6/24 22:27:33阅读更多 →
从Drupal漏洞到Root权限:DC1靶场渗透实战全解析

从Drupal漏洞到Root权限:DC1靶场渗透实战全解析

1. 项目概述:一次经典的“老系统”渗透之旅最近在复现一个非常经典的渗透测试靶场——DC1。这个靶场之所以经典,是因为它完美复现了一个在真实环境中屡见不鲜的场景:一个使用老旧内容管理系统(CMS)的Web服务器&#xf…

2026/6/24 22:27:33阅读更多 →
MATLAB单元测试中的Mock技术:从原理到工程实践

MATLAB单元测试中的Mock技术:从原理到工程实践

1. 项目概述:为什么我们需要“Mock”?在软件开发和算法验证的世界里,我们常常会遇到一个令人头疼的场景:你正在编写一个功能模块,比如一个复杂的信号处理算法,它依赖于另一个尚未完成的模块(比如…

2026/6/24 22:27:33阅读更多 →
CVE-2025-4664漏洞复现:跨源数据泄露原理与浏览器安全攻防实践

CVE-2025-4664漏洞复现:跨源数据泄露原理与浏览器安全攻防实践

1. 项目概述:一次对现代浏览器安全边界的“越狱”尝试 最近在安全研究圈里,CVE-2025-4664这个编号被频繁提及,它指向的是Google Chrome浏览器中一个相当棘手的跨源数据泄露漏洞。简单来说,这个漏洞允许一个恶意网站,在…

2026/6/24 22:27:33阅读更多 →
OpenClaw本地AI工作流引擎实战:离线运行+飞书集成+配置即代码

OpenClaw本地AI工作流引擎实战:离线运行+飞书集成+配置即代码

1. OpenClaw不是“飞书AI插件”,而是你个人工作流的智能中枢 很多人第一次看到“飞书OpenClaw插件”这个说法,下意识就以为它是像飞书文档里点几下就能启用的轻量级小工具——点开、授权、搞定。我最初也这么想,结果在本地跑第一条 openclaw…

2026/6/24 22:27:33阅读更多 →
Nginx国密SSL双轨制配置实战:从编译到部署全流程详解

Nginx国密SSL双轨制配置实战:从编译到部署全流程详解

1. 项目概述:为什么国密SSL证书不再是“可选项”最近给一个金融行业的客户做安全加固,对方技术负责人上来就问:“咱们的系统能不能支持国密SSL?” 我当时心里咯噔一下,知道这事儿已经从一个技术选型问题,变…

2026/6/24 22:22:30阅读更多 →
【人工智能】一文搞定到底什么是智能体

【人工智能】一文搞定到底什么是智能体

【人工智能】一文搞定到底什么是智能体 一文搞定到底什么是智能体【人工智能】一文搞定到底什么是智能体一. LM,WorkFlow,Agent分别有什么么不同二. Agent的思考过程是怎样的三. Agent的五个核心部分1)LLM2)Prompt3)Me…

2026/6/24 7:33:03阅读更多 →
嵌入式GUI控件实战:ROTARY、SCROLLBAR、SLIDER原理与应用

嵌入式GUI控件实战:ROTARY、SCROLLBAR、SLIDER原理与应用

1. 嵌入式GUI控件:从原理到实战的深度解析在嵌入式系统开发中,图形用户界面(GUI)的设计与实现往往是项目从“能用”到“好用”的关键一跃。不同于资源充沛的PC或移动平台,嵌入式设备的GUI需要在有限的CPU性能、内存空间…

2026/6/24 2:12:09阅读更多 →
Google AI Studio 300美元额度的真相与实战指南

Google AI Studio 300美元额度的真相与实战指南

1. 这300美金不是“送钱”,而是Google埋下的第一道技术门槛 你看到标题里那个醒目的“$300美金”时,第一反应可能是:又一个免费额度?领完就完事?我亲手试过——这300美金根本不是红包,而是一张入场券&…

2026/6/24 7:37:00阅读更多 →
TaskJuggler脚本编程入门:用代码实现自动化项目管理

TaskJuggler脚本编程入门:用代码实现自动化项目管理

TaskJuggler脚本编程入门:用代码实现自动化项目管理 【免费下载链接】TaskJuggler TaskJuggler - Project Management beyond Gantt chart drawing 项目地址: https://gitcode.com/gh_mirrors/ta/TaskJuggler TaskJuggler是一款强大的开源项目管理工具&#…

2026/6/24 0:02:41阅读更多 →
终极教程:使用angular-mobile-nav实现流畅的移动页面过渡效果

终极教程:使用angular-mobile-nav实现流畅的移动页面过渡效果

终极教程:使用angular-mobile-nav实现流畅的移动页面过渡效果 【免费下载链接】angular-mobile-nav An angular navigation service for mobile applications 项目地址: https://gitcode.com/gh_mirrors/an/angular-mobile-nav angular-mobile-nav是一款专为…

2026/6/24 0:02:41阅读更多 →
Wan2.1-Fun-V1.1-1.3B-InP Web UI使用教程:无需代码的AI视频创作

Wan2.1-Fun-V1.1-1.3B-InP Web UI使用教程:无需代码的AI视频创作

Wan2.1-Fun-V1.1-1.3B-InP Web UI使用教程:无需代码的AI视频创作 【免费下载链接】Wan2.1-Fun-V1.1-1.3B-InP 项目地址: https://ai.gitcode.com/hf_mirrors/PAI/Wan2.1-Fun-V1.1-1.3B-InP Wan2.1-Fun-V1.1-1.3B-InP是一款强大的AI视频创作工具,…

2026/6/24 0:02:41阅读更多 →