ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Java+IoT+AI实战:百万级人脸库毫秒检索与跨摄像头轨迹追踪系统

Java+IoT+AI实战:百万级人脸库毫秒检索与跨摄像头轨迹追踪系统 说实话第一眼看到这个标题我脑子里蹦出来的画面不是技术架构图而是去年某次联调现场几十路摄像头画面在大屏上滚一个目标从A栋大堂出现十分钟后要在B栋地库出口重新捞回来。人脸库压到百万级之后原来的MySQL比对方案直接被打回原形查询接口从几十毫秒一路飙到两秒开外跨摄像头轨迹更是靠人肉肉眼去追。项目最后能用“毫秒检索 轨迹追踪”这个组合交卷靠的正是Java、IoT、AI三套技术栈分头死磕再把它们拧成一条完整的链路。这篇文章就是那次实战的全过程复盘。我不会给你铺一堆PPT架构图而是把真实跑通的方案、每个环节的选型理由、关键参数计算、踩过的坑连同可以直接抄走的代码片段一起放出来。适合那些准备做人脸识别平台、视频结构化系统、或者被“百万级底库”和“轨迹追踪”这两个需求折磨得睡不着的Java工程师和IoT从业者。1. 整体设计与技术选型三叉戟各守一摊1.1 这个系统到底要解决什么问题先把这个项目的真实需求拆开看。业务方给的原始需求只有两句话第一人脸底库要支持百万量级单张照片检索响应时间要求在毫秒级第二同一目标在多个摄像头下出现时能自动串联成一条轨迹并且在轨迹回放页面能按时间轴拖拽查看。听起来不复杂但你往下拆就会发现全是硬钉子。百万级人脸库意味着你不可能用传统的关系型数据库做“每条记录比对”一张人脸特征通常是128维到512维的浮点数组百万条特征做暴力计算就是上亿次浮点运算。跨摄像头轨迹追踪意味着你必须先解决“同一个人在不同摄像头下长得不完全一样”的问题——角度、光线、遮挡都会让同一个人的特征向量产生漂移。更麻烦的是摄像头遍布园区各个出入口设备品牌混杂有海康的、大华的、还有几路老旧的RTSP模拟信号源。我当时的判断是这不是一个纯算法项目也不是一个纯后台项目而是一个标准的物联网数据管道 AI推理 高并发检索的混合体。Java负责的是整个系统的骨架和业务编排IoT负责的是设备接入和数据采集AI负责的是人脸检测、特征提取和轨迹推理。三块独立演进但必须在接口层面严丝合缝地对接。1.2 Java、IoT、AI各自负责什么在实际交付的架构里三部分的分工非常清晰。IoT这一层负责“把物理世界变成数据”。所有摄像头通过RTSP协议接入由接入网关统一管理。这个网关做三件事拉取视频流、按帧率抽帧、把图片投递给后续模块。我用的Java写了一个基于Netty的网关服务配合FFmpeg做视频流解码。为什么不直接用海康的SDK因为项目里有非海康设备SDK绑定太死后面换设备就要改代码而RTSP FFmpeg是通用协议任何支持RTSP的设备都能接入。AI这一层负责“从图像里提取语义信息”。人脸检测用YOLOv8或者SCRFD这类开源模型检测到人脸后裁剪出来再送进ArcFace网络提取512维特征向量。这一层我用Python写了独立的推理服务通过gRPC对外暴露接口Java后台通过proto文件生成客户端调用。很多人问我为什么不用Java直接做推理说实话Java生态里跑深度模型不是不行DJL、ONNX Runtime都支持但团队对Python算法栈的迭代速度要求太高模型一换就要重新验证解耦以后两边互不耽误。Java这一层负责“把数据变成业务价值”。它承接三块核心能力一是底库管理注册新人的时候把特征向量写入向量数据库二是检索服务收到一张待识别照片后提取特征、执行向量检索、返回TopN结果三是轨迹引擎把检索命中的结果按时间和空间关联关系串成轨迹。Java在这里最大的优势不是性能性能反而要靠底层组件而是稳定性和工程化能力——Spring Boot的生态、事务控制、权限体系、监控埋点这些写业务系统太顺手了。1.3 为什么这么拆而不是一锅端这个架构不是设计出来的是被现实逼出来的。最开始有人提议“全用Python一把梭”FastAPI写后台算法也跑在同一个进程里。原型demo确实跑通了但一上压测就露馅Python端高并发连接管理费劲数据库迁移和事务处理绕来绕去运维部署更是心累。Java做不到的事情Python能做算法迭代Python做不到的事情Java能做工程韧性把两者结合才是这个场景的最优解。IoT层独立出来的原因更直接——摄像头和网络是不可靠的设备掉线、码流波动、丢帧是常态。如果设备接入逻辑和业务逻辑耦合在一起一个摄像头抽搐就能拖垮整条业务链路。独立网关可以把这种不稳定性隔离在边缘摄像头断了网关缓存任务、重试连接业务侧几乎无感。用一句话总结选型思路Java管底盘IoT管入口AI管大脑各守各的边界用清晰的接口协议连接彼此。这个决策在后面整个开发周期里都被证明是对的每次出问题都能快速定位到具体层而不是在纠缠不清的代码里大海捞针。2. 百万级人脸库毫秒检索的实现方案2.1 把“人脸比对”变成“向量检索”这是整个项目最核心的一个认知转变。传统做法是把人脸图片直接存进数据库检索时拿目标照片和底库照片逐张比对。这种方案在小数据量下没问题一百人、一千人都能扛但百万级底库下每秒钟就算只做100次检索计算量也是天文数字。真正的做法是提前把每张人脸照片变成一串数字——特征向量。ArcFace输出的512维特征向量可以理解为把这张脸的“长相”映射到一个人为定义的空间里的坐标点。长得越像的人坐标挨得越近长得不像的人距离越远。于是“人脸比对”就变成了“在向量空间里寻找距离最近的点”这个操作叫向量检索。距离度量我用的是余弦相似度。两个512维向量的余弦值越接近1说明方向越一致也就是越像。实际代码里为了统一会把所有向量做过L2归一化这样余弦相似度和内积结果就等价了计算上可以省一次除法。向量检索为什么快因为它不是暴力遍历百万条数据而是利用索引结构提前划定“搜索范围”。就像查字典你不会从第一页翻到最后一页而是根据拼音首字母直接翻到那一块区域。向量索引也是这个思路。百万级数据量属于中小规模用合理的索引配置完全可以做到毫秒级响应。2.2 检索引擎选型Milvus、FAISS、ES怎么选这里我做了三组对比测试结论非常有代表性。FAISS是Meta开源的向量检索库性能极强但它是个库而不是个服务部署文档相对友好重要的是Java客户端比较弱需要自己做gRPC封装Elasticsearch的向量检索能力依托于Dense Vector类型胜在能和业务数据一起检索不用额外引入新组件但百万级向量在高并发下的表现一般内存占用也比较猛Milvus是专门的向量数据库自带Java SDK支持集合管理、索引构建、标量过滤团队熟悉度也够。最终选了Milvus核心原因有三个第一它有原生Java客户端这对我们这种以Java为主语言的后端团队太重要了不需要额外维护一套协议转换第二Milvus对HNSW索引的支持很成熟自带参数调优的文档不需要像FAISS那样从C层折腾第三它支持标量字段过滤比如我可以给每张人脸带上“性别”“年龄”“所属区域”这些标签检索时可以先过滤再排序业务上可玩性高很多。三者的对比测试结果放在下表测试环境是8核32G的机器底库100万条512维特征引擎单次检索耗时P99并发200 QPSJava客户端成熟度运维成本FAISSIVF_HNSW8ms稳定弱需自研封装高Elasticsearch 8.x35ms偶发超时成熟中Milvus 2.3HNSW12ms稳定成熟官方支持中这个表不是to say FAISS不行恰恰相反FAISS单机性能是最强的。但对Java团队来说Milvus是“够用且最省心”的那个选项。任何选型都要结合团队实际情况不要唯性能论。2.3 索引参数调优从500ms到20ms索引选型定了之后真正花时间的是参数调优。HNSWHierarchical Navigable Small World是我最终使用的索引类型它通过构建多层图结构实现快速跳转检索时从上往下逐层逼近目标。HNSW有两个关键参数M和efConstruction。M控制每个节点的最大连接数M越大图越稠密召回率越高但内存和构建时间也越高efConstruction控制构建时的搜索范围越大构建质量越好但也越慢。经过几轮压测我最终确定的参数是M16efConstruction200efSearch64。在这个配置下100万条底库的检索P99耗时稳定在12ms左右召回率Recall1约95%这就满足了“毫秒级”和“高准确率”两个核心要求。如果追求极端召回率可以加大efSearch到100以上但检索耗时也会明显上涨需要业务侧做取舍。底库的特征向量分片存储也是一个必须考虑的细节。我把底库按业务区域拆成多个Collection比如北区、南区、东区各一个。检索时可以根据“目标最后出现的位置”只查对应区域再把结果合并。这个策略让每次检索的基数平均降到了30万左右进一步压低了延迟。2.4 Java端调用与兜底策略Java端调用Milvus非常简单官方Client SDK封装得挺干净。核心代码思路如下// 初始化Milvus客户端 MilvusServiceClient client new MilvusServiceClient( ConnectParam.newBuilder() .withHost(10.0.0.8) .withPort(19530) .build()); // 构造查询向量 ListFloat queryVector faceFeatureService.extractFeature(imageBytes); // 设置检索参数 SearchParam searchParam SearchParam.newBuilder() .withCollectionName(face_db_zone_north) .withVectors(Collections.singletonList(queryVector)) .withVectorFieldName(feature_vector) .withParams({\ef\: 64}) .withTopK(10) .build(); // 执行检索 RSearchResults response client.search(searchParam);这个代码块看起来简单真正要注意的是查询向量的来源如果待检索的照片本身质量太差特征提取得不准再好的索引也救不回来。所以我在抽取特征之前会加一个质量判断人脸检测置信度低于阈值就直接拒绝检索而不是硬着头皮去比对。这叫“毫不留情地在入口拦脏数据”。兜底策略一样重要。万一某一路向量库节点挂了我做了两重保护第一层是内存缓存把热门的、最近频繁出现的目标特征放到Redis缓存里检索时先查缓存命中就直接返回不落向量库第二层是降级策略如果Milvus连续报错系统自动切换到一个静态的“重点人员底库”一般几千人规模用Java本地暴力比对顶住保证核心业务不中断。3. 跨摄像头轨迹追踪从单点命中到连续轨迹3.1 单点识别不代表能追踪先恶补一下ReID项目做到一半我发现了一个尴尬的现实人脸识别做得好并不意味着轨迹追踪做得好。单摄像头下抓到一张正脸识别人物身份很容易但目标从摄像头A走到摄像头B两个摄像头拍到的可能是完全不同的角度、距离和光照条件直接用人脸特征去匹配相似度经常跌破阈值。这就引入了一个技术点叫ReIDPerson Re-Identification行人重识别。ReID的核心思路是提取整个人的全局特征而不是只看脸——包括衣服颜色、背包、体型、步态等。我用一个轻量的ReID模型对检测到的行人全身图提512维特征和人脸特征一起存起来。轨迹追踪的时候两条线索一起用如果脸足够清楚就用人脸特征做主判断脸部模糊就退而求其次用ReID特征做参考。为什么ReID是轨迹追踪的关键前置技术因为跨摄像头场景下大多数时候人脸的成像质量根本不够用。走廊尽头的摄像头拍到的可能只有一个背影人脸特征无从谈起但全身特征还是可以提取的。ReID和人脸识别不是替代关系而是互补关系两者结合才能保证轨迹在大多数普通场景下不会断掉。3.2 轨迹拼接的核心算法相似度打分 时空约束纯粹靠特征相似度去串联轨迹一定会出现大量误报。因为我不能只回答说“这两个像同一个人”我还要回答“这两个目标在物理上有没有可能是一个人呢”。所以轨迹拼接的算法里必须引入时空约束。核心原理就是构造一个打分函数。假设我在摄像头A的t1时刻抓到了目标X在摄像头B的t2时刻抓到了目标Y要判断X和Y是不是同一个人需要考虑四个维度的分数人脸特征相似度有正脸时、ReID特征相似度、时间间隔合理性、空间拓扑可行性。综合得分超过阈值就把两个抓拍目标串联起来。时间合理性判断逻辑从A到B有物理距离人是跑不过去的。如果A和B相距200米且之间没有捷径正常人走完至少要1分钟那么t1和t2相差只有10秒的同身份推断基本不成立。我会预先建一张摄像头拓扑表记录每对摄像头之间的最短路径距离再根据平均步速约1.2米/秒算出理论可行的时间窗口。空间拓扑判断逻辑两个摄像头如果没有共同的物理覆盖区域那么从A到B必须经过中间的某路摄像头。如果X在t1出现在A下一个抓拍却直接跳到10公里外的C中间完全没有中间点那这个跳变大概率是误报或目标坐车了需要人工复核。选择保留所有候选连接边而不是直接做硬绑定。离线任务会把“抓拍点序列”按时间排序然后使用一个类似最长路径的贪心策略把所有候选边按照综合得分从高到低填充就能还原出目标完整的时空轨迹。这个策略在数据有噪声的场景下非常稳直接硬绑定的方案我在测试里翻车过太多次。3.3 轨迹存储与查询架构轨迹生成之后怎么存、怎么查又是一个新的工程问题。轨迹的本质是“目标ID 有序场景序列”每个场景包含摄像头编号、经纬度、时间戳、抓拍图片地址。这个结构天然适合时序数据库我选了InfluxDB作为轨迹落库的存储。每条轨迹按目标人脸ID做Tag时间戳作为索引场景序列作为Field。查询“某个人在某个时间段的行动路线”就变成了一个简单的范围查询。为了避免百万级底库的检索压力都集中在同一张表我会按天对轨迹做分片默认只查最近7天超过7天自动归档到冷存储。轨迹查询接口的Java实现思路如下GetMapping(/track/{faceId}) public TrackResult queryTrack(PathVariable String faceId, RequestParam Long startTime, RequestParam Long endTime) { // 1. 从缓存查目标基础信息 FaceProfile profile faceCache.get(faceId); if (profile null) { return TrackResult.empty(目标不存在); } // 2. 查询轨迹库 ListTrackPoint points trackStore.query(faceId, startTime, endTime); // 3. 按摄像头拓扑关系补齐缺失信息比如中间某个摄像头没有抓拍但理论存在 ListTrackPoint completed trackTopology.fillGaps(points); return TrackResult.success(completed); }这个接口在高峰期一天的调用量在几十万次左右配合Redis缓存热点目标的轨迹结果P99耗时能控制在80ms以内。注意这里的endTime参数必须参与查询不然百万级目标的轨迹数据会把InfluxDB的扫描范围拉爆。3.4 轨迹聚合的完整流程示例用一个实例把整个轨迹生成过程串一遍。假设目标“张三”先出现在南门入口摄像头CAM_01时间是09:00:00抓拍人脸置信度0.92特征向量v15分钟后出现在园区主干道的CAM_07人脸置信度只有0.45侧脸但ReID特征正常得到特征向量r2又过了8分钟在办公楼前台CAM_12出现人脸置信度0.88特征向量v3。这个流程在我系统中的处理逻辑是CAM_01的抓拍经人脸检索命中底库“张三”创建初始轨迹ID为tr_20240901_001CAM_07的抓拍先做人脸检索置信度低拒绝了硬性匹配但ReID特征与tr_20240901_001上存储的目标全身特征相似度达到0.71同时时间间隔和空间拓扑都符合理论预期于是判定为同一目标的新轨迹点CAM_12的抓拍再次通过人脸检索命中张三相似度0.86时间间隔和空间拓扑也满足追加进轨迹最终这条轨迹包含三个抓拍点覆盖了张三从南门到办公楼前台的完整路径前后跨度15分钟中间没有断点。整个流程没有用到任何神秘的算法库核心就是特征相似度、时空约束、贪心拼接三个模块的组合。模型优化只是把单点的“认人”能力拉高真正让轨迹连续的是工程上严格的时序与地理可行性约束。4. IoT接入与全链路管道摄像头到告警的每一跳4.1 摄像头接入RTSP拉流、解码、抽帧现在把注意力转到IoT接入层。这个模块的高频翻车点不在算法而在“怎么稳定地把每一帧画面从摄像头里拿出来”。摄像头端的标准协议是RTSP。RTSP本身只是一个会话控制协议真正的视频数据用RTP承载编码格式往往是H.264或者H.265。Java生态里直接处理RTP裸流很痛苦我最终的方案是Java网关 FFmpeg子进程配合。具体做法是网关服务维护一个摄像头连接池按需调用FFmpeg命令行拉取RTSP流输出为MJPEG或者裸RGB帧再通过内存队列送给后续的人脸检测模块。用到的FFmpeg命令示例如下ffmpeg -rtsp_transport tcp -i rtsp://user:pass10.0.0.10:554/Streaming/Channels/1 \ -vf fps1,scale1280:720 -f image2pipe -vcodec mjpeg -q:v 3 pipe:1命令里fps1代表每秒抽一帧。有人会觉得一帧太少但人脸识别场景下每秒一帧完全够用因为人走路的速度有限的一秒钟最多也就移动不到两米一帧能保证每2米左右一个采样点。抽帧太多反而会增加人脸检测的重复计算出现大量重复抓拍。这个fps参数我要单独强调一开始我设了5帧每秒结果特征抽取服务直接被打爆缓存里堆了几百万张重复图片排查了一个通宵才找到原因。RTSP传输模式选了TCP而不是默认的UDP是因为UDP在弱网环境下丢包太严重视频流会花屏、卡顿导致抽出来的帧质量差、人脸漏检率高。TCP多了一点延迟但换来的是稳定和可靠在园区局域网环境下这个代价完全可接受。4.2 消息管道与数据处理链路摄像头数据接入之后整个处理链路是异步的中间我用Kafka做数据管道。完整链路如下摄像头 - IoT网关抽帧 - Kafka Topic: raw_frame - 人脸检测服务检测裁剪 - Kafka Topic: face_crop - 特征提取服务提取512维向量 - Kafka Topic: face_feature - 检索/轨迹服务向量检索轨迹拼接 - 结果写入MySQL/Milvus/InfluxDB - 告警/页面展示Kafka的Topic设计看似简单其实有很多讲究。我把raw_frame、face_crop、face_feature拆成三个独立Topic分别对应数据管道的三个阶段。这样做的好处是每个阶段可以独立扩容、独立隔离故障。如果某个阶段的消费能力跟不上积压只会停留在当前Topic不会影响上下游服务。分区的选择也踩过坑。最初把摄像头ID作为分区键想着同一个摄像头的帧能保序处理。结果发现某个摄像头码流特别大把所有数据都堆到同一分区而其他分区闲置造成了严重的数据倾斜消费者组里的节点忙闲不均。后来改成按目标唯一ID底库人脸ID做分区键因为后续处理对“同一目标”的处理顺序更敏感倾斜问题大幅缓解。4.3 端到端延迟拆解与压测结果整个链路是否满足“毫秒级”不能只看检索环节而要看从摄像头抓拍一张照片到页面展示最新轨迹点的端到端延迟。我上线前做了一次全链路压测结果如下表链路环节平均耗时说明摄像头抽帧到Kafka120msFFmpeg管道传输Kafka到人脸检测80ms网络传输 反序列化人脸检测 特征提取180msGPU推理单张512维向量向量检索百万底库12msHNSW索引P99轨迹拼接与入库50msInfluxDB写入端到端合计442ms不含队列积压等待442毫秒的端到端延迟意味着从物理世界“人出现在摄像头里”到系统“知道这个人是谁、他在哪里”中间只需要不到半秒。这个数字在演示的时候很有冲击力但实际上优化空间还很大。瓶颈几乎全在AI推理环节的GPU排队上如果后续上多卡并行推理把检测和特征提取分别拆到不同GPU上理论上可以把端到端延迟压到200毫秒以内。压测时我特意关注了峰值场景早上9点到10点的入园高峰100路摄像头同时工作每秒产生大约200个抓拍任务Kafka Topic的积压最多只涨到5万条左右消费侧CPU水位稳定在70%以下。这个结论可以给同样规模的项目做个参考基线。4.4 缓存、降级与并发控制高并发下面有三件容易被忽视的事热点缓存、降级预案、并发控制。热点缓存是我上线第一周就加的。园区里每天通勤的员工就那几百人他们每天上班都会经过门口摄像头相当于同一批人脸反复触发检索。如果不做缓存这堆重复请求会白白消耗Milvus的查询时间。我用Caffeine在Java服务里加了本地缓存key是“人脸特征向量”value是“底库命中结果”过期时间设成15分钟。实测下来重复抓拍场景的检索QPS直接下降了60%以上效果立竿见影。降级预案是分等级的。一级降级Milvus挂了走Redis缓存 小型本地底库暴力比对二级降级缓存也挂了返回最近一次成功检索的结果并标记“结果时效性降低”三级降级整个检索服务不可用时人脸抓拍照常存储但不再执行实时比对改由离线任务每5分钟补一次。这样保证摄像头端永远不丢数据业务影响降到最低。并发控制是很多人会忽略的细节。特征提取服务是GPU密集型同时跑太多请求反而导致显存溢出和推理时间翻倍。我给Kafka消费者设置了信号量限流每个消费者实例最多同时处理4个推理任务超出部分排队等待。这个参数来自GPU的batch size最大值和显存容量。有时候“限制并发”反而能提升吞吐因为减少了GPU任务切换的开销。5. 实战中踩过的坑与排查速查表5.1 误检和漏检脏数据让检索准确率下滑人脸检测模型不是100%精确的。YouTube上有人把海报上的假人当真人检测出来有人在黑暗走廊里被完全漏掉。人脸库检索系统最怕的不是“漏”而是“误”——误检把一张没有人脸的照片裁出来送去提取特征提取出来的向量是纯噪音。大量噪音进入底库会拉低所有后续检索的准确率。我踩过的一次真实事故是某天运营反馈检索准确率骤降排查了半天发现是门口那台摄像头的镜头被雨滴糊住了导致检测模型把玻璃上的水滴纹路当成“五官”框了出来一天之内给底库塞了两千多条垃圾特征。从那以后我在入库环节加了一道硬校验人脸检测的置信度低于0.7直接丢弃关键点检测左眼、右眼、鼻尖、左嘴角、右嘴角缺失超过2个的直接丢弃人脸宽高小于64像素的直接丢弃。三道闸门下来脏数据的比例下降了95%以上。5.2 时间不同步轨迹错乱的最隐蔽元凶跨摄像头轨迹追踪最让我头痛的不是算法精度而是摄像头时间不同步。排查了一个下午发现两个摄像头记录的抓拍时间差了整整3分钟导致轨迹拼接算法对时间窗口的判断全乱套原本合理的“A到B间隔5分钟”被算成“2分钟”直接超出行走速度上限轨迹被拦腰截断。解决方案是三步走第一所有摄像头强制接入NTP时间同步服务每5分钟校准一次第二IoT网关在抓拍时记录的不是摄像头系统时间而是网关本地收到该帧的时间戳第三轨迹拼接模块里增加一个时间偏差容忍窗口比如默认允许±5秒的偏差超过这个偏差就在日志里标记“时钟可疑”。这三步走完因为时间错乱引发的轨迹断裂问题基本绝迹。5.3 重复抓拍暴增不加聚合轨迹就是一团麻第一次上线轨迹功能产品经理看完页面说“这轨迹怎么是一串珠子密密麻麻全是点”。原因很简单摄像头每秒抽一帧人站在那里不动同一个摄像头5秒内会产生5个抓拍轨迹页面上就显示5个几乎重叠的点。后续的轨迹聚类类库排布非常混乱用户根本看不出来这个人到底走了什么路线。我的解决思路是抓拍聚合——把同一个目标在同一摄像头下的连续抓拍合并成一个“轨迹段”。判定规则是同一人脸ID在同一个摄像头下连续出现且相邻抓拍间隔不超过10秒就归并为同一个停留点只保留第一次抓拍和最后一次抓拍。这样“一串珠子”就变成了“一根线”轨迹清晰了很多。聚合逻辑放在轨迹存储之前直接减少了大概80%的重复数据InfluxDB的写入压力也小了一大截。5.4 排障速查表与最后一个提醒最后整理一份高频问题速查表都是我在实际运维中反复用到的排查点现象可能原因排查方法检索响应突然变慢Milvus索引段数过多查看Milvus segment数量执行手动compact某路摄像头数据持续为空RTSP流中断或账号失效用VLC打开RTSP地址验证检查网关日志的断线重连记录轨迹在特定区域频繁断裂摄像头存在盲区或拓扑信息不完整实地检查该区域物理覆盖补充拓扑表同一个人跨摄像头匹配相似度普遍偏低摄像头画质差异过大提取两端抓拍图做人工对比评估是否需要针对该点位做画质归一化Kafka消费积压持续上涨推理服务GPU负载过高扩容消费者实例或降低抽帧fps这组排查表写出来不是为了让你出问题时对着抄而是想提醒每一个做类似系统的人及时沉淀自己的排障经验比背八股文有用得多。项目上线不是终点后续的稳定运营才是真正考验工程能力的时刻。
返回列表