Java框架 SpringCloud 快速入门: NacosRule 同集群优先的负载均衡
概述集群属性配好了实例也按机房分开了但order-service调user-service时照样跨机房——因为默认的负载均衡规则根本不认识 Nacos 的集群概念得把规则换成NacosRule。纲要承接服务分级存储模型服务 → 集群 → 实例为什么默认规则会跨机房ZoneAvoidanceRule的zone跟 Nacos 的cluster不是一回事NacosRule的选取逻辑同集群优先 → 集群内随机 → 都没有才跨集群附决策流程图跨集群告警日志格式、含义、运维价值配置实战真实application.yml为什么前缀是被调用方服务名为什么写在消费者侧完整可复现的验证流程造两个集群、连调五次、停掉本地集群、观察告警权重配置权重如何影响选择、权重为 0 意味着什么与 Ribbon 自带策略的关系以及 Spring Cloud Alibaba 新版本的写法变化五个容易踩的坑先理清默认规则为什么不认集群上一篇把user-service的三个实例分成了两拨8081、8082挂在HZ集群8083挂在SH集群。order-service也贴上了cluster-nameHZ。按直觉order-service应该只调8081和8082。实测却是三个实例轮流被打到——它还在轮询。原因在于负载均衡规则的默认实现。order-service用的是 Spring Cloud Netflix Ribbon默认 rule 是ZoneAvoidanceRule维度ZoneAvoidanceRule默认NacosRuleNacos 提供区域概念取 Eureka 实例的zone元数据eureka.instance.metadata-map.zone取 Nacos 实例的clusterNamespring.cloud.nacos.discovery.cluster-name数据来源Eureka 的 zoneNacos 注册中心的集群属性我们配了什么没配 zone所有实例 zone 相同 → 退化成轮询—同集群优先不支持支持集群内选择方式轮询随机跨集群行为无告警打 WARN 日志关键点ZoneAvoidanceRule眼里的区域来自 Eureka 的 zone 元数据。我们的工程早就把注册中心换成 Nacos 了Nacos 实例上报的是clusterName两个字段对不上ZoneAvoidanceRule拿到一片空白的 zone 信息只能退化成轮询。所以不是配置写错了是规则选错了。同集群优先这件事得用 Nacos 自己实现的NacosRule。NacosRule 的选取逻辑NacosRule是 Spring Cloud Alibaba 提供的IRule实现包名com.alibaba.cloud.nacos.ribbon.NacosRule。它挑实例分三步是否getInstances(serviceId)拿到服务全部实例过滤掉权重为 0 的实例存在与调用方同集群的健康实例?在同集群实例中按随机方式挑一个打印跨集群访问告警日志WARN 级别在剩余全部实例中按随机方式挑一个返回 Instance发起 HTTP 调用三条要记住优先同集群。从跟自己cluster-name相同的实例里挑。这是它存在的唯一理由。集群内是随机不是轮询。这一点视频里专门对比过连着请求五次被调用的实例顺序是8081 → 8082 → 8082 → 8081 → 8082这种来回跳的序列没有轮询那种整齐的循环。判断是不是轮询最直接的办法就是数次数看规律轮询会严格 1-2-3-1-2-3。本地没有才跨集群。只有当同集群内一个健康实例都没有时才会去别的集群找并且会打一条 WARN 日志。跨集群的那条告警别当成噪音本地集群全挂时order-service的日志里会出现这样一行不同版本实例信息串会有差异主干message一致2021-07-13 23:48:12.316 WARN 21940 --- [nio-8088-exec-3] c.a.c.nacos.ribbon.NacosRule : A cross-cluster call occursname userservice, clusterName HZ, instance Instance{instanceId127.0.0.1#8083#SH#DEFAULT#DEFAULT_GROUPuserservice, ip 127.0.0.1, port 8083}拆开看信息量很足name userservice被调用的服务名clusterName HZ调用方所在的集群也就是我想去哪instance ...#8083#SH#...实际打到的实例SH就是它真实所在的集群也就是说这行日志完整记录了我本该在杭州找用户服务但杭州没人只好打到了上海的 8083。它的价值在于跨机房调用是延迟上涨、带宽成本上升的前兆而这条日志是它最早的信号。正常情况下服务不该跨机房一旦出现告警运维该做的动作是去查HZ集群里的实例为什么掉线——是进程崩了、健康检查没通过还是发布时集体下线了。不配这条告警就看不到业务只会表现为接口慢了一点很难定位。顺带说一句本地集群没了但还能正常返回说明 Nacos 的可用性设计是对的——本地不可用不影响功能只影响性能。这也是集群划分能落地的原因。配置实战两处改动都在消费者侧。给 order-service 配集群order-service/src/main/resources/application.ymlspring:cloud:nacos:server-addr:localhost:8848discovery:cluster-name:HZ# 集群名称cluster-name的值要和本地机房保持一致这里是HZ否则NacosRule会把自己当成没有同集群实例直接走跨集群分支。换掉负载均衡规则这是本篇的核心配置来自终态工程的order-service/src/main/resources/application.yml原样引用userservice:ribbon:NFLoadBalancerRuleClassName:com.alibaba.cloud.nacos.ribbon.NacosRule# 负载均衡规则两个地方容易被问前缀为什么是userservice因为负载均衡规则是按被调用方配的。userservice是被调用的服务名ribbon.NFLoadBalancerRuleClassName是 Ribbon 约定的配置键。写在userservice下面意思是我调userservice时用这个规则。所以我完全可以给另一个服务配别的规则userservice:ribbon:NFLoadBalancerRuleClassName:com.alibaba.cloud.nacos.ribbon.NacosRule# 用户服务走同集群优先orderservice:ribbon:NFLoadBalancerRuleClassName:com.netflix.loadbalancer.RandomRule# 订单服务走纯随机为什么配在消费者侧因为发起调用的是消费者选择实例这个动作发生在消费者进程里Ribbon 的ILoadBalancer跑在客户端。提供方只管把自己注册上去、把cluster-name报给 Nacos它不知道也不会关心谁要调它、按什么规则调。所以规则配置写在order-service不写在user-service——这一点后面要进坑列表。改完重启order-service。工程里还开着 Ribbon 饥饿加载两行配置配合着看ribbon:eager-load:enabled:true# 开启饥饿加载clients:# 指定饥饿加载的服务名称-userservice第一次调用慢、后面快这是懒加载的典型表现eager-load就是让 Ribbon 在启动时就把userservice的实例列表拉下来第一次调用不用等。工程结构改动涉及的模块在终态工程里是这样组织的cloud-demo ├── pom.xml # 聚合父工程统一管理 Spring Cloud Alibaba 版本 ├── eureka-server # 早期用 Eureka后切 Nacos ├── feign-api # 抽出 Feign 的 Client 与实体被 order/user 共同依赖 ├── gateway # 网关10010 ├── user-service │ ├── src/main/java/cn/itcast/user │ │ ├── UserApplication.java │ │ ├── web/UserController.java # GET /user/{id} │ │ ├── service/UserService.java │ │ ├── mapper/UserMapper.java │ │ └── pojo/User.java │ └── src/main/resources/application.yml # cluster-name 写在这里 └── order-service ├── src/main/java/cn/itcast/order │ ├── OrderApplication.java # EnableFeignClients RestTemplate Bean │ ├── web/OrderController.java # GET /order/{orderId} │ ├── service/OrderService.java # 通过 Feign 远程调 userservice │ ├── mapper/OrderMapper.java │ └── pojo/Order.java └── src/main/resources/application.yml # NacosRule 写在这里order-service发起远程调用的代码Feign 版终态工程实际在用的写法packagecn.itcast.order.service;importcn.itcast.feign.clients.UserClient;importcn.itcast.feign.pojo.User;importcn.itcast.order.mapper.OrderMapper;importcn.itcast.order.pojo.Order;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.stereotype.Service;ServicepublicclassOrderService{AutowiredprivateOrderMapperorderMapper;AutowiredprivateUserClientuserClient;publicOrderqueryOrderById(LongorderId){// 1.查询订单OrderorderorderMapper.findById(orderId);// 2.用Feign远程调用服务名 userservice 会走 Ribbon 的负载均衡UseruseruserClient.findById(order.getUserId());// 3.封装user到Orderorder.setUser(user);// 4.返回returnorder;}}UserClient上标FeignClient(userservice)Feign 底层复用 Ribbon所以userservice.ribbon.NFLoadBalancerRuleClassName这条配置对 Feign 调用同样生效——这不是巧合是同一套ILoadBalancer在干活。完整验证流程原理讲完了但这篇最有说服力的地方是能一步步复现出来。下面这套步骤照抄即可。造出一个跨集群的实例列表user-service的application.yml里把集群写上终态工程里这段是注释掉的验证时需要放开spring:cloud:nacos:server-addr:localhost:8848discovery:cluster-name:HZ# 集群名称然后启动三份实例。前两份直接用配置文件里的HZ第三份在 IDEA 的 VM options 里覆盖-Dserver.port8083-Dspring.cloud.nacos.discovery.cluster-nameSH命令行起也行java-Dserver.port8083\-Dspring.cloud.nacos.discovery.cluster-nameSH\-jaruser-service.jar启动完去 Nacos 控制台 → 服务列表 →userservice→ 详情应该看到HZ集群下两个实例、SH集群下一个实例。让消费者站在 HZorder-service的cluster-name配成HZ重启。同样在控制台确认orderservice的集群是HZ——这一步别跳过配错集群名后面的现象会完全不同。连打五次看落在谁身上foriin12345;docurl-shttp://localhost:8088/order/101;echo;done观察点在两个 HZ 实例的控制台日志。工程里开了cn.itcast: debug每个实例处理请求时会打出 MyBatis 的 SQLlogging:level:cn.itcast:debugpattern:dateformat:MM-dd HH:mm:ss:SSS预期结果8081和8082的控制台都有 SQL 输出8083SH 集群的控制台干干净净一条都没有五次调用在 8081/8082 之间的分布没有固定循环规律是随机如果8083也打了日志说明规则没生效——先回去确认userservice.ribbon.NFLoadBalancerRuleClassName的层级缩进对不对。想在响应里直接看到端口、省得来回切控制台可以临时加一个探针接口packagecn.itcast.user.web;importorg.springframework.beans.factory.annotation.Value;importorg.springframework.web.bind.annotation.GetMapping;importorg.springframework.web.bind.annotation.RequestMapping;importorg.springframework.web.bind.annotation.RestController;RestControllerRequestMapping(/probe)publicclassProbeController{Value(${server.port})privateStringport;Value(${spring.cloud.nacos.discovery.cluster-name:UNKNOWN})privateStringclusterName;/** * 联调探针返回当前实例的端口与集群用来确认请求落到了哪个实例 * 路径/probe/instance */GetMapping(/instance)publicStringinstance(){returnportport, clusterclusterName;}}然后在order-service里换成一个能带出探针结果的调用看一眼就行。上线前记得删掉。停掉 HZ制造跨集群把8081、8082两个进程停掉让HZ集群彻底没人。回到 Nacos 控制台刷新userservice会显示健康实例数为 1点进详情HZ集群是空的。再打请求curl-shttp://localhost:8088/order/101;echo这次能正常返回功能不降级这是重点8083的控制台开始出现 SQL 日志同时order-service的控制台出现前面那条A cross-cluster call occurs告警。整个过程用一张时序图看更清楚userservice-3(SH:8083)userservice-1(HZ:8081)Nacos 注册中心orderservice(HZ)浏览器userservice-3(SH:8083)userservice-1(HZ:8081)Nacos 注册中心orderservice(HZ)浏览器阶段一HZ 集群健康阶段二HZ 实例全部下线GET /order/101拉取 userservice 实例列表8081(HZ), 8082(HZ), 8083(SH)NacosRule同集群过滤后随机HTTP 调用UserOrderGET /order/101拉取 userservice 实例列表仅 8083(SH)同集群无实例打印 WARN跨集群 HTTP 调用UserOrder成功但跨了机房权重的影响集群解决的是往哪个机房打权重解决的是同一批实例里各打多少。Nacos 控制台的实例列表里每个实例都有权重点编辑就能改默认值是 1。规则是这样的权重会影响选择结果。权重高的实例被挑中的概率更大用来让配置好的机器多扛点流量。权重为 0 的实例不会被选中。这是权重最实用的一条用法想让某台机器退出流量不用停进程把权重改 0 就行进程还在、注册还在、健康状态还在但没有任何请求会过去。第二条有个经典的误判把权重改成 0 之后Nacos 控制台里这个实例依然显示为健康实例健康实例数不变。有同学看到健康就以为流量还过去其实请求早就绕开它了。反过来排查问题也要注意——健康实例数是 3实际参与负载均衡的可能只有 2 个。权重为 0 的典型场景灰度发布新版本先挂上去、权重设 0确认启动没问题再放开、机器维护不动进程先摘流量、以及临时降级容量不足的节点。和 Ribbon 自带策略的关系NacosRule并没有另起炉灶。它实现的是和RandomRule、RoundRobinRule完全相同的com.netflix.loadbalancer.IRule接口所以配置方式一模一样userservice:ribbon:NFLoadBalancerRuleClassName:com.netflix.loadbalancer.RandomRule# 纯随机# NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RoundRobinRule # 轮询# NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule # 同集群优先上一篇学怎么改 Ribbon 规则NFLoadBalancerRuleClassName这个键、按服务名做前缀、写在消费者侧这一篇只是把值从RandomRule换成NacosRule。换个值就换了一套实例选取算法——这就是面向接口换来扩展性的地方。版本提醒如果用的是Spring Cloud Alibaba 2021.0.1.0 及之后的版本Ribbon 已经被移除NFLoadBalancerRuleClassName这套配置不再生效NacosRule也不在com.alibaba.cloud.nacos.ribbon包下了。新版本走的是 Spring Cloud LoadBalancerspring:cloud:loadbalancer:nacos:enabled:true# 开启 Nacos 的负载均衡策略效果等同于 NacosRule本文基于课程中的 Ribbon 版本HoxtonSpring Cloud Alibaba 2.2.x一系来写因为原始工程的配置就是这么写的。老版本看到ribbon字样、新版本看到loadbalancer.nacos字样两者是同源的两代实现别混着抄。五个实战坑坑现象正确做法规则配到提供者侧消费者行为毫无变化还是跨机房规则属于调用方配在order-service的application.yml类名写错不报错、不启动失败行为看起来正常但一直在跨机房类名拼写必须精确到com.alibaba.cloud.nacos.ribbon.NacosRule排查时直接搜这条警告日志只给部分服务配了cluster-name没配的那个服务上报的集群名是默认值与消费者永远不同集群优先级失效参与集群划分的每个服务都要配包括消费者自己集群内实例全挂后无人知晓功能正常只是悄悄跨机房延迟无声上涨盯A cross-cluster call occurs告警接到告警去查 HZ 实例为什么下线权重改 0 后误判控制台仍显示健康以为流量还在走记牢健康 ≠ 参与负载均衡权重 0 不参与选择第三个坑的排查手法很简单拿到一条跨集群告警先去 Nacos 控制台对比消费者和提供者上报的集群名十有八九是一边没配或配错了值。配置速览配置项位置作用spring.cloud.nacos.discovery.cluster-name每个服务自己的application.yml声明本实例所属集群userservice.ribbon.NFLoadBalancerRuleClassName消费者order-service指定调userservice时用的负载均衡规则ribbon.eager-load.enabled/clients消费者启动时预加载实例列表避免首次调用变慢实例权重Nacos 控制台 → 服务详情 → 编辑影响被选中概率0 表示不参与负载均衡官方文档Nacos 官方文档 - 服务发现Spring Cloud Alibaba - Nacos DiscoverySpring Cloud LoadBalancer 文档总结集群属性只是把实例分了组分组本身不改变调用行为。真正决定往哪打的是负载均衡规则。默认的ZoneAvoidanceRule认的是 Eureka 的 zone跟 Nacos 的cluster-name是两套字段所以它做不到同集群优先只会轮询。NacosRule的顺序是同集群优先 → 集群内随机 → 都没有才跨集群并打 WARN。集群内是随机别把它当成轮询。那条跨集群告警是免费的监控点价值在于把跨机房这种性能问题提前暴露出来。集群内实例挂光不影响功能只影响延迟。配置两处都在消费者侧本服务配cluster-name按被调用方服务名配NacosRule。类名写错会静默回退默认策略出问题先搜告警日志。权重能调流量分配权重 0 的实例不参与负载均衡但仍然健康——这个看起来还健康是最容易被误判的地方。

相关新闻

10.7【A】

10.7【A】

301暴力递归先求最少删除的次数但关键问题在于如何不重不漏的知道所有可能的结果考虑使用dfs即对于每个位置都尝试删除,首先要保证删除后字符串合法,其次再查询结果当中是否已经存在dfs保留,已删除的数量,当前的左括号数&#xff…

2026/10/9 7:59:27 阅读更多 →
输电线路行波测距原理与Simulink仿真实战解析

输电线路行波测距原理与Simulink仿真实战解析

干了几年输电线路故障分析,我最头疼的一件事,就是线路跳闸之后要第一时间给调度报出故障点在哪。传统测距算法靠工频量硬算,遇到高阻接地、运行方式变化大的场景,误差几公里是家常便饭,现场巡线的人沿着线路找一整夜也…

2026/10/9 7:58:26 阅读更多 →
Deepseek生成Word/Excel文件全攻略:从复制粘贴到API自动化

Deepseek生成Word/Excel文件全攻略:从复制粘贴到API自动化

说实话,我第一次被问到“Deepseek能不能直接生成Word或Excel文件”的时候,也愣了一下。因为大多数人对大模型的预期,和它实际能做的事之间存在一道认知差——你让它“生成一个销售统计表.xlsx”,它回你一大段文字,你复…

2026/10/9 7:58:26 阅读更多 →

最新新闻

KTV聚会点歌辅助工具:基于曲风标签与多人适配的推荐实现

KTV聚会点歌辅助工具:基于曲风标签与多人适配的推荐实现

每次组织K歌聚会,最头疼的不是订包厢,大概是谁点什么歌。我做过一个点歌辅助工具,核心就一条:录入好友的喜好曲风,推荐适配歌曲,顺带把演唱难度和原唱标清楚。做这个事的起因很简单——一次十来人的局&…

2026/10/9 8:28:16 阅读更多 →
基于Kubernetes容器编排的CTFd动态题目靶场插件实战

基于Kubernetes容器编排的CTFd动态题目靶场插件实战

简介:面向高校信息安全、云计算、网络工程等专业课程设计与毕业设计场景,这套资源基于 Kubernetes 容器编排实现了 CTFd 动态题目靶场插件,可较好解决赛事场景下动态题目实例快速创建、调度与回收的需求。压缩包共 34 个文件、约 195KB&#…

2026/10/9 8:28:16 阅读更多 →
智慧社区家庭医生预约系统:Java毕业设计部署与改造实战

智慧社区家庭医生预约系统:Java毕业设计部署与改造实战

简介:这是一套基于Java与MySQL的智慧社区家庭医生预约系统毕业设计完整资料包,面向计算机相关专业学生,可用于课题参考、功能设计、代码实现与论文撰写。压缩包内提供项目源代码、毕业论文文档及答辩PPT模板,具备Java环境即可部署…

2026/10/9 8:28:16 阅读更多 →
Agent Skill 开发实战教程:从入门到精通,用 TaoToken 统一 Key 打通调试链路

Agent Skill 开发实战教程:从入门到精通,用 TaoToken 统一 Key 打通调试链路

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 8:28:16 阅读更多 →
Python易错题精讲:作用域、闭包、lambda与Py2/Py3差异

Python易错题精讲:作用域、闭包、lambda与Py2/Py3差异

1. 变量作用域:LEGB规则与常见的坑1.1 从一道送命题说起:函数内定义变量为何报错先看一道流传甚广的Python入门题:x 1def func():print(x)x 2func()很多新手一看就答:输出1。因为上面定义了x1,函数里打印x&#xff0…

2026/10/9 8:28:16 阅读更多 →
SpringBoot+Vue+MySQL校园求职招聘系统毕设全流程实战解析

SpringBoot+Vue+MySQL校园求职招聘系统毕设全流程实战解析

一个“毕业设计”项目被做成“源码数据库论文部署文档”的整合包,其实对应的是一个非常经典的技术组合:SpringBoot负责后端接口,Vue负责前端页面,MySQL负责数据存储,三者的协作关系可以说是目前Java Web方向毕业生最熟…

2026/10/9 8:27:15 阅读更多 →

日新闻

Java时间API实战:LocalDate、Date与ZonedDateTime的转换与避坑指南

Java时间API实战:LocalDate、Date与ZonedDateTime的转换与避坑指南

Java时间API这个话题,隔三差五就会在群里被翻出来讨论一次。上周还有个同事线上处理一个订单超时问题,排查到最后发现是ZonedDateTime序列化后时区丢了,用户在下单当天晚上看到的时间整整差了8个小时。这类问题几乎每个做Java开发的人都遇到过…

2026/10/9 0:00:49 阅读更多 →
EasyTier实践:从NAT穿透到子网代理的异地组网部署与排错

EasyTier实践:从NAT穿透到子网代理的异地组网部署与排错

前几个月我手头有好几台机器需要互相访问:办公室台式机、家里 NAS、还有一台云主机。如果只是偶尔传个文件倒还好,问题是工作场景经常要在几处环境之间来回切换,每次都先登录跳板机再层层代理,实在折腾。我先后试过端口映射、自建…

2026/10/9 0:00:49 阅读更多 →
AI Agent工程实战:从七要素到七个决策点的系统设计指南

AI Agent工程实战:从七要素到七个决策点的系统设计指南

AI Agent 这个词在过去一年里被反复提及,但真正动手搭过一套能跑起来的 Agent 系统的人都知道,从"知道它是什么"到"让它稳定干活"之间隔着一整套工程决策。我前后参与过几个 Agent 项目的落地,从最初用现成框架拼装&…

2026/10/9 0:01:50 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 15:26:32 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 15:26:40 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 10:10:36 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 21:13:17 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 15:26:17 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 6:17:20 阅读更多 →